diff --git a/src/Model/Message/AssistantMessage.php b/src/Model/Message/AssistantMessage.php index aabca471..c8b76791 100644 --- a/src/Model/Message/AssistantMessage.php +++ b/src/Model/Message/AssistantMessage.php @@ -6,7 +6,7 @@ use PhpLlm\LlmChain\Model\Response\ToolCall; -final readonly class AssistantMessage implements MessageInterface +final readonly class AssistantMessage extends Message { /** * @param ?ToolCall[] $toolCalls @@ -14,12 +14,9 @@ public function __construct( public ?string $content = null, public ?array $toolCalls = null, + Metadata $metadata = new Metadata(), ) { - } - - public function getRole(): Role - { - return Role::Assistant; + parent::__construct(Role::Assistant, $metadata); } public function hasToolCalls(): bool diff --git a/src/Model/Message/Message.php b/src/Model/Message/Message.php index 33377947..49f1c1e1 100644 --- a/src/Model/Message/Message.php +++ b/src/Model/Message/Message.php @@ -7,12 +7,21 @@ use PhpLlm\LlmChain\Model\Message\Content\Content; use PhpLlm\LlmChain\Model\Message\Content\Text; use PhpLlm\LlmChain\Model\Response\ToolCall; +use Symfony\Component\Uid\Uuid; -final readonly class Message +/** + * Besides a base implementation this class is a factory for the specific message types. + * We sacrifice basic OOP principles in favor of developer experience. + */ +abstract readonly class Message implements MessageInterface { - // Disabled by default, just a bridge to the specific messages - private function __construct() - { + /** + * Only available for subclasses. + */ + protected function __construct( + private Role $role, + private Metadata $metadata = new Metadata(), + ) { } public static function forSystem(string $content): SystemMessage @@ -23,7 +32,7 @@ public static function forSystem(string $content): SystemMessage /** * @param ?ToolCall[] $toolCalls */ - public static function ofAssistant(?string $content = null, ?array $toolCalls = null): AssistantMessage + public static function ofAssistant(?string $content = null, ?array $toolCalls = null, Metadata $metadata = new Metadata()): AssistantMessage { return new AssistantMessage($content, $toolCalls); } @@ -42,4 +51,19 @@ public static function ofToolCall(ToolCall $toolCall, string $content): ToolCall { return new ToolCallMessage($toolCall, $content); } + + public function getRole(): Role + { + return $this->role; + } + + public function getId(): Uuid + { + return $this->id; + } + + public function getMetadata(): Metadata + { + return $this->metadata; + } } diff --git a/src/Model/Message/Metadata.php b/src/Model/Message/Metadata.php new file mode 100644 index 00000000..3419d66c --- /dev/null +++ b/src/Model/Message/Metadata.php @@ -0,0 +1,30 @@ + + */ +class Metadata extends \ArrayObject +{ + public function __construct( + array $array = [], + Uuid $id = new UuidV4(), + \DateTimeImmutable $createdAt = new \DateTimeImmutable(), + ) { + if (!isset($array['created_at'])) { + $array['created_at'] = $createdAt; + } + + if (!isset($array['id'])) { + $array['id'] = $id; + } + + parent::__construct($array); + } +} diff --git a/src/Model/Message/SystemMessage.php b/src/Model/Message/SystemMessage.php index b914c3bd..763922b8 100644 --- a/src/Model/Message/SystemMessage.php +++ b/src/Model/Message/SystemMessage.php @@ -4,15 +4,11 @@ namespace PhpLlm\LlmChain\Model\Message; -final readonly class SystemMessage implements MessageInterface +final readonly class SystemMessage extends Message { public function __construct(public string $content) { - } - - public function getRole(): Role - { - return Role::System; + parent::__construct(Role::System); } /** diff --git a/src/Model/Message/ToolCallMessage.php b/src/Model/Message/ToolCallMessage.php index 20a97679..19bed273 100644 --- a/src/Model/Message/ToolCallMessage.php +++ b/src/Model/Message/ToolCallMessage.php @@ -6,17 +6,13 @@ use PhpLlm\LlmChain\Model\Response\ToolCall; -final readonly class ToolCallMessage implements MessageInterface +final readonly class ToolCallMessage extends Message { public function __construct( public ToolCall $toolCall, public string $content, ) { - } - - public function getRole(): Role - { - return Role::ToolCall; + parent::__construct(Role::ToolCall); } /** diff --git a/src/Model/Message/UserMessage.php b/src/Model/Message/UserMessage.php index eea38bcf..38383fe6 100644 --- a/src/Model/Message/UserMessage.php +++ b/src/Model/Message/UserMessage.php @@ -8,7 +8,7 @@ use PhpLlm\LlmChain\Model\Message\Content\Image; use PhpLlm\LlmChain\Model\Message\Content\Text; -final readonly class UserMessage implements MessageInterface +final readonly class UserMessage extends Message { /** * @var list @@ -19,11 +19,8 @@ public function __construct( Content ...$content, ) { $this->content = $content; - } - public function getRole(): Role - { - return Role::User; + parent::__construct(Role::User); } public function hasImageContent(): bool