Skip to content

Commit 2dafbed

Browse files
OskarStarkclaude
andcommitted
feat\!: add unique ID (UID) to all messages
BREAKING CHANGE: MessageInterface now requires getUid() method - Added symfony/uid package dependency - Added UuidV7 uid property to all message classes (UserMessage, AssistantMessage, SystemMessage, ToolCallMessage) - UIDs are automatically generated upon message instantiation - Added comprehensive tests for UID functionality Closes #77 Closes #344 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent 3ebcc79 commit 2dafbed

File tree

10 files changed

+124
-1
lines changed

10 files changed

+124
-1
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"symfony/property-info": "^6.4 || ^7.1",
3434
"symfony/serializer": "^6.4 || ^7.1",
3535
"symfony/type-info": "^7.2.3",
36-
"symfony/uid": "^6.4 || ^7.1",
36+
"symfony/uid": "^7.3",
3737
"webmozart/assert": "^1.11"
3838
},
3939
"require-dev": {

src/Platform/Message/AssistantMessage.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,35 @@
55
namespace PhpLlm\LlmChain\Platform\Message;
66

77
use PhpLlm\LlmChain\Platform\Response\ToolCall;
8+
use Symfony\Component\Uid\UuidV7;
89

910
/**
1011
* @author Denis Zunke <[email protected]>
1112
*/
1213
final readonly class AssistantMessage implements MessageInterface
1314
{
15+
public UuidV7 $uid;
16+
1417
/**
1518
* @param ?ToolCall[] $toolCalls
1619
*/
1720
public function __construct(
1821
public ?string $content = null,
1922
public ?array $toolCalls = null,
2023
) {
24+
$this->uid = new UuidV7();
2125
}
2226

2327
public function getRole(): Role
2428
{
2529
return Role::Assistant;
2630
}
2731

32+
public function getUid(): UuidV7
33+
{
34+
return $this->uid;
35+
}
36+
2837
public function hasToolCalls(): bool
2938
{
3039
return null !== $this->toolCalls && 0 !== \count($this->toolCalls);

src/Platform/Message/MessageInterface.php

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

55
namespace PhpLlm\LlmChain\Platform\Message;
66

7+
use Symfony\Component\Uid\UuidV7;
8+
79
/**
810
* @author Denis Zunke <[email protected]>
911
*/
1012
interface MessageInterface
1113
{
1214
public function getRole(): Role;
15+
16+
public function getUid(): UuidV7;
1317
}

src/Platform/Message/SystemMessage.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,27 @@
44

55
namespace PhpLlm\LlmChain\Platform\Message;
66

7+
use Symfony\Component\Uid\UuidV7;
8+
79
/**
810
* @author Denis Zunke <[email protected]>
911
*/
1012
final readonly class SystemMessage implements MessageInterface
1113
{
14+
public UuidV7 $uid;
15+
1216
public function __construct(public string $content)
1317
{
18+
$this->uid = new UuidV7();
1419
}
1520

1621
public function getRole(): Role
1722
{
1823
return Role::System;
1924
}
25+
26+
public function getUid(): UuidV7
27+
{
28+
return $this->uid;
29+
}
2030
}

src/Platform/Message/ToolCallMessage.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
namespace PhpLlm\LlmChain\Platform\Message;
66

77
use PhpLlm\LlmChain\Platform\Response\ToolCall;
8+
use Symfony\Component\Uid\UuidV7;
89

910
/**
1011
* @author Denis Zunke <[email protected]>
1112
*/
1213
final readonly class ToolCallMessage implements MessageInterface
1314
{
15+
public UuidV7 $uid;
16+
1417
public function __construct(
1518
public ToolCall $toolCall,
1619
public string $content,
1720
) {
21+
$this->uid = new UuidV7();
1822
}
1923

2024
public function getRole(): Role
2125
{
2226
return Role::ToolCall;
2327
}
28+
29+
public function getUid(): UuidV7
30+
{
31+
return $this->uid;
32+
}
2433
}

src/Platform/Message/UserMessage.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
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\UuidV7;
1112

1213
/**
1314
* @author Denis Zunke <[email protected]>
@@ -19,17 +20,25 @@
1920
*/
2021
public array $content;
2122

23+
public UuidV7 $uid;
24+
2225
public function __construct(
2326
ContentInterface ...$content,
2427
) {
2528
$this->content = $content;
29+
$this->uid = new UuidV7();
2630
}
2731

2832
public function getRole(): Role
2933
{
3034
return Role::User;
3135
}
3236

37+
public function getUid(): UuidV7
38+
{
39+
return $this->uid;
40+
}
41+
3342
public function hasAudioContent(): bool
3443
{
3544
foreach ($this->content as $content) {

tests/Platform/Message/AssistantMessageTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPUnit\Framework\Attributes\Test;
1313
use PHPUnit\Framework\Attributes\UsesClass;
1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Uid\UuidV7;
1516

1617
#[CoversClass(AssistantMessage::class)]
1718
#[UsesClass(ToolCall::class)]
@@ -43,4 +44,23 @@ public function constructionWithoutContentIsPossible(): void
4344
self::assertSame([$toolCall], $message->toolCalls);
4445
self::assertTrue($message->hasToolCalls());
4546
}
47+
48+
#[Test]
49+
public function messageHasUid(): void
50+
{
51+
$message = new AssistantMessage('foo');
52+
53+
self::assertInstanceOf(UuidV7::class, $message->uid);
54+
self::assertInstanceOf(UuidV7::class, $message->getUid());
55+
self::assertSame($message->uid, $message->getUid());
56+
}
57+
58+
#[Test]
59+
public function differentMessagesHaveDifferentUids(): void
60+
{
61+
$message1 = new AssistantMessage('foo');
62+
$message2 = new AssistantMessage('bar');
63+
64+
self::assertNotEquals($message1->getUid()->toRfc4122(), $message2->getUid()->toRfc4122());
65+
}
4666
}

tests/Platform/Message/SystemMessageTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPUnit\Framework\Attributes\Small;
1111
use PHPUnit\Framework\Attributes\Test;
1212
use PHPUnit\Framework\TestCase;
13+
use Symfony\Component\Uid\UuidV7;
1314

1415
#[CoversClass(SystemMessage::class)]
1516
#[Small]
@@ -23,4 +24,23 @@ public function constructionIsPossible(): void
2324
self::assertSame(Role::System, $message->getRole());
2425
self::assertSame('foo', $message->content);
2526
}
27+
28+
#[Test]
29+
public function messageHasUid(): void
30+
{
31+
$message = new SystemMessage('foo');
32+
33+
self::assertInstanceOf(UuidV7::class, $message->uid);
34+
self::assertInstanceOf(UuidV7::class, $message->getUid());
35+
self::assertSame($message->uid, $message->getUid());
36+
}
37+
38+
#[Test]
39+
public function differentMessagesHaveDifferentUids(): void
40+
{
41+
$message1 = new SystemMessage('foo');
42+
$message2 = new SystemMessage('bar');
43+
44+
self::assertNotEquals($message1->getUid()->toRfc4122(), $message2->getUid()->toRfc4122());
45+
}
2646
}

tests/Platform/Message/ToolCallMessageTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use PHPUnit\Framework\Attributes\Test;
1212
use PHPUnit\Framework\Attributes\UsesClass;
1313
use PHPUnit\Framework\TestCase;
14+
use Symfony\Component\Uid\UuidV7;
1415

1516
#[CoversClass(ToolCallMessage::class)]
1617
#[UsesClass(ToolCall::class)]
@@ -26,4 +27,25 @@ public function constructionIsPossible(): void
2627
self::assertSame($toolCall, $obj->toolCall);
2728
self::assertSame('bar', $obj->content);
2829
}
30+
31+
#[Test]
32+
public function messageHasUid(): void
33+
{
34+
$toolCall = new ToolCall('foo', 'bar');
35+
$message = new ToolCallMessage($toolCall, 'bar');
36+
37+
self::assertInstanceOf(UuidV7::class, $message->uid);
38+
self::assertInstanceOf(UuidV7::class, $message->getUid());
39+
self::assertSame($message->uid, $message->getUid());
40+
}
41+
42+
#[Test]
43+
public function differentMessagesHaveDifferentUids(): void
44+
{
45+
$toolCall = new ToolCall('foo', 'bar');
46+
$message1 = new ToolCallMessage($toolCall, 'bar');
47+
$message2 = new ToolCallMessage($toolCall, 'baz');
48+
49+
self::assertNotEquals($message1->getUid()->toRfc4122(), $message2->getUid()->toRfc4122());
50+
}
2951
}

