From 11c9cc26552ff9bd853b0c6b23ebac2db7e11709 Mon Sep 17 00:00:00 2001 From: xersion22 Date: Tue, 9 Sep 2025 15:24:56 +0530 Subject: [PATCH 1/2] [Agent] Show system message first in chat command --- src/agent/src/Agent.php | 9 +++++ src/agent/src/AgentInterface.php | 2 ++ src/agent/tests/AgentTest.php | 43 +++++++++++++++++++++++ src/ai-bundle/src/Command/ChatCommand.php | 12 +++---- 4 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/agent/src/Agent.php b/src/agent/src/Agent.php index 49122a6d6..48ca0dbeb 100644 --- a/src/agent/src/Agent.php +++ b/src/agent/src/Agent.php @@ -122,4 +122,13 @@ private function initializeProcessors(iterable $processors, string $interface): return $processors instanceof \Traversable ? iterator_to_array($processors) : $processors; } + + public function getSystemMessage(): ?string + { + $input = new Input($this->model, new MessageBag(), []); + + array_map(fn (InputProcessorInterface $processor) => $processor->processInput($input), $this->inputProcessors); + + return $input->messages->getSystemMessage()?->content; + } } diff --git a/src/agent/src/AgentInterface.php b/src/agent/src/AgentInterface.php index ed3c27c33..2f4ea66c3 100644 --- a/src/agent/src/AgentInterface.php +++ b/src/agent/src/AgentInterface.php @@ -26,4 +26,6 @@ interface AgentInterface * @throws ExceptionInterface When the agent encounters an error (e.g., unsupported model capabilities, invalid arguments, network failures, or processor errors) */ public function call(MessageBag $messages, array $options = []): ResultInterface; + + public function getSystemMessage(): ?string; } diff --git a/src/agent/tests/AgentTest.php b/src/agent/tests/AgentTest.php index ba1014f75..56fadf97d 100644 --- a/src/agent/tests/AgentTest.php +++ b/src/agent/tests/AgentTest.php @@ -30,6 +30,7 @@ use Symfony\AI\Platform\Message\Content\Audio; use Symfony\AI\Platform\Message\Content\Image; use Symfony\AI\Platform\Message\Content\Text; +use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; use Symfony\AI\Platform\Message\UserMessage; use Symfony\AI\Platform\Model; @@ -405,4 +406,46 @@ public function testConstructorAcceptsTraversableProcessors() $this->assertInstanceOf(AgentInterface::class, $agent); } + + public function testGetSystemMessageReturnsExpectedValue() + { + $platform = $this->createMock(PlatformInterface::class); + $model = $this->createMock(Model::class); + $expectedSystemMessage = 'System prompt here'; + + $inputProcessor = $this->createMock(InputProcessorInterface::class); + $outputProcessor = $this->createMock(OutputProcessorInterface::class); + + $inputProcessor->expects($this->once()) + ->method('processInput') + ->willReturnCallback(function (Input $input) use ($expectedSystemMessage) { + $input->messages->add(Message::forSystem($expectedSystemMessage)); + }); + + $agent = new Agent($platform, $model, new \ArrayIterator([$inputProcessor]), new \ArrayIterator([$outputProcessor])); + + $systemMessage = $agent->getSystemMessage(); + + $this->assertSame($expectedSystemMessage, $systemMessage); + } + + public function testGetSystemMessageReturnsNullIfNoSystemMessageSet() + { + $platform = $this->createMock(PlatformInterface::class); + $model = $this->createMock(Model::class); + + $inputProcessor = $this->createMock(InputProcessorInterface::class); + $outputProcessor = $this->createMock(OutputProcessorInterface::class); + + $inputProcessor->expects($this->once()) + ->method('processInput') + ->willReturnCallback(function (Input $input) { + }); + + $agent = new Agent($platform, $model, new \ArrayIterator([$inputProcessor]), new \ArrayIterator([$outputProcessor])); + + $systemMessage = $agent->getSystemMessage(); + + $this->assertNull($systemMessage); + } } diff --git a/src/ai-bundle/src/Command/ChatCommand.php b/src/ai-bundle/src/Command/ChatCommand.php index ee34f132a..0e8bd3369 100644 --- a/src/ai-bundle/src/Command/ChatCommand.php +++ b/src/ai-bundle/src/Command/ChatCommand.php @@ -126,16 +126,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $agent = $this->agents->get($agentName); + $systemMessage = $agent->getSystemMessage(); // Now start the chat $io = new SymfonyStyle($input, $output); $io->title(\sprintf('Chat with %s Agent', $agentName)); + if (null !== $systemMessage) { + $io->writeln("System prompt: $systemMessage"); + } $io->info('Type your message and press Enter. Type "exit" or "quit" to end the conversation.'); $io->newLine(); $messages = new MessageBag(); - $systemPromptDisplayed = false; while (true) { $userInput = $io->ask('You'); @@ -154,13 +157,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int try { $result = $agent->call($messages); - // Display system prompt after first successful call - if (!$systemPromptDisplayed && null !== ($systemMessage = $messages->getSystemMessage())) { - $io->section('System Prompt'); - $io->block($systemMessage->content, null, 'fg=gray', ' ', true); - $systemPromptDisplayed = true; - } - if ($result instanceof TextResult) { $io->write('Assistant:'); $io->writeln(''); From 5a24961144bab11ad082b5c0891b08247add02f4 Mon Sep 17 00:00:00 2001 From: xersion22 Date: Tue, 9 Sep 2025 15:31:53 +0530 Subject: [PATCH 2/2] [Agent] Show system message first in chat command --- src/agent/src/Agent.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/agent/src/Agent.php b/src/agent/src/Agent.php index 48ca0dbeb..17c27760f 100644 --- a/src/agent/src/Agent.php +++ b/src/agent/src/Agent.php @@ -102,6 +102,15 @@ public function call(MessageBag $messages, array $options = []): ResultInterface return $output->result; } + public function getSystemMessage(): ?string + { + $input = new Input($this->model, new MessageBag(), []); + + array_map(fn (InputProcessorInterface $processor) => $processor->processInput($input), $this->inputProcessors); + + return $input->messages->getSystemMessage()?->content; + } + /** * @param InputProcessorInterface[]|OutputProcessorInterface[] $processors * @param class-string $interface @@ -122,13 +131,4 @@ private function initializeProcessors(iterable $processors, string $interface): return $processors instanceof \Traversable ? iterator_to_array($processors) : $processors; } - - public function getSystemMessage(): ?string - { - $input = new Input($this->model, new MessageBag(), []); - - array_map(fn (InputProcessorInterface $processor) => $processor->processInput($input), $this->inputProcessors); - - return $input->messages->getSystemMessage()?->content; - } }