Skip to content
This repository was archived by the owner on Jul 16, 2025. It is now read-only.

Commit bf72975

Browse files
authored
feat: use intersection type AbstractUid&TimeBasedUidInterface for flexible message IDs (#384)
## Summary This PR updates the message ID type from `TimeBasedUidInterface` to `AbstractUid&TimeBasedUidInterface` using PHP's intersection types. This change provides more flexibility while maintaining type safety. ## Solution Using the intersection type `AbstractUid&TimeBasedUidInterface` ensures that: - ✅ Both `toRfc4122()` (from AbstractUid) and `getDateTime()` (from TimeBasedUidInterface) are available - ✅ Implementations can use any time-based UID type (UUID v1/v6/v7 or ULID) - ✅ Type safety is maintained - ✅ All existing tests pass without modification ## Changes - Updated `MessageInterface::getId()` return type - Updated all message implementations (AssistantMessage, SystemMessage, UserMessage, ToolCallMessage) - Updated anonymous class in tests ## Benefits 1. **Flexibility**: Users can now implement messages with either UUID or ULID 2. **Type Safety**: The intersection type guarantees all necessary methods are available 3. **Future Proof**: Any new Symfony UID types that extend AbstractUid and implement TimeBasedUidInterface will work ## Breaking Changes None - this is backwards compatible since all existing UUID implementations already satisfy the new type constraint. ## Testing All existing tests pass. The implementation has been verified to work with both UUID and ULID.
1 parent fed405e commit bf72975

File tree

10 files changed

+71
-11
lines changed

10 files changed

+71
-11
lines changed

src/Platform/Message/AssistantMessage.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
namespace PhpLlm\LlmChain\Platform\Message;
66

77
use PhpLlm\LlmChain\Platform\Response\ToolCall;
8+
use Symfony\Component\Uid\AbstractUid;
9+
use Symfony\Component\Uid\TimeBasedUidInterface;
810
use Symfony\Component\Uid\Uuid;
911

1012
/**
1113
* @author Denis Zunke <[email protected]>
1214
*/
1315
final readonly class AssistantMessage implements MessageInterface
1416
{
15-
public Uuid $id;
17+
public AbstractUid&TimeBasedUidInterface $id;
1618

1719
/**
1820
* @param ?ToolCall[] $toolCalls
@@ -29,7 +31,7 @@ public function getRole(): Role
2931
return Role::Assistant;
3032
}
3133

32-
public function getId(): Uuid
34+
public function getId(): AbstractUid&TimeBasedUidInterface
3335
{
3436
return $this->id;
3537
}

src/Platform/Message/MessageInterface.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
namespace PhpLlm\LlmChain\Platform\Message;
66

7-
use Symfony\Component\Uid\Uuid;
7+
use Symfony\Component\Uid\AbstractUid;
8+
use Symfony\Component\Uid\TimeBasedUidInterface;
89

910
/**
1011
* @author Denis Zunke <[email protected]>
@@ -13,5 +14,5 @@ interface MessageInterface
1314
{
1415
public function getRole(): Role;
1516

16-
public function getId(): Uuid;
17+
public function getId(): AbstractUid&TimeBasedUidInterface;
1718
}

src/Platform/Message/SystemMessage.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44

55
namespace PhpLlm\LlmChain\Platform\Message;
66

7+
use Symfony\Component\Uid\AbstractUid;
8+
use Symfony\Component\Uid\TimeBasedUidInterface;
79
use Symfony\Component\Uid\Uuid;
810

911
/**
1012
* @author Denis Zunke <[email protected]>
1113
*/
1214
final readonly class SystemMessage implements MessageInterface
1315
{
14-
public Uuid $id;
16+
public AbstractUid&TimeBasedUidInterface $id;
1517

1618
public function __construct(public string $content)
1719
{
@@ -23,7 +25,7 @@ public function getRole(): Role
2325
return Role::System;
2426
}
2527

26-
public function getId(): Uuid
28+
public function getId(): AbstractUid&TimeBasedUidInterface
2729
{
2830
return $this->id;
2931
}

src/Platform/Message/ToolCallMessage.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55
namespace PhpLlm\LlmChain\Platform\Message;
66

77
use PhpLlm\LlmChain\Platform\Response\ToolCall;
8+
use Symfony\Component\Uid\AbstractUid;
9+
use Symfony\Component\Uid\TimeBasedUidInterface;
810
use Symfony\Component\Uid\Uuid;
911

1012
/**
1113
* @author Denis Zunke <[email protected]>
1214
*/
1315
final readonly class ToolCallMessage implements MessageInterface
1416
{
15-
public Uuid $id;
17+
public AbstractUid&TimeBasedUidInterface $id;
1618

1719
public function __construct(
1820
public ToolCall $toolCall,
@@ -26,7 +28,7 @@ public function getRole(): Role
2628
return Role::ToolCall;
2729
}
2830

29-
public function getId(): Uuid
31+
public function getId(): AbstractUid&TimeBasedUidInterface
3032
{
3133
return $this->id;
3234
}

src/Platform/Message/UserMessage.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use PhpLlm\LlmChain\Platform\Message\Content\ContentInterface;
99
use PhpLlm\LlmChain\Platform\Message\Content\Image;
1010
use PhpLlm\LlmChain\Platform\Message\Content\ImageUrl;
11+
use Symfony\Component\Uid\AbstractUid;
12+
use Symfony\Component\Uid\TimeBasedUidInterface;
1113
use Symfony\Component\Uid\Uuid;
1214

1315
/**
@@ -20,7 +22,7 @@
2022
*/
2123
public array $content;
2224

23-
public Uuid $id;
25+
public AbstractUid&TimeBasedUidInterface $id;
2426

2527
public function __construct(
2628
ContentInterface ...$content,
@@ -34,7 +36,7 @@ public function getRole(): Role
3436
return Role::User;
3537
}
3638

37-
public function getId(): Uuid
39+
public function getId(): AbstractUid&TimeBasedUidInterface
3840
{
3941
return $this->id;
4042
}

tests/Platform/ContractTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
use PHPUnit\Framework\Attributes\Test;
3636
use PHPUnit\Framework\Attributes\UsesClass;
3737
use PHPUnit\Framework\TestCase;
38+
use Symfony\Component\Uid\AbstractUid;
39+
use Symfony\Component\Uid\TimeBasedUidInterface;
3840
use Symfony\Component\Uid\Uuid;
3941

4042
#[Large]
@@ -201,7 +203,7 @@ public function getRole(): Role
201203
return Role::User;
202204
}
203205

204-
public function getId(): Uuid
206+
public function getId(): AbstractUid&TimeBasedUidInterface
205207
{
206208
return Uuid::v7();
207209
}

tests/Platform/Message/AssistantMessageTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
use PHPUnit\Framework\Attributes\Test;
1414
use PHPUnit\Framework\Attributes\UsesClass;
1515
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Uid\AbstractUid;
17+
use Symfony\Component\Uid\TimeBasedUidInterface;
1618
use Symfony\Component\Uid\UuidV7;
1719

1820
#[CoversClass(AssistantMessage::class)]
@@ -79,4 +81,14 @@ public function sameMessagesHaveDifferentUids(): void
7981
self::assertIsUuidV7($message1->getId()->toRfc4122());
8082
self::assertIsUuidV7($message2->getId()->toRfc4122());
8183
}
84+
85+
#[Test]
86+
public function messageIdImplementsRequiredInterfaces(): void
87+
{
88+
$message = new AssistantMessage('test');
89+
90+
self::assertInstanceOf(AbstractUid::class, $message->getId());
91+
self::assertInstanceOf(TimeBasedUidInterface::class, $message->getId());
92+
self::assertInstanceOf(UuidV7::class, $message->getId());
93+
}
8294
}

tests/Platform/Message/SystemMessageTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use PHPUnit\Framework\Attributes\Small;
1212
use PHPUnit\Framework\Attributes\Test;
1313
use PHPUnit\Framework\TestCase;
14+
use Symfony\Component\Uid\AbstractUid;
15+
use Symfony\Component\Uid\TimeBasedUidInterface;
1416
use Symfony\Component\Uid\UuidV7;
1517

1618
#[CoversClass(SystemMessage::class)]
@@ -59,4 +61,14 @@ public function sameMessagesHaveDifferentUids(): void
5961
self::assertIsUuidV7($message1->getId()->toRfc4122());
6062
self::assertIsUuidV7($message2->getId()->toRfc4122());
6163
}
64+
65+
#[Test]
66+
public function messageIdImplementsRequiredInterfaces(): void
67+
{
68+
$message = new SystemMessage('test');
69+
70+
self::assertInstanceOf(AbstractUid::class, $message->getId());
71+
self::assertInstanceOf(TimeBasedUidInterface::class, $message->getId());
72+
self::assertInstanceOf(UuidV7::class, $message->getId());
73+
}
6274
}

