geng
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user