Files
AgentLab/backend/app/core/events.py
T
ThearchyHelios dcba9a63e0 一次思考在轨迹里只落一条事件
思考流上线时漏了把它登记进 ephemeral 集合,导致每个流式增量都
落库——一条思考链在执行轨迹里被拆成几十条 llm.thinking 事件。

拆成两种事件:llm.thinking.delta 是流式增量,只推给画布做实时
滚动、不落库(与 llm.token 同类);llm.thinking 是调用收尾时落的
单条汇总,携带完整思考内容(截断 6000 字符,完整版在节点输出
工件里)。顺带修好刷新回放:此前回放重现不了思考(增量被隐藏、
汇总不存在),现在一条汇总事件直接恢复全文,时间线上也可展开查看。

验证:确定性假思考模型过完整管道(3 条增量实时推、汇总恰一条且
内容完整);真模型跑模板⑤,轨迹 29 条降到 18 条,llm.thinking
恰好 1 条。adaptive thinking 对简单任务自主跳过思考时两类事件
都不产生,已从工件核实是模型行为而非管道丢失。
2026-09-14 10:40:20 +08:00

73 lines
2.1 KiB
Python

from __future__ import annotations
import time
import uuid
from enum import StrEnum
from typing import Any
from pydantic import BaseModel, Field
class EventType(StrEnum):
"""前端与后端之间的实时协议。画布高亮、时间线、token 流全部基于这套事件。"""
# run 级
RUN_STARTED = "run.started"
RUN_FINISHED = "run.finished"
RUN_FAILED = "run.failed"
RUN_CANCELLED = "run.cancelled"
RUN_INTERRUPTED = "run.interrupted" # 等待人工介入
RUN_RESUMED = "run.resumed"
# 节点级
NODE_STARTED = "node.started"
NODE_FINISHED = "node.finished"
NODE_FAILED = "node.failed"
NODE_SKIPPED = "node.skipped"
EDGE_TAKEN = "edge.taken" # 条件分支实际走了哪条边
# 模型级
LLM_START = "llm.start"
LLM_TOKEN = "llm.token"
# 思考的流式增量:只推给画布做实时显示,不落库
LLM_THINKING_DELTA = "llm.thinking.delta"
# 一次完整思考:调用结束时落一条,这才是进轨迹的事件
LLM_THINKING = "llm.thinking"
LLM_END = "llm.end"
# 工具 / 沙箱
TOOL_START = "tool.start"
TOOL_END = "tool.end"
TOOL_ERROR = "tool.error"
SANDBOX_START = "sandbox.start"
SANDBOX_END = "sandbox.end"
# 多 agent 协作中的单个 agent 步骤
AGENT_STEP_START = "agent.step.start"
AGENT_STEP_END = "agent.step.end"
# 人工介入
HUMAN_REQUESTED = "human.requested"
HUMAN_RESOLVED = "human.resolved"
# 出具与口径治理
ISSUANCE = "issuance" # 出具契约的判定结果(档位 / 缺数据 / 未回指数字)
CALIBER_UPGRADE = "caliber.upgrade" # 钉住的方法卡有新版本,按声明的策略处置
# 其他
LOG = "log"
USAGE = "usage" # token / 成本累计
class RunEventModel(BaseModel):
id: str = Field(default_factory=lambda: uuid.uuid4().hex)
run_id: str
seq: int = 0
type: EventType
node_id: str | None = None
ts: float = Field(default_factory=time.time)
data: dict[str, Any] = Field(default_factory=dict)
def to_wire(self) -> dict[str, Any]:
return self.model_dump(mode="json")