Files
zyt/server/app/adminapi/service/AssistantSseProtocol.php
T
2026-08-18 14:08:38 +08:00

50 lines
1.3 KiB
PHP

<?php
declare(strict_types=1);
namespace app\adminapi\service;
/**
* 诊单 AI 助手 SSE 事件状态机:start -> delta* -> done|error。
*/
final class AssistantSseProtocol
{
private int $seq = 0;
private bool $started = false;
private bool $terminal = false;
/** @param array<string,mixed> $payload */
public function encode(string $event, array $payload): ?string
{
if ($this->terminal || !in_array($event, ['start', 'delta', 'done', 'error'], true)) {
return null;
}
if ((!$this->started && $event !== 'start') || ($this->started && $event === 'start')) {
return null;
}
$nextSeq = $this->seq + 1;
$encoded = json_encode(
['seq' => $nextSeq] + $payload,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE
);
if (!is_string($encoded)) {
return null;
}
$this->seq = $nextSeq;
$this->started = true;
if (in_array($event, ['done', 'error'], true)) {
$this->terminal = true;
}
return 'event: ' . $event . "\n" . 'data: ' . $encoded . "\n\n";
}
public function isTerminal(): bool
{
return $this->terminal;
}
}