1212namespace Symfony \AI \Chat \Bridge \Pogocache ;
1313
1414use Symfony \AI \Chat \Exception \InvalidArgumentException ;
15- use Symfony \AI \Chat \Exception \LogicException ;
1615use Symfony \AI \Chat \ManagedStoreInterface ;
16+ use Symfony \AI \Chat \MessageNormalizer ;
1717use Symfony \AI \Chat \MessageStoreInterface ;
18- use Symfony \AI \Platform \Message \AssistantMessage ;
19- use Symfony \AI \Platform \Message \Content \Audio ;
20- use Symfony \AI \Platform \Message \Content \ContentInterface ;
21- use Symfony \AI \Platform \Message \Content \DocumentUrl ;
22- use Symfony \AI \Platform \Message \Content \File ;
23- use Symfony \AI \Platform \Message \Content \Image ;
24- use Symfony \AI \Platform \Message \Content \ImageUrl ;
25- use Symfony \AI \Platform \Message \Content \Text ;
2618use Symfony \AI \Platform \Message \MessageBag ;
2719use Symfony \AI \Platform \Message \MessageInterface ;
28- use Symfony \AI \Platform \Message \SystemMessage ;
29- use Symfony \AI \Platform \Message \ToolCallMessage ;
30- use Symfony \AI \Platform \Message \UserMessage ;
31- use Symfony \AI \Platform \Result \ToolCall ;
20+ use Symfony \Component \Serializer \Encoder \JsonEncoder ;
21+ use Symfony \Component \Serializer \Normalizer \ArrayDenormalizer ;
22+ use Symfony \Component \Serializer \Normalizer \DenormalizerInterface ;
23+ use Symfony \Component \Serializer \Normalizer \NormalizerInterface ;
24+ use Symfony \Component \Serializer \Serializer ;
25+ use Symfony \Component \Serializer \SerializerInterface ;
3226use Symfony \Contracts \HttpClient \HttpClientInterface ;
3327
3428/**
@@ -41,6 +35,10 @@ public function __construct(
4135 private readonly string $ host ,
4236 #[\SensitiveParameter] private readonly string $ password ,
4337 private readonly string $ key = '_message_store_pogocache ' ,
38+ private readonly SerializerInterface &NormalizerInterface &DenormalizerInterface $ serializer = new Serializer ([
39+ new ArrayDenormalizer (),
40+ new MessageNormalizer (),
41+ ], [new JsonEncoder ()]),
4442 ) {
4543 }
4644
@@ -60,11 +58,9 @@ public function drop(): void
6058
6159 public function save (MessageBag $ messages ): void
6260 {
63- $ messages = $ messages ->getMessages ();
64-
6561 $ this ->request ('PUT ' , $ this ->key , array_map (
66- $ this ->convertToIndexableArray (... ),
67- $ messages ,
62+ fn ( MessageInterface $ message ): array => $ this ->serializer -> normalize ( $ message ),
63+ $ messages-> getMessages () ,
6864 ));
6965 }
7066
@@ -73,7 +69,7 @@ public function load(): MessageBag
7369 $ messages = $ this ->request ('GET ' , $ this ->key );
7470
7571 return new MessageBag (...array_map (
76- $ this ->convertToMessage (... ),
72+ fn ( array $ message ): MessageInterface => $ this ->serializer -> denormalize ( $ message , MessageInterface::class ),
7773 $ messages ,
7874 ));
7975 }
@@ -97,87 +93,4 @@ private function request(string $method, string $endpoint, array $payload = []):
9793
9894 return [];
9995 }
100-
101- /**
102- * @return array<string, mixed>
103- */
104- private function convertToIndexableArray (MessageInterface $ message ): array
105- {
106- $ toolsCalls = [];
107-
108- if ($ message instanceof AssistantMessage && $ message ->hasToolCalls ()) {
109- $ toolsCalls = array_map (
110- static fn (ToolCall $ toolCall ): array => $ toolCall ->jsonSerialize (),
111- $ message ->getToolCalls (),
112- );
113- }
114-
115- if ($ message instanceof ToolCallMessage) {
116- $ toolsCalls = $ message ->getToolCall ()->jsonSerialize ();
117- }
118-
119- return [
120- 'id ' => $ message ->getId ()->toRfc4122 (),
121- 'type ' => $ message ::class,
122- 'content ' => ($ message instanceof SystemMessage || $ message instanceof AssistantMessage || $ message instanceof ToolCallMessage) ? $ message ->getContent () : '' ,
123- 'contentAsBase64 ' => ($ message instanceof UserMessage && [] !== $ message ->getContent ()) ? array_map (
124- static fn (ContentInterface $ content ) => [
125- 'type ' => $ content ::class,
126- 'content ' => match ($ content ::class) {
127- Text::class => $ content ->getText (),
128- File::class,
129- Image::class,
130- Audio::class => $ content ->asBase64 (),
131- ImageUrl::class,
132- DocumentUrl::class => $ content ->getUrl (),
133- default => throw new LogicException (\sprintf ('Unknown content type "%s". ' , $ content ::class)),
134- },
135- ],
136- $ message ->getContent (),
137- ) : [],
138- 'toolsCalls ' => $ toolsCalls ,
139- 'metadata ' => $ message ->getMetadata ()->all (),
140- ];
141- }
142-
143- /**
144- * @param array<string, mixed> $payload
145- */
146- private function convertToMessage (array $ payload ): MessageInterface
147- {
148- $ type = $ payload ['type ' ];
149- $ content = $ payload ['content ' ] ?? '' ;
150- $ contentAsBase64 = $ payload ['contentAsBase64 ' ] ?? [];
151-
152- $ message = match ($ type ) {
153- SystemMessage::class => new SystemMessage ($ content ),
154- AssistantMessage::class => new AssistantMessage ($ content , array_map (
155- static fn (array $ toolsCall ): ToolCall => new ToolCall (
156- $ toolsCall ['id ' ],
157- $ toolsCall ['function ' ]['name ' ],
158- json_decode ($ toolsCall ['function ' ]['arguments ' ], true )
159- ),
160- $ payload ['toolsCalls ' ],
161- )),
162- UserMessage::class => new UserMessage (...array_map (
163- static fn (array $ contentAsBase64 ): ContentInterface => \in_array ($ contentAsBase64 ['type ' ], [File::class, Image::class, Audio::class], true )
164- ? $ contentAsBase64 ['type ' ]::fromDataUrl ($ contentAsBase64 ['content ' ])
165- : new $ contentAsBase64 ['type ' ]($ contentAsBase64 ['content ' ]),
166- $ contentAsBase64 ,
167- )),
168- ToolCallMessage::class => new ToolCallMessage (
169- new ToolCall (
170- $ payload ['toolsCalls ' ]['id ' ],
171- $ payload ['toolsCalls ' ]['function ' ]['name ' ],
172- json_decode ($ payload ['toolsCalls ' ]['function ' ]['arguments ' ], true )
173- ),
174- $ content
175- ),
176- default => throw new LogicException (\sprintf ('Unknown message type "%s". ' , $ type )),
177- };
178-
179- $ message ->getMetadata ()->set ($ payload ['metadata ' ]);
180-
181- return $ message ;
182- }
18396}
0 commit comments