diff --git a/demo/tests/Blog/ChatTest.php b/demo/tests/Blog/ChatTest.php index c7c9333f6..811be0c69 100644 --- a/demo/tests/Blog/ChatTest.php +++ b/demo/tests/Blog/ChatTest.php @@ -37,8 +37,8 @@ public function testLoadMessagesReturnsDefaultSystemMessage() $systemMessage = $messages->getMessages()[0]; $this->assertInstanceOf(SystemMessage::class, $systemMessage); - $this->assertStringContainsString('helpful assistant', $systemMessage->content); - $this->assertStringContainsString('similarity_search', $systemMessage->content); + $this->assertStringContainsString('helpful assistant', $systemMessage->getContent()); + $this->assertStringContainsString('similarity_search', $systemMessage->getContent()); } public function testSubmitMessageAddsUserMessageAndAgentResponse() @@ -65,12 +65,12 @@ public function testSubmitMessageAddsUserMessageAndAgentResponse() // Check user message $userMessage = $messageList[1]; $this->assertInstanceOf(UserMessage::class, $userMessage); - $this->assertSame('What is Symfony?', $userMessage->content[0]->text); + $this->assertSame('What is Symfony?', $userMessage->getContent()[0]->getText()); // Check assistant message $assistantMessage = $messageList[2]; $this->assertInstanceOf(AssistantMessage::class, $assistantMessage); - $this->assertSame('Symfony is a PHP web framework for building web applications and APIs.', $assistantMessage->content); + $this->assertSame('Symfony is a PHP web framework for building web applications and APIs.', $assistantMessage->getContent()); } public function testSubmitMessageWithUnknownQueryUsesDefaultResponse() @@ -91,7 +91,7 @@ public function testSubmitMessageWithUnknownQueryUsesDefaultResponse() // Check assistant used default response $assistantMessage = $messageList[2]; - $this->assertSame('I can help you with Symfony-related questions!', $assistantMessage->content); + $this->assertSame('I can help you with Symfony-related questions!', $assistantMessage->getContent()); } public function testMultipleMessagesAreTrackedCorrectly() @@ -169,10 +169,10 @@ public function testAgentReceivesFullConversationHistory() $this->assertCount(5, $messages); // Verify the conversation flow (with 5 messages) - $this->assertStringContainsString('helpful assistant', $messages[0]->content); // system - $this->assertSame('What is Symfony?', $messages[1]->content[0]->text); // user1 - $this->assertSame('Symfony is a PHP web framework for building web applications and APIs.', $messages[2]->content); // assistant1 - $this->assertSame('Tell me more', $messages[3]->content[0]->text); // user2 + $this->assertStringContainsString('helpful assistant', $messages[0]->getContent()); // system + $this->assertSame('What is Symfony?', $messages[1]->getContent()[0]->getText()); // user1 + $this->assertSame('Symfony is a PHP web framework for building web applications and APIs.', $messages[2]->getContent()); // assistant1 + $this->assertSame('Tell me more', $messages[3]->getContent()[0]->getText()); // user2 // The 5th message appears to be the previous assistant response or another system message } diff --git a/examples/chat/persistent-chat-cache.php b/examples/chat/persistent-chat-cache.php index 0ce491ff2..78abdaa58 100644 --- a/examples/chat/persistent-chat-cache.php +++ b/examples/chat/persistent-chat-cache.php @@ -35,4 +35,4 @@ $chat->submit(Message::ofUser('My name is Christopher.')); $message = $chat->submit(Message::ofUser('What is my name?')); -echo $message->content.\PHP_EOL; +echo $message->getContent().\PHP_EOL; diff --git a/examples/chat/persistent-chat-session.php b/examples/chat/persistent-chat-session.php index cf315cb7b..397664abd 100644 --- a/examples/chat/persistent-chat-session.php +++ b/examples/chat/persistent-chat-session.php @@ -44,4 +44,4 @@ $chat->submit(Message::ofUser('My name is Christopher.')); $message = $chat->submit(Message::ofUser('What is my name?')); -echo $message->content.\PHP_EOL; +echo $message->getContent().\PHP_EOL; diff --git a/examples/chat/persistent-chat.php b/examples/chat/persistent-chat.php index cfe46a91c..a574e9f13 100644 --- a/examples/chat/persistent-chat.php +++ b/examples/chat/persistent-chat.php @@ -31,4 +31,4 @@ $chat->submit(Message::ofUser('My name is Christopher.')); $message = $chat->submit(Message::ofUser('What is my name?')); -echo $message->content.\PHP_EOL; +echo $message->getContent().\PHP_EOL; diff --git a/src/agent/src/Memory/EmbeddingProvider.php b/src/agent/src/Memory/EmbeddingProvider.php index 99266535e..e93a76fde 100644 --- a/src/agent/src/Memory/EmbeddingProvider.php +++ b/src/agent/src/Memory/EmbeddingProvider.php @@ -43,7 +43,7 @@ public function load(Input $input): array } $userMessageTextContent = array_filter( - $userMessage->content, + $userMessage->getContent(), static fn (ContentInterface $content): bool => $content instanceof Text, ); @@ -53,7 +53,7 @@ public function load(Input $input): array $userMessageTextContent = array_shift($userMessageTextContent); - $vectors = $this->platform->invoke($this->model->getName(), $userMessageTextContent->text)->asVectors(); + $vectors = $this->platform->invoke($this->model->getName(), $userMessageTextContent->getText())->asVectors(); $foundEmbeddingContent = $this->vectorStore->query($vectors[0]); if (0 === \count($foundEmbeddingContent)) { return []; diff --git a/src/agent/src/Memory/MemoryInputProcessor.php b/src/agent/src/Memory/MemoryInputProcessor.php index 2c37bae82..997c5dad5 100644 --- a/src/agent/src/Memory/MemoryInputProcessor.php +++ b/src/agent/src/Memory/MemoryInputProcessor.php @@ -69,7 +69,7 @@ public function processInput(Input $input): void return; } - $systemMessage = $input->getMessageBag()->getSystemMessage()->content ?? ''; + $systemMessage = $input->getMessageBag()->getSystemMessage()?->getContent() ?? ''; $combinedMessage = self::MEMORY_PROMPT_MESSAGE.$memory; if ('' !== $systemMessage) { diff --git a/src/agent/src/MockAgent.php b/src/agent/src/MockAgent.php index 195db56b2..bea40fdff 100644 --- a/src/agent/src/MockAgent.php +++ b/src/agent/src/MockAgent.php @@ -62,9 +62,9 @@ public function call(MessageBag $messages, array $options = []): ResultInterface $content = ''; if ($lastMessage instanceof UserMessage) { - foreach ($lastMessage->content as $messageContent) { + foreach ($lastMessage->getContent() as $messageContent) { if ($messageContent instanceof Text) { - $content .= $messageContent->text; + $content .= $messageContent->getText(); } } } diff --git a/src/agent/src/Toolbox/AgentProcessor.php b/src/agent/src/Toolbox/AgentProcessor.php index 510f02e8d..f6236b994 100644 --- a/src/agent/src/Toolbox/AgentProcessor.php +++ b/src/agent/src/Toolbox/AgentProcessor.php @@ -89,7 +89,7 @@ private function handleToolCallsCallback(Output $output): \Closure return function (ToolCallResult $result, ?AssistantMessage $streamedAssistantResponse = null) use ($output): ResultInterface { $messages = $this->keepToolMessages ? $output->getMessageBag() : clone $output->getMessageBag(); - if (null !== $streamedAssistantResponse && '' !== $streamedAssistantResponse->content) { + if (null !== $streamedAssistantResponse && '' !== $streamedAssistantResponse->getContent()) { $messages->add($streamedAssistantResponse); } diff --git a/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php b/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php index a448ce943..803fe803b 100644 --- a/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php +++ b/src/agent/tests/InputProcessor/SystemPromptInputProcessorTest.php @@ -41,7 +41,7 @@ public function testProcessInputAddsSystemMessageWhenNoneExists() $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); $this->assertInstanceOf(UserMessage::class, $messages[1]); - $this->assertSame('This is a system prompt', $messages[0]->content); + $this->assertSame('This is a system prompt', $messages[0]->getContent()); } public function testProcessInputDoesNotAddSystemMessageWhenOneExists() @@ -59,7 +59,7 @@ public function testProcessInputDoesNotAddSystemMessageWhenOneExists() $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); $this->assertInstanceOf(UserMessage::class, $messages[1]); - $this->assertSame('This is already a system prompt', $messages[0]->content); + $this->assertSame('This is already a system prompt', $messages[0]->getContent()); } public function testDoesNotIncludeToolsIfToolboxIsEmpty() @@ -86,7 +86,7 @@ public function execute(ToolCall $toolCall): mixed $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); $this->assertInstanceOf(UserMessage::class, $messages[1]); - $this->assertSame('This is a system prompt', $messages[0]->content); + $this->assertSame('This is a system prompt', $messages[0]->getContent()); } public function testIncludeToolDefinitions() @@ -138,7 +138,7 @@ public function execute(ToolCall $toolCall): mixed ## tool_required_params A tool with required parameters or not - PROMPT, $messages[0]->content); + PROMPT, $messages[0]->getContent()); } public function testWithStringableSystemPrompt() @@ -176,7 +176,7 @@ public function execute(ToolCall $toolCall): mixed ## tool_no_params A tool without parameters - PROMPT, $messages[0]->content); + PROMPT, $messages[0]->getContent()); } public function testWithTranslatedSystemPrompt() @@ -190,7 +190,7 @@ public function testWithTranslatedSystemPrompt() $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); $this->assertInstanceOf(UserMessage::class, $messages[1]); - $this->assertSame('This is a cool translated system prompt', $messages[0]->content); + $this->assertSame('This is a cool translated system prompt', $messages[0]->getContent()); } public function testWithTranslationDomainSystemPrompt() @@ -207,7 +207,7 @@ public function testWithTranslationDomainSystemPrompt() $messages = $input->getMessageBag()->getMessages(); $this->assertCount(1, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); - $this->assertSame('This is a cool translated system prompt with a translation domain', $messages[0]->content); + $this->assertSame('This is a cool translated system prompt with a translation domain', $messages[0]->getContent()); } public function testWithMissingTranslator() @@ -237,7 +237,7 @@ public function testProcessInputWithFile() $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); $this->assertInstanceOf(UserMessage::class, $messages[1]); - $this->assertSame('This is a system prompt from a file', $messages[0]->content); + $this->assertSame('This is a system prompt from a file', $messages[0]->getContent()); } finally { unlink($tempFile); } @@ -258,7 +258,7 @@ public function testProcessInputWithMultilineFile() $messages = $input->getMessageBag()->getMessages(); $this->assertCount(2, $messages); $this->assertInstanceOf(SystemMessage::class, $messages[0]); - $this->assertSame("Line 1\nLine 2\nLine 3", $messages[0]->content); + $this->assertSame("Line 1\nLine 2\nLine 3", $messages[0]->getContent()); } finally { unlink($tempFile); } diff --git a/src/agent/tests/Memory/MemoryInputProcessorTest.php b/src/agent/tests/Memory/MemoryInputProcessorTest.php index 23cd26f20..d2cd806d2 100644 --- a/src/agent/tests/Memory/MemoryInputProcessorTest.php +++ b/src/agent/tests/Memory/MemoryInputProcessorTest.php @@ -82,7 +82,7 @@ public function testItIsAddingMemoryToSystemPrompt() You are a helpful and kind assistant. MARKDOWN, - $input->getMessageBag()->getSystemMessage()->content, + $input->getMessageBag()->getSystemMessage()->getContent(), ); } @@ -108,7 +108,7 @@ public function testItIsAddingMemoryToSystemPromptEvenItIsEmpty() First memory content MARKDOWN, - $input->getMessageBag()->getSystemMessage()->content, + $input->getMessageBag()->getSystemMessage()->getContent(), ); } @@ -135,7 +135,7 @@ public function testItIsAddingMultipleMemoryFromSingleProviderToSystemPrompt() First memory content Second memory content MARKDOWN, - $input->getMessageBag()->getSystemMessage()->content, + $input->getMessageBag()->getSystemMessage()->getContent(), ); } @@ -151,6 +151,6 @@ public function testItIsNotAddingAnythingIfMemoryWasEmpty() $memoryInputProcessor->processInput($input = new Input('gpt-4', new MessageBag(), [])); $this->assertArrayNotHasKey('use_memory', $input->getOptions()); - $this->assertNull($input->getMessageBag()->getSystemMessage()?->content); + $this->assertNull($input->getMessageBag()->getSystemMessage()?->getContent()); } } diff --git a/src/ai-bundle/src/Command/AgentCallCommand.php b/src/ai-bundle/src/Command/AgentCallCommand.php index 6bee9c490..b8571112b 100644 --- a/src/ai-bundle/src/Command/AgentCallCommand.php +++ b/src/ai-bundle/src/Command/AgentCallCommand.php @@ -153,7 +153,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (!$systemPromptDisplayed && null !== ($systemMessage = $messages->getSystemMessage())) { $io->section('System Prompt'); - $io->block($systemMessage->content, null, 'fg=gray', ' ', true); + $io->block($systemMessage->getContent(), null, 'fg=gray', ' ', true); $systemPromptDisplayed = true; } diff --git a/src/chat/composer.json b/src/chat/composer.json index 4da6583cc..2c45209d9 100644 --- a/src/chat/composer.json +++ b/src/chat/composer.json @@ -21,7 +21,8 @@ ], "require": { "php": ">=8.2", - "symfony/ai-agent": "@dev" + "symfony/ai-agent": "@dev", + "symfony/ai-platform": "@dev" }, "require-dev": { "phpstan/phpstan": "^2.0", diff --git a/src/chat/tests/Bridge/Local/InMemoryStoreTest.php b/src/chat/tests/Bridge/Local/InMemoryStoreTest.php index dc19e02c3..4e0cbd18a 100644 --- a/src/chat/tests/Bridge/Local/InMemoryStoreTest.php +++ b/src/chat/tests/Bridge/Local/InMemoryStoreTest.php @@ -72,8 +72,8 @@ public function testLoadReturnsStoredMessages() $this->assertCount(1, $loadedMessages); $messages = $loadedMessages->getMessages(); $this->assertInstanceOf(UserMessage::class, $messages[0]); - $this->assertInstanceOf(Text::class, $messages[0]->content[0]); - $this->assertSame('Test message', $messages[0]->content[0]->text); + $this->assertInstanceOf(Text::class, $messages[0]->getContent()[0]); + $this->assertSame('Test message', $messages[0]->getContent()[0]->getText()); } public function testDropClearsMessages() diff --git a/src/chat/tests/ChatTest.php b/src/chat/tests/ChatTest.php index 078d92465..b6ad22d9a 100644 --- a/src/chat/tests/ChatTest.php +++ b/src/chat/tests/ChatTest.php @@ -62,7 +62,7 @@ public function testItSubmitsUserMessageAndReturnsAssistantMessage() $result = $this->chat->submit($userMessage); $this->assertInstanceOf(AssistantMessage::class, $result); - $this->assertSame($assistantContent, $result->content); + $this->assertSame($assistantContent, $result->getContent()); $this->assertCount(2, $this->store->load()); } @@ -87,7 +87,7 @@ public function testItAppendsMessagesToExistingConversation() $result = $this->chat->submit($newUserMessage); $this->assertInstanceOf(AssistantMessage::class, $result); - $this->assertSame($newAssistantContent, $result->content); + $this->assertSame($newAssistantContent, $result->getContent()); $this->assertCount(2, $this->store->load()); } @@ -110,7 +110,7 @@ public function testItHandlesEmptyMessageStore() $result = $this->chat->submit($userMessage); $this->assertInstanceOf(AssistantMessage::class, $result); - $this->assertSame($assistantContent, $result->content); + $this->assertSame($assistantContent, $result->getContent()); $this->assertCount(2, $this->store->load()); } } diff --git a/src/platform/src/Bridge/Anthropic/Contract/AssistantMessageNormalizer.php b/src/platform/src/Bridge/Anthropic/Contract/AssistantMessageNormalizer.php index abe2148f0..fb5369969 100644 --- a/src/platform/src/Bridge/Anthropic/Contract/AssistantMessageNormalizer.php +++ b/src/platform/src/Bridge/Anthropic/Contract/AssistantMessageNormalizer.php @@ -50,7 +50,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'name' => $toolCall->getName(), 'input' => [] !== $toolCall->getArguments() ? $toolCall->getArguments() : new \stdClass(), ]; - }, $data->toolCalls) : $data->content, + }, $data->getToolCalls()) : $data->getContent(), ]; } diff --git a/src/platform/src/Bridge/Anthropic/Contract/DocumentUrlNormalizer.php b/src/platform/src/Bridge/Anthropic/Contract/DocumentUrlNormalizer.php index 8e36c3195..efcf30c02 100644 --- a/src/platform/src/Bridge/Anthropic/Contract/DocumentUrlNormalizer.php +++ b/src/platform/src/Bridge/Anthropic/Contract/DocumentUrlNormalizer.php @@ -32,7 +32,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'type' => 'document', 'source' => [ 'type' => 'url', - 'url' => $data->url, + 'url' => $data->getUrl(), ], ]; } diff --git a/src/platform/src/Bridge/Anthropic/Contract/ImageUrlNormalizer.php b/src/platform/src/Bridge/Anthropic/Contract/ImageUrlNormalizer.php index 4f7edeb94..0f746244d 100644 --- a/src/platform/src/Bridge/Anthropic/Contract/ImageUrlNormalizer.php +++ b/src/platform/src/Bridge/Anthropic/Contract/ImageUrlNormalizer.php @@ -33,7 +33,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'type' => 'image', 'source' => [ 'type' => 'url', - 'url' => $data->url, + 'url' => $data->getUrl(), ], ]; } diff --git a/src/platform/src/Bridge/Anthropic/Contract/MessageBagNormalizer.php b/src/platform/src/Bridge/Anthropic/Contract/MessageBagNormalizer.php index 709045cbe..9a29e459a 100644 --- a/src/platform/src/Bridge/Anthropic/Contract/MessageBagNormalizer.php +++ b/src/platform/src/Bridge/Anthropic/Contract/MessageBagNormalizer.php @@ -42,7 +42,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = ]; if (null !== $system = $data->getSystemMessage()) { - $array['system'] = $system->content; + $array['system'] = $system->getContent(); } if (isset($context[Contract::CONTEXT_MODEL]) && $context[Contract::CONTEXT_MODEL] instanceof Model) { diff --git a/src/platform/src/Bridge/Anthropic/Contract/ToolCallMessageNormalizer.php b/src/platform/src/Bridge/Anthropic/Contract/ToolCallMessageNormalizer.php index cc561643c..a0a9b8786 100644 --- a/src/platform/src/Bridge/Anthropic/Contract/ToolCallMessageNormalizer.php +++ b/src/platform/src/Bridge/Anthropic/Contract/ToolCallMessageNormalizer.php @@ -44,8 +44,8 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'content' => [ [ 'type' => 'tool_result', - 'tool_use_id' => $data->toolCall->getId(), - 'content' => $data->content, + 'tool_use_id' => $data->getToolCall()->getId(), + 'content' => $data->getContent(), ], ], ]; diff --git a/src/platform/src/Bridge/Bedrock/Nova/Contract/AssistantMessageNormalizer.php b/src/platform/src/Bridge/Bedrock/Nova/Contract/AssistantMessageNormalizer.php index 6df68a745..234e4c1fd 100644 --- a/src/platform/src/Bridge/Bedrock/Nova/Contract/AssistantMessageNormalizer.php +++ b/src/platform/src/Bridge/Bedrock/Nova/Contract/AssistantMessageNormalizer.php @@ -50,13 +50,13 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'input' => [] !== $toolCall->getArguments() ? $toolCall->getArguments() : new \stdClass(), ], ]; - }, $data->toolCalls), + }, $data->getToolCalls()), ]; } return [ 'role' => 'assistant', - 'content' => [['text' => $data->content]], + 'content' => [['text' => $data->getContent()]], ]; } diff --git a/src/platform/src/Bridge/Bedrock/Nova/Contract/MessageBagNormalizer.php b/src/platform/src/Bridge/Bedrock/Nova/Contract/MessageBagNormalizer.php index 51a5f24f7..732e812e3 100644 --- a/src/platform/src/Bridge/Bedrock/Nova/Contract/MessageBagNormalizer.php +++ b/src/platform/src/Bridge/Bedrock/Nova/Contract/MessageBagNormalizer.php @@ -38,7 +38,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = $array = []; if ($data->getSystemMessage()) { - $array['system'][]['text'] = $data->getSystemMessage()->content; + $array['system'][]['text'] = $data->getSystemMessage()->getContent(); } $array['messages'] = $this->normalizer->normalize($data->withoutSystemMessage()->getMessages(), $format, $context); diff --git a/src/platform/src/Bridge/Bedrock/Nova/Contract/ToolCallMessageNormalizer.php b/src/platform/src/Bridge/Bedrock/Nova/Contract/ToolCallMessageNormalizer.php index d6cf052ae..513a89244 100644 --- a/src/platform/src/Bridge/Bedrock/Nova/Contract/ToolCallMessageNormalizer.php +++ b/src/platform/src/Bridge/Bedrock/Nova/Contract/ToolCallMessageNormalizer.php @@ -45,8 +45,8 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'content' => [ [ 'toolResult' => [ - 'toolUseId' => $data->toolCall->getId(), - 'content' => [['json' => $data->content]], + 'toolUseId' => $data->getToolCall()->getId(), + 'content' => [['json' => $data->getContent()]], ], ], ], diff --git a/src/platform/src/Bridge/Bedrock/Nova/Contract/UserMessageNormalizer.php b/src/platform/src/Bridge/Bedrock/Nova/Contract/UserMessageNormalizer.php index efcfccb7d..ae3a622d0 100644 --- a/src/platform/src/Bridge/Bedrock/Nova/Contract/UserMessageNormalizer.php +++ b/src/platform/src/Bridge/Bedrock/Nova/Contract/UserMessageNormalizer.php @@ -44,10 +44,10 @@ public function normalize(mixed $data, ?string $format = null, array $context = { $array = ['role' => $data->getRole()->value]; - foreach ($data->content as $value) { + foreach ($data->getContent() as $value) { $contentPart = []; if ($value instanceof Text) { - $contentPart['text'] = $value->text; + $contentPart['text'] = $value->getText(); } elseif ($value instanceof Image) { $contentPart['image']['format'] = u($value->getFormat())->replace('image/', '')->replace('jpg', 'jpeg')->toString(); $contentPart['image']['source']['bytes'] = $value->asBase64(); diff --git a/src/platform/src/Bridge/Gemini/Contract/AssistantMessageNormalizer.php b/src/platform/src/Bridge/Gemini/Contract/AssistantMessageNormalizer.php index bc6ad687d..d41b7c294 100644 --- a/src/platform/src/Bridge/Gemini/Contract/AssistantMessageNormalizer.php +++ b/src/platform/src/Bridge/Gemini/Contract/AssistantMessageNormalizer.php @@ -30,18 +30,18 @@ public function normalize(mixed $data, ?string $format = null, array $context = { $normalized = []; - if (isset($data->content)) { - $normalized['text'] = $data->content; + if (null !== $data->getContent()) { + $normalized['text'] = $data->getContent(); } - if (isset($data->toolCalls[0])) { + if ($data->hasToolCalls()) { $normalized['functionCall'] = [ - 'id' => $data->toolCalls[0]->getId(), - 'name' => $data->toolCalls[0]->getName(), + 'id' => $data->getToolCalls()[0]->getId(), + 'name' => $data->getToolCalls()[0]->getName(), ]; - if ($data->toolCalls[0]->getArguments()) { - $normalized['functionCall']['args'] = $data->toolCalls[0]->getArguments(); + if ($data->getToolCalls()[0]->getArguments()) { + $normalized['functionCall']['args'] = $data->getToolCalls()[0]->getArguments(); } } diff --git a/src/platform/src/Bridge/Gemini/Contract/MessageBagNormalizer.php b/src/platform/src/Bridge/Gemini/Contract/MessageBagNormalizer.php index fe133db53..c40370419 100644 --- a/src/platform/src/Bridge/Gemini/Contract/MessageBagNormalizer.php +++ b/src/platform/src/Bridge/Gemini/Contract/MessageBagNormalizer.php @@ -43,7 +43,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = if (null !== $systemMessage = $data->getSystemMessage()) { $array['system_instruction'] = [ - 'parts' => [['text' => $systemMessage->content]], + 'parts' => [['text' => $systemMessage->getContent()]], ]; } diff --git a/src/platform/src/Bridge/Gemini/Contract/ToolCallMessageNormalizer.php b/src/platform/src/Bridge/Gemini/Contract/ToolCallMessageNormalizer.php index 2053aa532..31bcc39e6 100644 --- a/src/platform/src/Bridge/Gemini/Contract/ToolCallMessageNormalizer.php +++ b/src/platform/src/Bridge/Gemini/Contract/ToolCallMessageNormalizer.php @@ -34,12 +34,13 @@ final class ToolCallMessageNormalizer extends ModelContractNormalizer */ public function normalize(mixed $data, ?string $format = null, array $context = []): array { - $resultContent = json_validate($data->content) ? json_decode($data->content, true) : $data->content; + $resultContent = json_validate($data->getContent()) + ? json_decode($data->getContent(), true) : $data->getContent(); return [[ 'functionResponse' => array_filter([ - 'id' => $data->toolCall->getId(), - 'name' => $data->toolCall->getName(), + 'id' => $data->getToolCall()->getId(), + 'name' => $data->getToolCall()->getName(), 'response' => \is_array($resultContent) ? $resultContent : [ 'rawResponse' => $resultContent, // Gemini expects the response to be an object, but not everyone uses objects as their responses. ], diff --git a/src/platform/src/Bridge/Gemini/Contract/UserMessageNormalizer.php b/src/platform/src/Bridge/Gemini/Contract/UserMessageNormalizer.php index e72d780ca..a59530e4a 100644 --- a/src/platform/src/Bridge/Gemini/Contract/UserMessageNormalizer.php +++ b/src/platform/src/Bridge/Gemini/Contract/UserMessageNormalizer.php @@ -31,9 +31,9 @@ final class UserMessageNormalizer extends ModelContractNormalizer public function normalize(mixed $data, ?string $format = null, array $context = []): array { $parts = []; - foreach ($data->content as $content) { + foreach ($data->getContent() as $content) { if ($content instanceof Text) { - $parts[] = ['text' => $content->text]; + $parts[] = ['text' => $content->getText()]; } if ($content instanceof File) { $parts[] = ['inline_data' => [ diff --git a/src/platform/src/Bridge/Meta/LlamaPromptConverter.php b/src/platform/src/Bridge/Meta/LlamaPromptConverter.php index 40c1efe2d..acdc3bc31 100644 --- a/src/platform/src/Bridge/Meta/LlamaPromptConverter.php +++ b/src/platform/src/Bridge/Meta/LlamaPromptConverter.php @@ -44,44 +44,44 @@ public function convertMessage(UserMessage|SystemMessage|AssistantMessage $messa return trim(<<<|start_header_id|>system<|end_header_id|> - {$message->content}<|eot_id|> + {$message->getContent()}<|eot_id|> SYSTEM); } if ($message instanceof AssistantMessage) { - if ('' === $message->content || null === $message->content) { + if ('' === $message->getContent() || null === $message->getContent()) { return ''; } return trim(<<{$message->getRole()->value}<|end_header_id|> - {$message->content}<|eot_id|> + {$message->getContent()}<|eot_id|> ASSISTANT); } // Handling of UserMessage - $count = \count($message->content); + $count = \count($message->getContent()); $contentParts = []; if ($count > 1) { - foreach ($message->content as $value) { + foreach ($message->getContent() as $value) { if ($value instanceof Text) { - $contentParts[] = $value->text; + $contentParts[] = $value->getText(); } if ($value instanceof ImageUrl) { - $contentParts[] = $value->url; + $contentParts[] = $value->getUrl(); } } } elseif (1 === $count) { - $value = $message->content[0]; + $value = $message->getContent()[0]; if ($value instanceof Text) { - $contentParts[] = $value->text; + $contentParts[] = $value->getText(); } if ($value instanceof ImageUrl) { - $contentParts[] = $value->url; + $contentParts[] = $value->getUrl(); } } else { throw new RuntimeException('Unsupported message type.'); diff --git a/src/platform/src/Bridge/Mistral/Contract/DocumentUrlNormalizer.php b/src/platform/src/Bridge/Mistral/Contract/DocumentUrlNormalizer.php index 343e714d1..107b1a29a 100644 --- a/src/platform/src/Bridge/Mistral/Contract/DocumentUrlNormalizer.php +++ b/src/platform/src/Bridge/Mistral/Contract/DocumentUrlNormalizer.php @@ -27,7 +27,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = { return [ 'type' => 'document_url', - 'document_url' => $data->url, + 'document_url' => $data->getUrl(), ]; } diff --git a/src/platform/src/Bridge/Ollama/Contract/AssistantMessageNormalizer.php b/src/platform/src/Bridge/Ollama/Contract/AssistantMessageNormalizer.php index 7edc08c74..afd055798 100644 --- a/src/platform/src/Bridge/Ollama/Contract/AssistantMessageNormalizer.php +++ b/src/platform/src/Bridge/Ollama/Contract/AssistantMessageNormalizer.php @@ -46,7 +46,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = { return [ 'role' => Role::Assistant, - 'content' => $data->content ?? '', + 'content' => $data->getContent() ?? '', 'tool_calls' => array_values(array_map(function (ToolCall $message): array { return [ 'type' => 'function', @@ -56,7 +56,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'arguments' => [] === $message->getArguments() ? new \stdClass() : $message->getArguments(), ], ]; - }, $data->toolCalls ?? [])), + }, $data->getToolCalls() ?? [])), ]; } diff --git a/src/platform/src/Bridge/Perplexity/Contract/FileUrlNormalizer.php b/src/platform/src/Bridge/Perplexity/Contract/FileUrlNormalizer.php index 895f5c1bb..64299d55a 100644 --- a/src/platform/src/Bridge/Perplexity/Contract/FileUrlNormalizer.php +++ b/src/platform/src/Bridge/Perplexity/Contract/FileUrlNormalizer.php @@ -31,7 +31,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = return [ 'type' => 'file_url', 'file_url' => [ - 'url' => $data->url, + 'url' => $data->getUrl(), ], ]; } diff --git a/src/platform/src/Bridge/VertexAi/Contract/AssistantMessageNormalizer.php b/src/platform/src/Bridge/VertexAi/Contract/AssistantMessageNormalizer.php index 613e93fd3..c720e94bd 100644 --- a/src/platform/src/Bridge/VertexAi/Contract/AssistantMessageNormalizer.php +++ b/src/platform/src/Bridge/VertexAi/Contract/AssistantMessageNormalizer.php @@ -38,17 +38,17 @@ public function normalize(mixed $data, ?string $format = null, array $context = { $normalized = []; - if (isset($data->content)) { - $normalized[] = ['text' => $data->content]; + if (null !== $data->getContent()) { + $normalized[] = ['text' => $data->getContent()]; } - if (isset($data->toolCalls[0])) { + if ($data->hasToolCalls()) { $normalized['functionCall'] = [ - 'name' => $data->toolCalls[0]->getName(), + 'name' => $data->getToolCalls()[0]->getName(), ]; - if ($data->toolCalls[0]->getArguments()) { - $normalized['functionCall']['args'] = $data->toolCalls[0]->getArguments(); + if ($data->getToolCalls()[0]->getArguments()) { + $normalized['functionCall']['args'] = $data->getToolCalls()[0]->getArguments(); } } diff --git a/src/platform/src/Bridge/VertexAi/Contract/MessageBagNormalizer.php b/src/platform/src/Bridge/VertexAi/Contract/MessageBagNormalizer.php index 7b7a0b8de..29fe5763f 100644 --- a/src/platform/src/Bridge/VertexAi/Contract/MessageBagNormalizer.php +++ b/src/platform/src/Bridge/VertexAi/Contract/MessageBagNormalizer.php @@ -46,7 +46,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = if (null !== $systemMessage = $data->getSystemMessage()) { $requestData['systemInstruction'] = [ - 'parts' => [['text' => $systemMessage->content]], + 'parts' => [['text' => $systemMessage->getContent()]], ]; } diff --git a/src/platform/src/Bridge/VertexAi/Contract/ToolCallMessageNormalizer.php b/src/platform/src/Bridge/VertexAi/Contract/ToolCallMessageNormalizer.php index 798637221..f21566b74 100644 --- a/src/platform/src/Bridge/VertexAi/Contract/ToolCallMessageNormalizer.php +++ b/src/platform/src/Bridge/VertexAi/Contract/ToolCallMessageNormalizer.php @@ -35,11 +35,11 @@ final class ToolCallMessageNormalizer extends ModelContractNormalizer */ public function normalize(mixed $data, ?string $format = null, array $context = []): array { - $resultContent = json_validate($data->content) ? json_decode($data->content, true, 512, \JSON_THROW_ON_ERROR) : $data->content; + $resultContent = json_validate($data->getContent()) ? json_decode($data->getContent(), true, 512, \JSON_THROW_ON_ERROR) : $data->getContent(); return [[ 'functionResponse' => array_filter([ - 'name' => $data->toolCall->getName(), + 'name' => $data->getToolCall()->getName(), 'response' => \is_array($resultContent) ? $resultContent : [ 'rawResponse' => $resultContent, ], diff --git a/src/platform/src/Bridge/VertexAi/Contract/UserMessageNormalizer.php b/src/platform/src/Bridge/VertexAi/Contract/UserMessageNormalizer.php index eb91aa52b..95ddaddcd 100644 --- a/src/platform/src/Bridge/VertexAi/Contract/UserMessageNormalizer.php +++ b/src/platform/src/Bridge/VertexAi/Contract/UserMessageNormalizer.php @@ -31,9 +31,9 @@ final class UserMessageNormalizer extends ModelContractNormalizer public function normalize(mixed $data, ?string $format = null, array $context = []): array { $parts = []; - foreach ($data->content as $content) { + foreach ($data->getContent() as $content) { if ($content instanceof Text) { - $parts[] = ['text' => $content->text]; + $parts[] = ['text' => $content->getText()]; } if ($content instanceof File) { diff --git a/src/platform/src/Contract/Normalizer/Message/AssistantMessageNormalizer.php b/src/platform/src/Contract/Normalizer/Message/AssistantMessageNormalizer.php index ad61c8f79..c6d37bd70 100644 --- a/src/platform/src/Contract/Normalizer/Message/AssistantMessageNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/AssistantMessageNormalizer.php @@ -46,12 +46,12 @@ public function normalize(mixed $data, ?string $format = null, array $context = 'role' => $data->getRole()->value, ]; - if (null !== $data->content) { - $array['content'] = $data->content; + if (null !== $data->getContent()) { + $array['content'] = $data->getContent(); } if ($data->hasToolCalls()) { - $array['tool_calls'] = $this->normalizer->normalize($data->toolCalls, $format, $context); + $array['tool_calls'] = $this->normalizer->normalize($data->getToolCalls(), $format, $context); } return $array; diff --git a/src/platform/src/Contract/Normalizer/Message/Content/ImageUrlNormalizer.php b/src/platform/src/Contract/Normalizer/Message/Content/ImageUrlNormalizer.php index 6b61cd7da..4ab2808a4 100644 --- a/src/platform/src/Contract/Normalizer/Message/Content/ImageUrlNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/Content/ImageUrlNormalizer.php @@ -40,7 +40,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = { return [ 'type' => 'image_url', - 'image_url' => ['url' => $data->url], + 'image_url' => ['url' => $data->getUrl()], ]; } } diff --git a/src/platform/src/Contract/Normalizer/Message/Content/TextNormalizer.php b/src/platform/src/Contract/Normalizer/Message/Content/TextNormalizer.php index 72860679d..4c29944ef 100644 --- a/src/platform/src/Contract/Normalizer/Message/Content/TextNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/Content/TextNormalizer.php @@ -38,6 +38,6 @@ public function getSupportedTypes(?string $format): array */ public function normalize(mixed $data, ?string $format = null, array $context = []): array { - return ['type' => 'text', 'text' => $data->text]; + return ['type' => 'text', 'text' => $data->getText()]; } } diff --git a/src/platform/src/Contract/Normalizer/Message/SystemMessageNormalizer.php b/src/platform/src/Contract/Normalizer/Message/SystemMessageNormalizer.php index 4985b87d1..c4eb7743e 100644 --- a/src/platform/src/Contract/Normalizer/Message/SystemMessageNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/SystemMessageNormalizer.php @@ -40,7 +40,7 @@ public function normalize(mixed $data, ?string $format = null, array $context = { return [ 'role' => $data->getRole()->value, - 'content' => $data->content, + 'content' => $data->getContent(), ]; } } diff --git a/src/platform/src/Contract/Normalizer/Message/ToolCallMessageNormalizer.php b/src/platform/src/Contract/Normalizer/Message/ToolCallMessageNormalizer.php index e4313d441..e75fa4990 100644 --- a/src/platform/src/Contract/Normalizer/Message/ToolCallMessageNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/ToolCallMessageNormalizer.php @@ -36,6 +36,8 @@ public function getSupportedTypes(?string $format): array } /** + * @param ToolCallMessage $data + * * @return array{ * role: 'tool', * content: string, @@ -46,8 +48,8 @@ public function normalize(mixed $data, ?string $format = null, array $context = { return [ 'role' => $data->getRole()->value, - 'content' => $this->normalizer->normalize($data->content, $format, $context), - 'tool_call_id' => $data->toolCall->getId(), + 'content' => $this->normalizer->normalize($data->getContent(), $format, $context), + 'tool_call_id' => $data->getToolCall()->getId(), ]; } } diff --git a/src/platform/src/Contract/Normalizer/Message/UserMessageNormalizer.php b/src/platform/src/Contract/Normalizer/Message/UserMessageNormalizer.php index af7794f5c..0af599809 100644 --- a/src/platform/src/Contract/Normalizer/Message/UserMessageNormalizer.php +++ b/src/platform/src/Contract/Normalizer/Message/UserMessageNormalizer.php @@ -45,13 +45,13 @@ public function normalize(mixed $data, ?string $format = null, array $context = { $array = ['role' => $data->getRole()->value]; - if (1 === \count($data->content) && $data->content[0] instanceof Text) { - $array['content'] = $data->content[0]->text; + if (1 === \count($data->getContent()) && $data->getContent()[0] instanceof Text) { + $array['content'] = $data->getContent()[0]->getText(); return $array; } - $array['content'] = $this->normalizer->normalize($data->content, $format, $context); + $array['content'] = $this->normalizer->normalize($data->getContent(), $format, $context); return $array; } diff --git a/src/platform/src/Message/AssistantMessage.php b/src/platform/src/Message/AssistantMessage.php index 3a5a17410..3bb7370b2 100644 --- a/src/platform/src/Message/AssistantMessage.php +++ b/src/platform/src/Message/AssistantMessage.php @@ -11,6 +11,7 @@ namespace Symfony\AI\Platform\Message; +use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\AI\Platform\Result\ToolCall; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; @@ -19,16 +20,18 @@ /** * @author Denis Zunke */ -final readonly class AssistantMessage implements MessageInterface +final class AssistantMessage implements MessageInterface { - public AbstractUid&TimeBasedUidInterface $id; + use MetadataAwareTrait; + + private readonly AbstractUid&TimeBasedUidInterface $id; /** * @param ?ToolCall[] $toolCalls */ public function __construct( - public ?string $content = null, - public ?array $toolCalls = null, + private ?string $content = null, + private ?array $toolCalls = null, ) { $this->id = Uuid::v7(); } @@ -47,4 +50,17 @@ public function hasToolCalls(): bool { return null !== $this->toolCalls && [] !== $this->toolCalls; } + + /** + * @return ?ToolCall[] + */ + public function getToolCalls(): ?array + { + return $this->toolCalls; + } + + public function getContent(): ?string + { + return $this->content; + } } diff --git a/src/platform/src/Message/Content/DocumentUrl.php b/src/platform/src/Message/Content/DocumentUrl.php index e44e9e562..dea8507ca 100644 --- a/src/platform/src/Message/Content/DocumentUrl.php +++ b/src/platform/src/Message/Content/DocumentUrl.php @@ -17,7 +17,12 @@ final readonly class DocumentUrl implements ContentInterface { public function __construct( - public string $url, + private string $url, ) { } + + public function getUrl(): string + { + return $this->url; + } } diff --git a/src/platform/src/Message/Content/ImageUrl.php b/src/platform/src/Message/Content/ImageUrl.php index 63420ff4a..882e75837 100644 --- a/src/platform/src/Message/Content/ImageUrl.php +++ b/src/platform/src/Message/Content/ImageUrl.php @@ -17,7 +17,12 @@ final readonly class ImageUrl implements ContentInterface { public function __construct( - public string $url, + private string $url, ) { } + + public function getUrl(): string + { + return $this->url; + } } diff --git a/src/platform/src/Message/Content/Text.php b/src/platform/src/Message/Content/Text.php index ddf371aff..362816c02 100644 --- a/src/platform/src/Message/Content/Text.php +++ b/src/platform/src/Message/Content/Text.php @@ -17,7 +17,12 @@ final readonly class Text implements ContentInterface { public function __construct( - public string $text, + private string $text, ) { } + + public function getText(): string + { + return $this->text; + } } diff --git a/src/platform/src/Message/MessageInterface.php b/src/platform/src/Message/MessageInterface.php index 7baefe64d..7ca9229c6 100644 --- a/src/platform/src/Message/MessageInterface.php +++ b/src/platform/src/Message/MessageInterface.php @@ -11,6 +11,8 @@ namespace Symfony\AI\Platform\Message; +use Symfony\AI\Platform\Message\Content\ContentInterface; +use Symfony\AI\Platform\Metadata\Metadata; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; @@ -22,4 +24,11 @@ interface MessageInterface public function getRole(): Role; public function getId(): AbstractUid&TimeBasedUidInterface; + + /** + * @return string|ContentInterface[]|null + */ + public function getContent(): string|array|null; + + public function getMetadata(): Metadata; } diff --git a/src/platform/src/Message/SystemMessage.php b/src/platform/src/Message/SystemMessage.php index 98fc69587..d0650773a 100644 --- a/src/platform/src/Message/SystemMessage.php +++ b/src/platform/src/Message/SystemMessage.php @@ -11,6 +11,7 @@ namespace Symfony\AI\Platform\Message; +use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; use Symfony\Component\Uid\Uuid; @@ -18,12 +19,15 @@ /** * @author Denis Zunke */ -final readonly class SystemMessage implements MessageInterface +final class SystemMessage implements MessageInterface { - public AbstractUid&TimeBasedUidInterface $id; + use MetadataAwareTrait; - public function __construct(public string $content) - { + private readonly AbstractUid&TimeBasedUidInterface $id; + + public function __construct( + private readonly string $content, + ) { $this->id = Uuid::v7(); } @@ -36,4 +40,9 @@ public function getId(): AbstractUid&TimeBasedUidInterface { return $this->id; } + + public function getContent(): string + { + return $this->content; + } } diff --git a/src/platform/src/Message/ToolCallMessage.php b/src/platform/src/Message/ToolCallMessage.php index 19beb7fba..c664c6b7b 100644 --- a/src/platform/src/Message/ToolCallMessage.php +++ b/src/platform/src/Message/ToolCallMessage.php @@ -11,6 +11,7 @@ namespace Symfony\AI\Platform\Message; +use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\AI\Platform\Result\ToolCall; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; @@ -19,13 +20,15 @@ /** * @author Denis Zunke */ -final readonly class ToolCallMessage implements MessageInterface +final class ToolCallMessage implements MessageInterface { - public AbstractUid&TimeBasedUidInterface $id; + use MetadataAwareTrait; + + private readonly AbstractUid&TimeBasedUidInterface $id; public function __construct( - public ToolCall $toolCall, - public string $content, + private readonly ToolCall $toolCall, + private readonly string $content, ) { $this->id = Uuid::v7(); } @@ -39,4 +42,14 @@ public function getId(): AbstractUid&TimeBasedUidInterface { return $this->id; } + + public function getToolCall(): ToolCall + { + return $this->toolCall; + } + + public function getContent(): string + { + return $this->content; + } } diff --git a/src/platform/src/Message/UserMessage.php b/src/platform/src/Message/UserMessage.php index e7485c932..445af64c3 100644 --- a/src/platform/src/Message/UserMessage.php +++ b/src/platform/src/Message/UserMessage.php @@ -16,6 +16,7 @@ use Symfony\AI\Platform\Message\Content\Image; use Symfony\AI\Platform\Message\Content\ImageUrl; use Symfony\AI\Platform\Message\Content\Text; +use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; use Symfony\Component\Uid\Uuid; @@ -23,14 +24,16 @@ /** * @author Denis Zunke */ -final readonly class UserMessage implements MessageInterface +final class UserMessage implements MessageInterface { + use MetadataAwareTrait; + /** - * @var list + * @var ContentInterface[] */ - public array $content; + private readonly array $content; - public AbstractUid&TimeBasedUidInterface $id; + private readonly AbstractUid&TimeBasedUidInterface $id; public function __construct( ContentInterface ...$content, @@ -49,6 +52,14 @@ public function getId(): AbstractUid&TimeBasedUidInterface return $this->id; } + /** + * @return ContentInterface[] + */ + public function getContent(): array + { + return $this->content; + } + public function hasAudioContent(): bool { foreach ($this->content as $content) { @@ -76,7 +87,7 @@ public function asText(): ?string $textParts = []; foreach ($this->content as $content) { if ($content instanceof Text) { - $textParts[] = $content->text; + $textParts[] = $content->getText(); } } diff --git a/src/platform/tests/Contract/Normalizer/Message/AssistantMessageNormalizerTest.php b/src/platform/tests/Contract/Normalizer/Message/AssistantMessageNormalizerTest.php index a9e645abf..f057c476f 100644 --- a/src/platform/tests/Contract/Normalizer/Message/AssistantMessageNormalizerTest.php +++ b/src/platform/tests/Contract/Normalizer/Message/AssistantMessageNormalizerTest.php @@ -65,7 +65,7 @@ public function testNormalizeWithToolCalls() $innerNormalizer = $this->createMock(NormalizerInterface::class); $innerNormalizer->expects($this->once()) ->method('normalize') - ->with($message->toolCalls, null, []) + ->with($message->getToolCalls(), null, []) ->willReturn($expectedToolCalls); $this->normalizer->setNormalizer($innerNormalizer); @@ -89,7 +89,7 @@ public function testNormalizeWithNullContent() $innerNormalizer = $this->createMock(NormalizerInterface::class); $innerNormalizer->expects($this->once()) ->method('normalize') - ->with($message->toolCalls, null, []) + ->with($message->getToolCalls(), null, []) ->willReturn($expectedToolCalls); $this->normalizer->setNormalizer($innerNormalizer); diff --git a/src/platform/tests/Contract/Normalizer/Message/ToolCallMessageNormalizerTest.php b/src/platform/tests/Contract/Normalizer/Message/ToolCallMessageNormalizerTest.php index 4e31cfd35..079ba18fe 100644 --- a/src/platform/tests/Contract/Normalizer/Message/ToolCallMessageNormalizerTest.php +++ b/src/platform/tests/Contract/Normalizer/Message/ToolCallMessageNormalizerTest.php @@ -48,7 +48,7 @@ public function testNormalize() $innerNormalizer = $this->createMock(NormalizerInterface::class); $innerNormalizer->expects($this->once()) ->method('normalize') - ->with($message->content, null, []) + ->with($message->getContent(), null, []) ->willReturn($expectedContent); $this->normalizer->setNormalizer($innerNormalizer); diff --git a/src/platform/tests/Contract/Normalizer/Message/UserMessageNormalizerTest.php b/src/platform/tests/Contract/Normalizer/Message/UserMessageNormalizerTest.php index 81760d8d1..23aacfc6f 100644 --- a/src/platform/tests/Contract/Normalizer/Message/UserMessageNormalizerTest.php +++ b/src/platform/tests/Contract/Normalizer/Message/UserMessageNormalizerTest.php @@ -65,7 +65,7 @@ public function testNormalizeWithMixedContent() $innerNormalizer = $this->createMock(NormalizerInterface::class); $innerNormalizer->expects($this->once()) ->method('normalize') - ->with($message->content, null, []) + ->with($message->getContent(), null, []) ->willReturn($expectedContent); $this->normalizer->setNormalizer($innerNormalizer); diff --git a/src/platform/tests/ContractTest.php b/src/platform/tests/ContractTest.php index f53d1f083..64bf3ee5d 100644 --- a/src/platform/tests/ContractTest.php +++ b/src/platform/tests/ContractTest.php @@ -22,10 +22,12 @@ use Symfony\AI\Platform\Message\Content\Audio; use Symfony\AI\Platform\Message\Content\Image; use Symfony\AI\Platform\Message\Content\ImageUrl; +use Symfony\AI\Platform\Message\Content\Text; use Symfony\AI\Platform\Message\Message; use Symfony\AI\Platform\Message\MessageBag; use Symfony\AI\Platform\Message\MessageInterface; use Symfony\AI\Platform\Message\Role; +use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\AI\Platform\Model; use Symfony\Component\Uid\AbstractUid; use Symfony\Component\Uid\TimeBasedUidInterface; @@ -172,6 +174,8 @@ public static function providePayloadTestCases(): iterable ]; $customSerializableMessage = new class implements MessageInterface, \JsonSerializable { + use MetadataAwareTrait; + public function getRole(): Role { return Role::User; @@ -182,6 +186,11 @@ public function getId(): AbstractUid&TimeBasedUidInterface return Uuid::v7(); } + public function getContent(): array + { + return [new Text('This is a custom serializable message.')]; + } + public function jsonSerialize(): array { return [ diff --git a/src/platform/tests/Message/AssistantMessageTest.php b/src/platform/tests/Message/AssistantMessageTest.php index f6767f186..d3883d28f 100644 --- a/src/platform/tests/Message/AssistantMessageTest.php +++ b/src/platform/tests/Message/AssistantMessageTest.php @@ -33,8 +33,8 @@ public function testConstructionWithoutToolCallIsPossible() { $message = new AssistantMessage('foo'); - $this->assertSame('foo', $message->content); - $this->assertNull($message->toolCalls); + $this->assertSame('foo', $message->getContent()); + $this->assertNull($message->getToolCalls()); } public function testConstructionWithoutContentIsPossible() @@ -42,8 +42,8 @@ public function testConstructionWithoutContentIsPossible() $toolCall = new ToolCall('foo', 'foo'); $message = new AssistantMessage(toolCalls: [$toolCall]); - $this->assertNull($message->content); - $this->assertSame([$toolCall], $message->toolCalls); + $this->assertNull($message->getContent()); + $this->assertSame([$toolCall], $message->getToolCalls()); $this->assertTrue($message->hasToolCalls()); } @@ -51,9 +51,7 @@ public function testMessageHasUid() { $message = new AssistantMessage('foo'); - $this->assertInstanceOf(UuidV7::class, $message->id); $this->assertInstanceOf(UuidV7::class, $message->getId()); - $this->assertSame($message->id, $message->getId()); } public function testDifferentMessagesHaveDifferentUids() diff --git a/src/platform/tests/Message/Content/ImageUrlTest.php b/src/platform/tests/Message/Content/ImageUrlTest.php index 3e0d25b41..9237ca0b1 100644 --- a/src/platform/tests/Message/Content/ImageUrlTest.php +++ b/src/platform/tests/Message/Content/ImageUrlTest.php @@ -20,6 +20,6 @@ public function testConstructWithValidUrl() { $image = new ImageUrl('https://foo.com/test.png'); - $this->assertSame('https://foo.com/test.png', $image->url); + $this->assertSame('https://foo.com/test.png', $image->getUrl()); } } diff --git a/src/platform/tests/Message/Content/TextTest.php b/src/platform/tests/Message/Content/TextTest.php index 07ace8d53..7c9341e54 100644 --- a/src/platform/tests/Message/Content/TextTest.php +++ b/src/platform/tests/Message/Content/TextTest.php @@ -20,6 +20,6 @@ public function testConstructionIsPossible() { $obj = new Text('foo'); - $this->assertSame('foo', $obj->text); + $this->assertSame('foo', $obj->getText()); } } diff --git a/src/platform/tests/Message/MessageBagTest.php b/src/platform/tests/Message/MessageBagTest.php index a66072396..cbe88e179 100644 --- a/src/platform/tests/Message/MessageBagTest.php +++ b/src/platform/tests/Message/MessageBagTest.php @@ -34,7 +34,7 @@ public function testGetSystemMessage() $systemMessage = $messageBag->getSystemMessage(); - $this->assertSame('My amazing system prompt.', $systemMessage->content); + $this->assertSame('My amazing system prompt.', $systemMessage->getContent()); } public function testGetSystemMessageWithoutSystemMessage() @@ -65,7 +65,7 @@ public function testWith() $newMessageFromBag = $newMessageBag->getMessages()[3]; $this->assertInstanceOf(AssistantMessage::class, $newMessageFromBag); - $this->assertSame('It is time to wake up.', $newMessageFromBag->content); + $this->assertSame('It is time to wake up.', $newMessageFromBag->getContent()); } public function testMerge() @@ -85,7 +85,7 @@ public function testMerge() $messageFromBag = $messageBag->getMessages()[3]; $this->assertInstanceOf(AssistantMessage::class, $messageFromBag); - $this->assertSame('It is time to wake up.', $messageFromBag->content); + $this->assertSame('It is time to wake up.', $messageFromBag->getContent()); } public function testWithoutSystemMessage() @@ -105,12 +105,12 @@ public function testWithoutSystemMessage() $assistantMessage = $newMessageBag->getMessages()[0]; $this->assertInstanceOf(AssistantMessage::class, $assistantMessage); - $this->assertSame('It is time to sleep.', $assistantMessage->content); + $this->assertSame('It is time to sleep.', $assistantMessage->getContent()); $userMessage = $newMessageBag->getMessages()[1]; $this->assertInstanceOf(UserMessage::class, $userMessage); - $this->assertInstanceOf(Text::class, $userMessage->content[0]); - $this->assertSame('Hello, world!', $userMessage->content[0]->text); + $this->assertInstanceOf(Text::class, $userMessage->getContent()[0]); + $this->assertSame('Hello, world!', $userMessage->getContent()[0]->getText()); } public function testPrepend() @@ -129,7 +129,7 @@ public function testPrepend() $newMessageBagMessage = $newMessageBag->getMessages()[0]; $this->assertInstanceOf(SystemMessage::class, $newMessageBagMessage); - $this->assertSame('My amazing system prompt.', $newMessageBagMessage->content); + $this->assertSame('My amazing system prompt.', $newMessageBagMessage->getContent()); } public function testContainsImageReturnsFalseWithoutImage() @@ -178,8 +178,8 @@ public function testGetUserMessage() $userMessage = $messageBag->getUserMessage(); $this->assertInstanceOf(UserMessage::class, $userMessage); - $this->assertInstanceOf(Text::class, $userMessage->content[0]); - $this->assertSame('Hello, world!', $userMessage->content[0]->text); + $this->assertInstanceOf(Text::class, $userMessage->getContent()[0]); + $this->assertSame('Hello, world!', $userMessage->getContent()[0]->getText()); } public function testGetUserMessageReturnsNullWithoutUserMessage() @@ -204,8 +204,8 @@ public function testGetUserMessageReturnsFirstUserMessage() $userMessage = $messageBag->getUserMessage(); $this->assertInstanceOf(UserMessage::class, $userMessage); - $this->assertInstanceOf(Text::class, $userMessage->content[0]); - $this->assertSame('First user message', $userMessage->content[0]->text); + $this->assertInstanceOf(Text::class, $userMessage->getContent()[0]); + $this->assertSame('First user message', $userMessage->getContent()[0]->getText()); } public function testGetUserMessageText() diff --git a/src/platform/tests/Message/MessageTest.php b/src/platform/tests/Message/MessageTest.php index c31a75128..b31a6b238 100644 --- a/src/platform/tests/Message/MessageTest.php +++ b/src/platform/tests/Message/MessageTest.php @@ -24,7 +24,7 @@ public function testCreateSystemMessageWithString() { $message = Message::forSystem('My amazing system prompt.'); - $this->assertSame('My amazing system prompt.', $message->content); + $this->assertSame('My amazing system prompt.', $message->getContent()); } public function testCreateSystemMessageWithStringable() @@ -36,14 +36,14 @@ public function __toString(): string } }); - $this->assertSame('My amazing system prompt.', $message->content); + $this->assertSame('My amazing system prompt.', $message->getContent()); } public function testCreateAssistantMessage() { $message = Message::ofAssistant('It is time to sleep.'); - $this->assertSame('It is time to sleep.', $message->content); + $this->assertSame('It is time to sleep.', $message->getContent()); } public function testCreateAssistantMessageWithToolCalls() @@ -54,7 +54,7 @@ public function testCreateAssistantMessageWithToolCalls() ]; $message = Message::ofAssistant(toolCalls: $toolCalls); - $this->assertCount(2, $message->toolCalls); + $this->assertCount(2, $message->getToolCalls()); $this->assertTrue($message->hasToolCalls()); } @@ -62,9 +62,9 @@ public function testCreateUserMessageWithString() { $message = Message::ofUser('Hi, my name is John.'); - $this->assertCount(1, $message->content); - $this->assertInstanceOf(Text::class, $message->content[0]); - $this->assertSame('Hi, my name is John.', $message->content[0]->text); + $this->assertCount(1, $message->getContent()); + $this->assertInstanceOf(Text::class, $message->getContent()[0]); + $this->assertSame('Hi, my name is John.', $message->getContent()[0]->getText()); } public function testCreateUserMessageWithStringable() @@ -76,9 +76,9 @@ public function __toString(): string } }); - $this->assertCount(1, $message->content); - $this->assertInstanceOf(Text::class, $message->content[0]); - $this->assertSame('Hi, my name is John.', $message->content[0]->text); + $this->assertCount(1, $message->getContent()); + $this->assertInstanceOf(Text::class, $message->getContent()[0]); + $this->assertSame('Hi, my name is John.', $message->getContent()[0]->getText()); } public function testCreateUserMessageContentInterfaceImplementingStringable() @@ -90,8 +90,8 @@ public function __toString(): string } }); - $this->assertCount(1, $message->content); - $this->assertInstanceOf(ContentInterface::class, $message->content[0]); + $this->assertCount(1, $message->getContent()); + $this->assertInstanceOf(ContentInterface::class, $message->getContent()[0]); } public function testCreateUserMessageWithTextContent() @@ -99,7 +99,7 @@ public function testCreateUserMessageWithTextContent() $text = new Text('Hi, my name is John.'); $message = Message::ofUser($text); - $this->assertSame([$text], $message->content); + $this->assertSame([$text], $message->getContent()); } public function testCreateUserMessageWithImages() @@ -111,7 +111,7 @@ public function testCreateUserMessageWithImages() new ImageUrl('http://images.local/my-image2.png'), ); - $this->assertCount(4, $message->content); + $this->assertCount(4, $message->getContent()); } public function testCreateToolCallMessage() @@ -119,7 +119,7 @@ public function testCreateToolCallMessage() $toolCall = new ToolCall('call_123456', 'my_tool', ['foo' => 'bar']); $message = Message::ofToolCall($toolCall, 'Foo bar.'); - $this->assertSame('Foo bar.', $message->content); - $this->assertSame($toolCall, $message->toolCall); + $this->assertSame('Foo bar.', $message->getContent()); + $this->assertSame($toolCall, $message->getToolCall()); } } diff --git a/src/platform/tests/Message/SystemMessageTest.php b/src/platform/tests/Message/SystemMessageTest.php index 0d88f91d3..0d8df0e48 100644 --- a/src/platform/tests/Message/SystemMessageTest.php +++ b/src/platform/tests/Message/SystemMessageTest.php @@ -28,16 +28,14 @@ public function testConstructionIsPossible() $message = new SystemMessage('foo'); $this->assertSame(Role::System, $message->getRole()); - $this->assertSame('foo', $message->content); + $this->assertSame('foo', $message->getContent()); } public function testMessageHasUid() { $message = new SystemMessage('foo'); - $this->assertInstanceOf(UuidV7::class, $message->id); $this->assertInstanceOf(UuidV7::class, $message->getId()); - $this->assertSame($message->id, $message->getId()); } public function testDifferentMessagesHaveDifferentUids() diff --git a/src/platform/tests/Message/ToolCallMessageTest.php b/src/platform/tests/Message/ToolCallMessageTest.php index fde79f25d..eccf06bc4 100644 --- a/src/platform/tests/Message/ToolCallMessageTest.php +++ b/src/platform/tests/Message/ToolCallMessageTest.php @@ -28,8 +28,8 @@ public function testConstructionIsPossible() $toolCall = new ToolCall('foo', 'bar'); $obj = new ToolCallMessage($toolCall, 'bar'); - $this->assertSame($toolCall, $obj->toolCall); - $this->assertSame('bar', $obj->content); + $this->assertSame($toolCall, $obj->getToolCall()); + $this->assertSame('bar', $obj->getContent()); } public function testMessageHasUid() @@ -37,9 +37,7 @@ public function testMessageHasUid() $toolCall = new ToolCall('foo', 'bar'); $message = new ToolCallMessage($toolCall, 'bar'); - $this->assertInstanceOf(UuidV7::class, $message->id); $this->assertInstanceOf(UuidV7::class, $message->getId()); - $this->assertSame($message->id, $message->getId()); } public function testDifferentMessagesHaveDifferentUids() diff --git a/src/platform/tests/Message/UserMessageTest.php b/src/platform/tests/Message/UserMessageTest.php index adc9dea20..155a6366a 100644 --- a/src/platform/tests/Message/UserMessageTest.php +++ b/src/platform/tests/Message/UserMessageTest.php @@ -31,16 +31,16 @@ public function testConstructionIsPossible() $obj = new UserMessage(new Text('foo')); $this->assertSame(Role::User, $obj->getRole()); - $this->assertCount(1, $obj->content); - $this->assertInstanceOf(Text::class, $obj->content[0]); - $this->assertSame('foo', $obj->content[0]->text); + $this->assertCount(1, $obj->getContent()); + $this->assertInstanceOf(Text::class, $obj->getContent()[0]); + $this->assertSame('foo', $obj->getContent()[0]->getText()); } public function testConstructionIsPossibleWithMultipleContent() { $message = new UserMessage(new Text('foo'), new ImageUrl('https://foo.com/bar.jpg')); - $this->assertCount(2, $message->content); + $this->assertCount(2, $message->getContent()); } public function testHasAudioContentWithoutAudio() @@ -75,9 +75,7 @@ public function testMessageHasUid() { $message = new UserMessage(new Text('foo')); - $this->assertInstanceOf(UuidV7::class, $message->id); $this->assertInstanceOf(UuidV7::class, $message->getId()); - $this->assertSame($message->id, $message->getId()); } public function testDifferentMessagesHaveDifferentUids()