139 lines
3.4 KiB
PHP
139 lines
3.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Domain\Chat;
|
|
|
|
use DateTimeImmutable;
|
|
use DateTimeInterface;
|
|
|
|
final class Message
|
|
{
|
|
/**
|
|
* @param array<ToolCall>|null $toolCalls
|
|
*/
|
|
public function __construct(
|
|
private readonly string $role,
|
|
private readonly ?string $content,
|
|
private readonly ?array $toolCalls = null,
|
|
private readonly ?ToolResult $toolResult = null,
|
|
private readonly DateTimeInterface $createdAt = new DateTimeImmutable(),
|
|
) {
|
|
}
|
|
|
|
public function getRole(): string
|
|
{
|
|
return $this->role;
|
|
}
|
|
|
|
public function getContent(): ?string
|
|
{
|
|
return $this->content;
|
|
}
|
|
|
|
public function getTwig(): ?string
|
|
{
|
|
$content = $this->getContent() ?? '```twig\n{}\n```';
|
|
$matches = [];
|
|
if (preg_match('/```twig\s*([\s\S]*?)\s*```/m', $content, $matches) > 0) {
|
|
return $matches[1];
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>|null
|
|
*/
|
|
public function getJson(): ?array
|
|
{
|
|
$content = $this->getContent() ?? '```json\n{}\n```';
|
|
$matches = [];
|
|
if (preg_match('/```json\s*([\s\S]*?)\s*```/m', $content, $matches) > 0) {
|
|
$decoded = json_decode($matches[1], true);
|
|
return is_array($decoded) ? $decoded : null;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function getCreatedAt(): DateTimeInterface
|
|
{
|
|
return $this->createdAt;
|
|
}
|
|
|
|
/**
|
|
* @return array<ToolCall>
|
|
*/
|
|
public function getToolCalls(): array
|
|
{
|
|
return $this->toolCalls ?? [];
|
|
}
|
|
|
|
public function getToolResult(): ?ToolResult
|
|
{
|
|
if (isset($this->toolResult)) {
|
|
return $this->toolResult;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public function toArray(): array
|
|
{
|
|
$result = [
|
|
'role' => $this->role,
|
|
];
|
|
|
|
if ($this->content !== null) {
|
|
$result['content'] = $this->content;
|
|
}
|
|
|
|
if ($this->toolResult !== null) {
|
|
$result['tool_call_id'] = $this->toolResult->getToolCallId();
|
|
}
|
|
|
|
if ($this->toolCalls !== null && $this->toolCalls !== []) {
|
|
$result['tool_calls'] = array_map(
|
|
fn (ToolCall $toolCall) => [
|
|
'id' => $toolCall->getId(),
|
|
'type' => $toolCall->getType(),
|
|
'function' => [
|
|
'name' => $toolCall->getName(),
|
|
'arguments' => json_encode($toolCall->getArguments()),
|
|
],
|
|
],
|
|
$this->toolCalls
|
|
);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
public static function fromUser(string $content): self
|
|
{
|
|
return new self(role: 'user', content: $content);
|
|
}
|
|
|
|
public static function fromSystem(string $content): self
|
|
{
|
|
return new self(role: 'system', content: $content);
|
|
}
|
|
|
|
/**
|
|
* @param array<ToolCall>|null $toolCalls
|
|
*/
|
|
public static function fromAssistant(?string $content = null, ?array $toolCalls = null): self
|
|
{
|
|
return new self(role: 'assistant', content: $content, toolCalls: $toolCalls);
|
|
}
|
|
|
|
public static function fromToolResult(string $content, string $toolCallId, string $toolName): self
|
|
{
|
|
return new self(role: 'tool', content: $content, toolResult: new ToolResult($toolCallId, $toolName));
|
|
}
|
|
}
|