Skip to content

Commit f753481

Browse files
committed
ref
1 parent afb8cac commit f753481

File tree

10 files changed

+74
-107
lines changed

10 files changed

+74
-107
lines changed

examples/misc/persistent-chat-double-agent.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,16 @@
2727

2828
$store = new InMemoryStore();
2929

30-
$firstChatStore = $store->withSession($firstAgent->getId());
31-
$secondChatStore = $store->withSession($secondAgent->getId());
30+
$firstChat = new Chat($firstAgent, $store);
31+
$secondChat = new Chat($secondAgent, $store);
3232

33-
$firstChat = new Chat($firstAgent, $firstChatStore);
34-
$secondChat = new Chat($secondAgent, $secondChatStore);
35-
36-
$messages = new MessageBag(
33+
$firstChat->initiate(new MessageBag(
34+
Message::forSystem('You are a helpful assistant. You only answer with short sentences.'),
35+
));
36+
$secondChat->initiate(new MessageBag(
3737
Message::forSystem('You are a helpful assistant. You only answer with short sentences.'),
38-
);
38+
));
3939

40-
$firstChat->initiate($messages);
41-
$secondChat->initiate($messages);
4240
$firstChat->submit(Message::ofUser('My name is Christopher.'));
4341
$firstChatMessage = $firstChat->submit(Message::ofUser('What is my name?'));
4442
$secondChatMessage = $secondChat->submit(Message::ofUser('What is my name?'));

src/agent/src/Chat.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
use Symfony\AI\Platform\Message\UserMessage;
1919
use Symfony\AI\Platform\Result\TextResult;
2020

