From 1ea656e79de98e735c4d38bd874defe3f113f107 Mon Sep 17 00:00:00 2001 From: Guillaume Loulier Date: Thu, 27 Nov 2025 11:01:11 +0100 Subject: [PATCH] refactor(core): improvements on Uuid handling && MessageNormalizer --- src/chat/src/MessageNormalizer.php | 8 +++++ src/chat/tests/MessageNormalizerTest.php | 4 ++- src/platform/src/Message/AssistantMessage.php | 12 ++----- .../src/Message/IdentifierAwareTrait.php | 33 +++++++++++++++++++ src/platform/src/Message/SystemMessage.php | 12 ++----- src/platform/src/Message/ToolCallMessage.php | 12 ++----- src/platform/src/Message/UserMessage.php | 12 ++----- 7 files changed, 52 insertions(+), 41 deletions(-) create mode 100644 src/platform/src/Message/IdentifierAwareTrait.php diff --git a/src/chat/src/MessageNormalizer.php b/src/chat/src/MessageNormalizer.php index e55eda9da..9de2c66f0 100644 --- a/src/chat/src/MessageNormalizer.php +++ b/src/chat/src/MessageNormalizer.php @@ -28,6 +28,9 @@ use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\TimeBasedUidInterface; +use Symfony\Component\Uid\Uuid; /** * @author Guillaume Loulier @@ -71,6 +74,11 @@ public function denormalize(mixed $data, string $type, ?string $format = null, a default => throw new LogicException(\sprintf('Unknown message type "%s".', $type)), }; + /** @var AbstractUid&TimeBasedUidInterface&Uuid $existingUuid */ + $existingUuid = Uuid::fromString($data['id']); + + $message->withId($existingUuid); + $message->getMetadata()->set([ ...$data['metadata'], 'addedAt' => $data['addedAt'], diff --git a/src/chat/tests/MessageNormalizerTest.php b/src/chat/tests/MessageNormalizerTest.php index a96a0192d..a7c15a03b 100644 --- a/src/chat/tests/MessageNormalizerTest.php +++ b/src/chat/tests/MessageNormalizerTest.php @@ -54,10 +54,11 @@ public function testItCanNormalize() public function testItCanDenormalize() { + $uuid = Uuid::v7()->toRfc4122(); $normalizer = new MessageNormalizer(); $message = $normalizer->denormalize([ - 'id' => Uuid::v7()->toRfc4122(), + 'id' => $uuid, 'type' => UserMessage::class, 'content' => '', 'contentAsBase64' => [ @@ -71,6 +72,7 @@ public function testItCanDenormalize() 'addedAt' => (new \DateTimeImmutable())->getTimestamp(), ], MessageInterface::class); + $this->assertSame($uuid, $message->getId()->toRfc4122()); $this->assertSame(Role::User, $message->getRole()); $this->assertArrayHasKey('addedAt', $message->getMetadata()->all()); } diff --git a/src/platform/src/Message/AssistantMessage.php b/src/platform/src/Message/AssistantMessage.php index 3bb7370b2..d27dd9e16 100644 --- a/src/platform/src/Message/AssistantMessage.php +++ b/src/platform/src/Message/AssistantMessage.php @@ -13,8 +13,6 @@ use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\AI\Platform\Result\ToolCall; -use Symfony\Component\Uid\AbstractUid; -use Symfony\Component\Uid\TimeBasedUidInterface; use Symfony\Component\Uid\Uuid; /** @@ -22,10 +20,9 @@ */ final class AssistantMessage implements MessageInterface { + use IdentifierAwareTrait; use MetadataAwareTrait; - private readonly AbstractUid&TimeBasedUidInterface $id; - /** * @param ?ToolCall[] $toolCalls */ @@ -33,7 +30,7 @@ public function __construct( private ?string $content = null, private ?array $toolCalls = null, ) { - $this->id = Uuid::v7(); + $this->withId(Uuid::v7()); } public function getRole(): Role @@ -41,11 +38,6 @@ public function getRole(): Role return Role::Assistant; } - public function getId(): AbstractUid&TimeBasedUidInterface - { - return $this->id; - } - public function hasToolCalls(): bool { return null !== $this->toolCalls && [] !== $this->toolCalls; diff --git a/src/platform/src/Message/IdentifierAwareTrait.php b/src/platform/src/Message/IdentifierAwareTrait.php new file mode 100644 index 000000000..6f0c1b3df --- /dev/null +++ b/src/platform/src/Message/IdentifierAwareTrait.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Platform\Message; + +use Symfony\Component\Uid\AbstractUid; +use Symfony\Component\Uid\TimeBasedUidInterface; + +/** + * @author Guillaume Loulier + */ +trait IdentifierAwareTrait +{ + private AbstractUid&TimeBasedUidInterface $id; + + public function withId(AbstractUid&TimeBasedUidInterface $id): void + { + $this->id = $id; + } + + public function getId(): AbstractUid&TimeBasedUidInterface + { + return $this->id; + } +} diff --git a/src/platform/src/Message/SystemMessage.php b/src/platform/src/Message/SystemMessage.php index d0650773a..550f1fd1f 100644 --- a/src/platform/src/Message/SystemMessage.php +++ b/src/platform/src/Message/SystemMessage.php @@ -12,8 +12,6 @@ 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; /** @@ -21,14 +19,13 @@ */ final class SystemMessage implements MessageInterface { + use IdentifierAwareTrait; use MetadataAwareTrait; - private readonly AbstractUid&TimeBasedUidInterface $id; - public function __construct( private readonly string $content, ) { - $this->id = Uuid::v7(); + $this->withId(Uuid::v7()); } public function getRole(): Role @@ -36,11 +33,6 @@ public function getRole(): Role return Role::System; } - 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 c664c6b7b..793112fdb 100644 --- a/src/platform/src/Message/ToolCallMessage.php +++ b/src/platform/src/Message/ToolCallMessage.php @@ -13,8 +13,6 @@ use Symfony\AI\Platform\Metadata\MetadataAwareTrait; use Symfony\AI\Platform\Result\ToolCall; -use Symfony\Component\Uid\AbstractUid; -use Symfony\Component\Uid\TimeBasedUidInterface; use Symfony\Component\Uid\Uuid; /** @@ -22,15 +20,14 @@ */ final class ToolCallMessage implements MessageInterface { + use IdentifierAwareTrait; use MetadataAwareTrait; - private readonly AbstractUid&TimeBasedUidInterface $id; - public function __construct( private readonly ToolCall $toolCall, private readonly string $content, ) { - $this->id = Uuid::v7(); + $this->withId(Uuid::v7()); } public function getRole(): Role @@ -38,11 +35,6 @@ public function getRole(): Role return Role::ToolCall; } - public function getId(): AbstractUid&TimeBasedUidInterface - { - return $this->id; - } - public function getToolCall(): ToolCall { return $this->toolCall; diff --git a/src/platform/src/Message/UserMessage.php b/src/platform/src/Message/UserMessage.php index 445af64c3..0f9cb9427 100644 --- a/src/platform/src/Message/UserMessage.php +++ b/src/platform/src/Message/UserMessage.php @@ -17,8 +17,6 @@ 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; /** @@ -26,6 +24,7 @@ */ final class UserMessage implements MessageInterface { + use IdentifierAwareTrait; use MetadataAwareTrait; /** @@ -33,13 +32,11 @@ final class UserMessage implements MessageInterface */ private readonly array $content; - private readonly AbstractUid&TimeBasedUidInterface $id; - public function __construct( ContentInterface ...$content, ) { $this->content = $content; - $this->id = Uuid::v7(); + $this->withId(Uuid::v7()); } public function getRole(): Role @@ -47,11 +44,6 @@ public function getRole(): Role return Role::User; } - public function getId(): AbstractUid&TimeBasedUidInterface - { - return $this->id; - } - /** * @return ContentInterface[] */