1414use Symfony \AI \Agent \Chat \InitializableMessageStoreInterface ;
1515use Symfony \AI \Agent \Chat \MessageStoreInterface ;
1616use Symfony \AI \Agent \Exception \InvalidArgumentException ;
17+ use Symfony \AI \Agent \Exception \LogicException ;
1718use Symfony \AI \Platform \Message \AssistantMessage ;
1819use Symfony \AI \Platform \Message \Content \Audio ;
1920use Symfony \AI \Platform \Message \Content \ContentInterface ;
2627use Symfony \AI \Platform \Message \MessageBagInterface ;
2728use Symfony \AI \Platform \Message \MessageInterface ;
2829use Symfony \AI \Platform \Message \SystemMessage ;
30+ use Symfony \AI \Platform \Message \ToolCallMessage ;
2931use Symfony \AI \Platform \Message \UserMessage ;
32+ use Symfony \AI \Platform \Result \ToolCall ;
3033use Symfony \Contracts \HttpClient \HttpClientInterface ;
3134
3235/**
@@ -77,7 +80,7 @@ public function initialize(array $options = []): void
7780 }
7881
7982 /**
80- * @param array<string, mixed> $payload
83+ * @param array<string, mixed>|list<array<string, mixed>> $payload
8184 *
8285 * @return array<string, mixed>
8386 */
@@ -94,12 +97,28 @@ private function request(string $method, string $endpoint, array $payload = []):
9497 return $ result ->toArray ();
9598 }
9699
100+ /**
101+ * @return array<string, mixed>
102+ */
97103 private function convertToIndexableArray (MessageInterface $ message ): array
98104 {
105+ $ toolsCalls = [];
106+
107+ if ($ message instanceof AssistantMessage && $ message ->hasToolCalls ()) {
108+ $ toolsCalls = array_map (
109+ static fn (ToolCall $ toolCall ): array => $ toolCall ->jsonSerialize (),
110+ $ message ->toolCalls ,
111+ );
112+ }
113+
114+ if ($ message instanceof ToolCallMessage) {
115+ $ toolsCalls = $ message ->toolCall ->jsonSerialize ();
116+ }
117+
99118 return [
100119 'id ' => $ message ->getId ()->toRfc4122 (),
101120 'type ' => $ message ::class,
102- 'content ' => ($ message instanceof SystemMessage || $ message instanceof AssistantMessage) ? $ message ->content : '' ,
121+ 'content ' => ($ message instanceof SystemMessage || $ message instanceof AssistantMessage || $ message instanceof ToolCallMessage ) ? $ message ->content : '' ,
103122 'contentAsBase64 ' => ($ message instanceof UserMessage && [] !== $ message ->content ) ? array_map (
104123 static fn (ContentInterface $ content ) => [
105124 'type ' => $ content ::class,
@@ -110,15 +129,18 @@ private function convertToIndexableArray(MessageInterface $message): array
110129 Audio::class => $ content ->asBase64 (),
111130 ImageUrl::class,
112131 DocumentUrl::class => $ content ->url ,
113- default => throw new \ LogicException (\sprintf ('Unknown content type "%s". ' , $ content ::class)),
132+ default => throw new LogicException (\sprintf ('Unknown content type "%s". ' , $ content ::class)),
114133 },
115134 ],
116135 $ message ->content ,
117136 ) : [],
118- 'toolsCalls ' => ( $ message instanceof AssistantMessage && $ message -> hasToolCalls ()) ? $ message -> toolCalls : [] ,
137+ 'toolsCalls ' => $ toolsCalls ,
119138 ];
120139 }
121140
141+ /**
142+ * @param array<string, mixed> $payload
143+ */
122144 private function convertToMessage (array $ payload ): MessageInterface
123145 {
124146 $ type = $ payload ['type ' ];
@@ -127,14 +149,29 @@ private function convertToMessage(array $payload): MessageInterface
127149
128150 return match ($ type ) {
129151 SystemMessage::class => new SystemMessage ($ content ),
130- AssistantMessage::class => new AssistantMessage ($ content , $ payload ['toolsCalls ' ] ?? []),
152+ AssistantMessage::class => new AssistantMessage ($ content , array_map (
153+ static fn (array $ toolsCall ): ToolCall => new ToolCall (
154+ $ toolsCall ['id ' ],
155+ $ toolsCall ['function ' ]['name ' ],
156+ json_decode ($ toolsCall ['function ' ]['arguments ' ], true )
157+ ),
158+ $ payload ['toolsCalls ' ],
159+ )),
131160 UserMessage::class => new UserMessage (...array_map (
132161 static fn (array $ contentAsBase64 ) => \in_array ($ contentAsBase64 ['type ' ], [File::class, Image::class, Audio::class], true )
133162 ? $ contentAsBase64 ['type ' ]::fromDataUrl ($ contentAsBase64 ['content ' ])
134163 : new $ contentAsBase64 ['type ' ]($ contentAsBase64 ['content ' ]),
135164 $ contentAsBase64 ,
136165 )),
137- default => throw new \LogicException (\sprintf ('Unknown message type "%s". ' , $ type )),
166+ ToolCallMessage::class => new ToolCallMessage (
167+ new ToolCall (
168+ $ payload ['toolsCalls ' ]['id ' ],
169+ $ payload ['toolsCalls ' ]['function ' ]['name ' ],
170+ json_decode ($ payload ['toolsCalls ' ]['function ' ]['arguments ' ], true )
171+ ),
172+ $ content
173+ ),
174+ default => throw new LogicException (\sprintf ('Unknown message type "%s". ' , $ type )),
138175 };
139176 }
140177}
0 commit comments