delta* -> done|error。 */ final class AssistantSseProtocol { private int $seq = 0; private bool $started = false; private bool $terminal = false; /** @param array $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; } }