tests/Platform/Message/ToolCallMessageTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
use PHPUnit\Framework\Attributes\Test;
1313
use PHPUnit\Framework\Attributes\UsesClass;
1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Uid\AbstractUid;
16+
use Symfony\Component\Uid\TimeBasedUidInterface;
1517
use Symfony\Component\Uid\UuidV7;
1618

1719
#[CoversClass(ToolCallMessage::class)]
@@ -65,4 +67,15 @@ public function sameMessagesHaveDifferentUids(): void
6567
self::assertIsUuidV7($message1->getId()->toRfc4122());
6668
self::assertIsUuidV7($message2->getId()->toRfc4122());
6769
}
70+
71+
#[Test]
72+
public function messageIdImplementsRequiredInterfaces(): void
73+
{
74+
$toolCall = new ToolCall('foo', 'bar');
75+
$message = new ToolCallMessage($toolCall, 'test');
76+
77+
self::assertInstanceOf(AbstractUid::class, $message->getId());
78+
self::assertInstanceOf(TimeBasedUidInterface::class, $message->getId());
79+
self::assertInstanceOf(UuidV7::class, $message->getId());
80+
}
6881
}

tests/Platform/Message/UserMessageTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use PHPUnit\Framework\Attributes\Test;
1616
use PHPUnit\Framework\Attributes\UsesClass;
1717
use PHPUnit\Framework\TestCase;
18+
use Symfony\Component\Uid\AbstractUid;
19+
use Symfony\Component\Uid\TimeBasedUidInterface;
1820
use Symfony\Component\Uid\UuidV7;
1921

2022
#[CoversClass(UserMessage::class)]
@@ -109,4 +111,14 @@ public function sameMessagesHaveDifferentUids(): void
109111
self::assertIsUuidV7($message1->getId()->toRfc4122());
110112
self::assertIsUuidV7($message2->getId()->toRfc4122());
111113
}
114+
115+
#[Test]
116+
public function messageIdImplementsRequiredInterfaces(): void
117+
{
118+
$message = new UserMessage(new Text('test'));
119+
120+
self::assertInstanceOf(AbstractUid::class, $message->getId());
121+
self::assertInstanceOf(TimeBasedUidInterface::class, $message->getId());
122+
self::assertInstanceOf(UuidV7::class, $message->getId());
123+
}
112124
}

0 commit comments

Comments
 (0)