"""组织事件协议:组织 → 前端/PG 的统一推送格式。""" from __future__ import annotations import time from dataclasses import dataclass, field from typing import Any, Dict, List, Literal OrgEventType = Literal[ "log", # 普通文本日志 "step", # 阶段推进(agent 切换、工具调用前后) "artifact", # 生成了产物(沿用 send_file 的 url 协议) "approval_request", # 需要用户审批 "done", # 任务完成 "error", # 任务失败 ] @dataclass class OrgEvent: """组织事件:一个 task 的执行过程会产生一连串这种事件。 被 SSE 推给前端面板,被 DAO 追加到 ``org_task.events`` JSONB 字段。 序列化用 ``to_dict``,反序列化用 ``from_dict``。 """ task_id: str type: OrgEventType payload: Dict[str, Any] = field(default_factory=dict) ts: float = field(default_factory=time.time) def to_dict(self) -> Dict[str, Any]: return { "task_id": self.task_id, "type": self.type, "payload": self.payload, "ts": self.ts, } @classmethod def from_dict(cls, data: Dict[str, Any]) -> "OrgEvent": return cls( task_id=data["task_id"], type=data["type"], payload=data.get("payload", {}), ts=data.get("ts", time.time()), ) @dataclass class TaskState: """组织内存中的任务状态(重启不保留,但事件流通过 PG 持久化)。""" task_id: str org_name: str trace_id: str user_id: str status: Literal["pending", "running", "completed", "failed"] = "pending" description: str = "" source: Literal["cabinet", "user"] = "user" events: List[OrgEvent] = field(default_factory=list) result: Any = None error: str | None = None