2026-07-02 03:22:12 +08:00
|
|
|
|
"""流式事件 DTO。
|
|
|
|
|
|
|
|
|
|
|
|
定义 ``AgentRunPort.streamAgentRun`` 返回的流式事件类型,替代原
|
|
|
|
|
|
``AsyncIterator[Any]`` 的弱类型签名(CON-019)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
from yuxi.channels.contract.errors import ValidationError
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class StreamEvent:
|
|
|
|
|
|
"""Agent 运行流式事件。
|
|
|
|
|
|
|
|
|
|
|
|
封装从 Redis Stream 读取的事件,供下游 SSE 渲染或事件重放使用。
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
字段:
|
2026-07-02 03:22:12 +08:00
|
|
|
|
event_type: 事件类型(如 ``messages`` / ``tool_call``)。
|
|
|
|
|
|
payload: 事件负载字典,结构由事件类型决定。
|
|
|
|
|
|
seq: Redis Stream 消息 ID,用于分页与去重。
|
|
|
|
|
|
|
|
|
|
|
|
关联约束:CON-019(端口返回类型不得使用 ``Any``)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
event_type: str
|
|
|
|
|
|
payload: dict[str, Any]
|
|
|
|
|
|
seq: str
|
2026-07-03 19:18:13 +08:00
|
|
|
|
|
|
|
|
|
|
def __post_init__(self) -> None:
|
|
|
|
|
|
"""校验 event_type 与 seq 非空。
|
|
|
|
|
|
|
|
|
|
|
|
``event_type`` 与 ``seq`` 必须非空,在构造时即抛出 ``ValidationError``,
|
|
|
|
|
|
避免空事件类型或空序列号导致事件渲染与去重失效(INV-8 / CON-019)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
if not self.event_type:
|
|
|
|
|
|
raise ValidationError("event_type", "must not be empty")
|
|
|
|
|
|
if not self.seq:
|
|
|
|
|
|
raise ValidationError("seq", "must not be empty")
|