"""Agent Runtime Event 与 SSE 传输协议。

一次 Agent 运行可能持续数秒。后端通过事件告诉前端当前处于开始、
工具完成、UI 就绪、运行完成或失败中的哪一步。
"""

import json
from datetime import datetime
from typing import Any, Literal

from pydantic import BaseModel, ConfigDict, Field


class RuntimeEvent(BaseModel):
    """一条有顺序号、可持久化、可重放的运行事件。"""

    model_config = ConfigDict(extra="forbid")

    event: Literal[
        "run.started",
        "tool.completed",
        "ui.ready",
        "run.completed",
        "run.failed",
    ]
    run_id: str
    sequence: int = Field(ge=1)
    occurred_at: datetime
    data: dict[str, Any] = Field(default_factory=dict)

    def to_sse(self) -> str:
        """按照 SSE 文本协议序列化事件。

        每条事件以空行结尾，浏览器才能把它识别为一个完整消息。
        """

        payload = self.model_dump(mode="json")
        return (
            f"id: {self.run_id}:{self.sequence}\n"
            f"event: {self.event}\n"
            f"data: {json.dumps(payload, ensure_ascii=False, separators=(',', ':'))}\n\n"
        )