21+
/**
22+
* @author Christopher Hertel <[email protected]>
23+
*/
2124
final readonly class Chat implements ChatInterface
2225
{
2326
public function __construct(
@@ -28,23 +31,25 @@ public function __construct(
2831

2932
public function initiate(MessageBagInterface $messages): void
3033
{
31-
$this->store->clear();
34+
$messages->setSession($this->agent->getId());
35+
36+
$this->store->clear($messages->getSession());
3237
$this->store->save($messages);
3338
}
3439

3540
public function submit(UserMessage $message): AssistantMessage
3641
{
37-
$messages = $this->store->load();
42+
$messagesBag = $this->store->load($this->agent->getId());
3843

39-
$messages->add($message);
40-
$result = $this->agent->call($messages);
44+
$messagesBag->add($message);
45+
$result = $this->agent->call($messagesBag);
4146

4247
\assert($result instanceof TextResult);
4348

4449
$assistantMessage = Message::ofAssistant($result->getContent());
45-
$messages->add($assistantMessage);
50+
$messagesBag->add($assistantMessage);
4651

47-
$this->store->save($messages);
52+
$this->store->save($messagesBag);
4853

4954
return $assistantMessage;
5055
}

src/agent/src/Chat/MessageStore/CacheStore.php

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,16 @@
1313

1414
use Psr\Cache\CacheItemPoolInterface;
1515
use Symfony\AI\Agent\Chat\MessageStoreInterface;
16-
use Symfony\AI\Agent\Chat\SessionAwareMessageStoreInterface;
1716
use Symfony\AI\Agent\Exception\RuntimeException;
1817
use Symfony\AI\Platform\Message\MessageBag;
1918
use Symfony\AI\Platform\Message\MessageBagInterface;
2019
use Symfony\Component\Uid\AbstractUid;
2120
use Symfony\Component\Uid\TimeBasedUidInterface;
2221

23-
final readonly class CacheStore implements MessageStoreInterface, SessionAwareMessageStoreInterface
22+
final readonly class CacheStore implements MessageStoreInterface
2423
{
2524
public function __construct(
2625
private CacheItemPoolInterface $cache,
27-
private string $cacheKey,
2826
private int $ttl = 86400,
2927
) {
3028
if (!interface_exists(CacheItemPoolInterface::class)) {
@@ -34,28 +32,23 @@ public function __construct(
3432

3533
public function save(MessageBagInterface $messages): void
3634
{
37-
$item = $this->cache->getItem($this->cacheKey);
35+
$item = $this->cache->getItem($messages->getSession()->toRfc4122());
3836

3937
$item->set($messages);
4038
$item->expiresAfter($this->ttl);
4139

4240
$this->cache->save($item);
4341
}
4442

45-
public function load(): MessageBag
43+
public function load(AbstractUid&TimeBasedUidInterface $session): MessageBagInterface
4644
{
47-
$item = $this->cache->getItem($this->cacheKey);
45+
$item = $this->cache->getItem($session->toRfc4122());
4846

4947
return $item->isHit() ? $item->get() : new MessageBag();
5048
}
5149

52-
public function clear(): void
50+
public function clear(AbstractUid&TimeBasedUidInterface $session): void
5351
{
54-
$this->cache->deleteItem($this->cacheKey);
55-
}
56-
57-
public function withSession(AbstractUid&TimeBasedUidInterface $session): MessageStoreInterface&SessionAwareMessageStoreInterface
58-
{
59-
return new self($this->cache, $session->toRfc4122(), $this->ttl);
52+
$this->cache->deleteItem($session->toRfc4122());
6053
}
6154
}

src/agent/src/Chat/MessageStore/InMemoryStore.php

Lines changed: 8 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,57 +12,30 @@
1212
namespace Symfony\AI\Agent\Chat\MessageStore;
1313

1414
use Symfony\AI\Agent\Chat\MessageStoreInterface;
15-
use Symfony\AI\Agent\Chat\SessionAwareMessageStoreInterface;
1615
use Symfony\AI\Platform\Message\MessageBag;
1716
use Symfony\AI\Platform\Message\MessageBagInterface;
18-
use Symfony\AI\Platform\Message\MessageInterface;
1917
use Symfony\Component\Uid\AbstractUid;
2018
use Symfony\Component\Uid\TimeBasedUidInterface;
2119

22-
final class InMemoryStore implements MessageStoreInterface, SessionAwareMessageStoreInterface
20+
final class InMemoryStore implements MessageStoreInterface
2321
{
2422
/**
25-
* @var MessageInterface[]
23+
* @var MessageBagInterface[]
2624
*/
27-
private array $messages;
28-
private (AbstractUid&TimeBasedUidInterface)|null $session = null;
25+
private array $messageBags;
2926

3027
public function save(MessageBagInterface $messages): void
3128
{
32-
if (null === $this->session) {
33-
$this->messages = $messages->getMessages();
34-
35-
return;
36-
}
37-
38-
$this->messages[$this->session->toRfc4122()] = $messages;
29+
$this->messageBags[$messages->getSession()->toRfc4122()] = $messages;
3930
}
4031

41-
public function load(): MessageBagInterface
32+
public function load(AbstractUid&TimeBasedUidInterface $session): MessageBagInterface
4233
{
43-
if (null === $this->session) {
44-
return new MessageBag(...$this->messages);
45-
}
46-
47-
return new MessageBag($this->messages[$this->session->toRfc4122()]);
34+
return $this->messageBags[$session->toRfc4122()] ?? new MessageBag();
4835
}
4936

50-
public function clear(): void
37+
public function clear(AbstractUid&TimeBasedUidInterface $session): void
5138
{
52-
if (null === $this->session) {
53-
$this->messages = [];
54-
55-
return;
56-
}
57-
58-
$this->messages[$this->session->toRfc4122()] = new MessageBag();
59-
}
60-
61-
public function withSession(AbstractUid&TimeBasedUidInterface $session): MessageStoreInterface&SessionAwareMessageStoreInterface
62-
{
63-
$store = clone $this;
64-
$store->session = $session;
65-
66-
return $store;
39+
$this->messageBags[$session->toRfc4122()] = new MessageBag();
6740
}
6841
}

src/agent/src/Chat/MessageStore/SessionStore.php

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\AI\Agent\Chat\MessageStore;
1313

1414
use Symfony\AI\Agent\Chat\MessageStoreInterface;
15-
use Symfony\AI\Agent\Chat\SessionAwareMessageStoreInterface;
1615
use Symfony\AI\Agent\Exception\RuntimeException;
1716
use Symfony\AI\Platform\Message\MessageBag;
1817
use Symfony\AI\Platform\Message\MessageBagInterface;
@@ -21,13 +20,12 @@
2120
use Symfony\Component\Uid\AbstractUid;
2221
use Symfony\Component\Uid\TimeBasedUidInterface;
2322

24-
final readonly class SessionStore implements MessageStoreInterface, SessionAwareMessageStoreInterface
23+
final readonly class SessionStore implements MessageStoreInterface
2524
{
2625
private SessionInterface $session;
2726

2827
public function __construct(
2928
RequestStack $requestStack,
30-
private string $sessionKey = 'messages',
3129
) {
3230
if (!class_exists(RequestStack::class)) {
3331
throw new RuntimeException('For using the SessionStore as message store, the symfony/http-foundation package is required. Try running "composer require symfony/http-foundation".');
@@ -37,24 +35,16 @@ public function __construct(
3735

3836
public function save(MessageBagInterface $messages): void
3937
{
40-
$this->session->set($this->sessionKey, $messages);
38+
$this->session->set($messages->getSession()->toRfc4122(), $messages);
4139
}
4240

43-
public function load(): MessageBagInterface
41+
public function load(AbstractUid&TimeBasedUidInterface $session): MessageBagInterface
4442
{
45-
return $this->session->get($this->sessionKey, new MessageBag());
43+
return $this->session->get($session->toRfc4122(), new MessageBag());
4644
}
4745

48-
public function clear(): void
46+
public function clear(AbstractUid&TimeBasedUidInterface $session): void
4947
{
50-
$this->session->remove($this->sessionKey);
51-
}
52-
53-
public function withSession(AbstractUid&TimeBasedUidInterface $session): MessageStoreInterface&SessionAwareMessageStoreInterface
54-
{
55-
$store = clone $this;
56-
$store->session->setId($session->toRfc4122());
57-
58-
return $store;
48+
$this->session->remove($session->toRfc4122());
5949
}
6050
}

src/agent/src/Chat/MessageStoreInterface.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ interface MessageStoreInterface
1919
{
2020
public function save(MessageBagInterface $messages): void;
2121

22-
public function load((AbstractUid&TimeBasedUidInterface)|null $session = null): MessageBagInterface;
22+
public function load(AbstractUid&TimeBasedUidInterface $session): MessageBagInterface;
2323

24-
public function clear(): void;
24+
public function clear(AbstractUid&TimeBasedUidInterface $session): void;
2525
}

src/agent/src/Chat/SessionAwareMessageStoreInterface.php

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/agent/tests/AgentTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -410,22 +410,22 @@ public function testDoubleAgentCanUseSameMessageStore()
410410
$secondAgent = new Agent($platform, $model);
411411

412412
$store = new InMemoryStore();
413-
$firstStore = $store->withSession($firstAgent->getId());
414-
$secondStore = $store->withSession($secondAgent->getId());
415413

416-
$firstChat = new Chat($firstAgent, $firstStore);
417-
$secondChat = new Chat($secondAgent, $secondStore);
414+
$firstChat = new Chat($firstAgent, $store);
415+
$secondChat = new Chat($secondAgent, $store);
418416

419417
$messages = new MessageBag(
420418
Message::forSystem('You are a helpful assistant. You only answer with short sentences.'),
421419
);
422420

423421
$firstChat->initiate($messages);
424422
$firstChat->submit(new UserMessage(new Text('Hello')));
423+
424+
$secondChat->initiate($messages);
425425
$secondChat->submit(new UserMessage(new Text('Hello')));
426426
$secondChat->submit(new UserMessage(new Text('Hello there')));
427427

428-
$this->assertCount(1, $firstStore->load());
429-
$this->assertCount(2, $secondStore->load());
428+
$this->assertCount(1, $store->load($firstAgent->getId()));
429+
$this->assertCount(2, $store->load($secondAgent->getId()));
430430
}
431431
}

src/platform/src/Message/MessageBag.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
namespace Symfony\AI\Platform\Message;
1313

14+
use Symfony\AI\Platform\Exception\RuntimeException;
15+
use Symfony\Component\Uid\AbstractUid;
16+
use Symfony\Component\Uid\TimeBasedUidInterface;
17+
1418
/**
1519
* @final
1620
*
@@ -23,6 +27,8 @@ class MessageBag implements MessageBagInterface
2327
*/
2428
private array $messages;
2529

30+
private (AbstractUid&TimeBasedUidInterface)|null $session = null;
31+
2632
public function __construct(MessageInterface ...$messages)
2733
{
2834
$this->messages = array_values($messages);
@@ -109,6 +115,20 @@ public function containsImage(): bool
109115
return false;
110116
}
111117

118+
public function setSession(AbstractUid&TimeBasedUidInterface $session): void
119+
{
120+
$this->session = $session;
121+
}
122+
123+
public function getSession(): AbstractUid&TimeBasedUidInterface
124+
{
125+
if (!$this->session instanceof TimeBasedUidInterface) {
126+
throw new RuntimeException('Current message bag session is not set.');
127+
}
128+
129+
return $this->session;
130+
}
131+
112132
public function count(): int
113133
{
114134
return \count($this->messages);

src/platform/src/Message/MessageBagInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@
1111

1212
namespace Symfony\AI\Platform\Message;
1313

14+
use Symfony\Component\Uid\AbstractUid;
15+
use Symfony\Component\Uid\TimeBasedUidInterface;
16+
1417
/**
1518
* @author Oskar Stark <[email protected]>
19+
* @author Christopher Hertel <[email protected]>
1620
*/
1721
interface MessageBagInterface extends \Countable
1822
{
@@ -36,4 +40,8 @@ public function prepend(MessageInterface $message): self;
3640
public function containsAudio(): bool;
3741

3842
public function containsImage(): bool;
43+
44+
public function setSession(AbstractUid&TimeBasedUidInterface $session): void;
45+
46+
public function getSession(): AbstractUid&TimeBasedUidInterface;
3947
}

0 commit comments

Comments
 (0)