tests/Platform/Message/UserMessageTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use PHPUnit\Framework\Attributes\Test;
1515
use PHPUnit\Framework\Attributes\UsesClass;
1616
use PHPUnit\Framework\TestCase;
17+
use Symfony\Component\Uid\UuidV7;
1718

1819
#[CoversClass(UserMessage::class)]
1920
#[UsesClass(Text::class)]
@@ -73,4 +74,23 @@ public function hasImageContentWithImage(): void
7374

7475
self::assertTrue($message->hasImageContent());
7576
}
77+
78+
#[Test]
79+
public function messageHasUid(): void
80+
{
81+
$message = new UserMessage(new Text('foo'));
82+
83+
self::assertInstanceOf(UuidV7::class, $message->uid);
84+
self::assertInstanceOf(UuidV7::class, $message->getUid());
85+
self::assertSame($message->uid, $message->getUid());
86+
}
87+
88+
#[Test]
89+
public function differentMessagesHaveDifferentUids(): void
90+
{
91+
$message1 = new UserMessage(new Text('foo'));
92+
$message2 = new UserMessage(new Text('bar'));
93+
94+
self::assertNotEquals($message1->getUid()->toRfc4122(), $message2->getUid()->toRfc4122());
95+
}
7696
}

0 commit comments

Comments
 (0)