package model // StreamKind 枚举补全流式过程中产生的结构化事件种类。 // 它对应 OpenClaw 的 AssistantMessageEvent 片段 // (文本 / 思考 / tool_call)外加一个工具执行进度事件, // 因此前端可以把每个片段渲染到自己的界面元素(正文、折叠 // 思考块、工具卡片),而不是累积成一条不透明的 token // 流。 type StreamKind string const ( // StreamKindTextStart 打开正文文本片段。一次响应的单个文本 // 片段由 TextStart/TextEnd 包起来;增量填充其中。 StreamKindTextStart StreamKind = "text_start" // StreamKindTextDelta 是一个正文文本 token 片段。 StreamKindTextDelta StreamKind = "text_delta" // StreamKindTextEnd 关闭正文文本片段。 StreamKindTextEnd StreamKind = "text_end" // StreamKindThinkingStart 打开一个思维链片段(前端 // 折叠块)。保留:上报推理的适配器会发出它。 StreamKindThinkingStart StreamKind = "thinking_start" // StreamKindThinkingDelta 是一个推理 token 片段。 StreamKindThinkingDelta StreamKind = "thinking_delta" // StreamKindThinkingEnd 关闭一个推理片段。 StreamKindThinkingEnd StreamKind = "thinking_end" // StreamKindToolCallStart 打开一次工具调用的流式形态。 StreamKindToolCallStart StreamKind = "tool_call_start" // StreamKindToolCallDelta 是工具参数的一个片段(例如 // Anthropic tool_use 块增量式的 input_json)。 StreamKindToolCallDelta StreamKind = "tool_call_delta" // StreamKindToolCallEnd 关闭一个工具调用块。 StreamKindToolCallEnd StreamKind = "tool_call_end" // StreamKindToolExecutionStart 打开模型所请求工具的 // 执行(design/04 §1.1:进入执行)。它由工具循环 // 发出,而不是模型适配器;Phase 携带 running 标签。 StreamKindToolExecutionStart StreamKind = "tool_execution_start" // StreamKindToolExecutionUpdate 报告所请求工具运行期间的 // 中间进度或部分输出(design/04 §1.1)。每次执行允许 // 多帧;线格式映射已定义,等工具能上报执行中进度时 // 就会有生产者。 StreamKindToolExecutionUpdate StreamKind = "tool_execution_update" // StreamKindToolExecutionEnd 以终态阶段(done 或 error) // 关闭一次工具执行。它由工具循环在 Invoke // 返回后发出。 StreamKindToolExecutionEnd StreamKind = "tool_execution_end" // StreamKindTurnStart 在 loop 的运行边界打开一个助手回合 // (design/04 §1.1 turn.start)。它不携带负载:帧外壳的 // 会话/回合标识在客户端一侧把该回合包起来。 StreamKindTurnStart StreamKind = "turn_start" // StreamKindTurnEnd 在 loop 的运行边界关闭一个助手回合, // 无论运行如何收场(最终答复、护栏停止、被终止的工具 // 循环、轮次耗尽或错误)。 StreamKindTurnEnd StreamKind = "turn_end" ) // 工具执行 phase 标签(design/04 §1.1 细粒度 phase)。取值与 design/19 §1 // 的节点 status 枚举(running/done/error)一致:start/update 帧带 running, // end 帧带 done 或 error,前端与实时流程图据此驱动工具节点的状态。 const ( // ToolPhaseRunning 标记工具进入执行或仍在执行中。 ToolPhaseRunning = "running" // ToolPhaseDone 标记工具执行成功结束。 ToolPhaseDone = "done" // ToolPhaseError 标记工具执行失败结束。 ToolPhaseError = "error" ) // StreamEvent 是流式补全里的单个结构化事件。它取代 // 原先的纯文本增量,成为 Adapter.ChatStream 投递的单位, // 因此消费者能区分正文文本、工具调用(以及将来还有推理 // 片段),并按 Index/ID 跟踪各自。 type StreamEvent struct { // Kind 对事件分类(见 StreamKind)。 Kind StreamKind // Delta 携带增量负载:TextDelta 时为正文文本,ThinkingDelta // 时为推理文本,ToolCallDelta 时为 partial_argument 片段。 // 工具执行事件绝不把阶段或工具名塞进这里—— // 那些住在结构化的 Phase/Tool 字段里。 Delta string // Index 是事件所属内容块的零基索引(提供商上报时)。 // 前端用它关联一个片段的 // start/delta/end 事件。 Index int // ID 是某次工具调用的提供商块/索引标识(例如 Anthropic 的 // tool_use 块 id)。文本片段为空。工具执行事件复用它, // 好让客户端能把一次执行与它的 tool_call.* 帧关联起来。 ID string // Tool 是 tool_execution.* 事件上被调用工具的名字。 // 其它所有种类为空。 Tool string // Phase 是 tool_execution.* 事件上的细粒度执行标签 // (ToolPhase*):start/update 时为 running,end 时为 done 或 error。 // 其它所有种类为空。 Phase string // ResultSummary 是 tool_execution_end 事件上**已脱敏**的工具结果摘要, // 供客户端在工具卡上渲染「这次调用拿到了什么」。它的取值与客户端**回看** // 同一次调用所见的 `toolCalls[].resultSummary`(图节点 props.result_summary) // 同源同口径 —— 同一份放行表、同一份凭据形状清洗(loop.toolFrameResultSummary)。 // // 🔴 缺席语义:只有结果**真正拿到**时才非空;失败/取消/超时(Invoke 返回 // error)一律留空 ⇒ 下行帧让该键**整键缺席**,绝不用空串顶位、也绝不把 // 一次失败说成「拿到了结果」。其它所有种类为空。 ResultSummary string // StreamID 标识某一帧所属的那一次模型流(一次 ChatStream 调用)。 // loop 在流边界打上它,使同一条流式消息的每一帧 // 共享它,而多步回合后续的模型调用会拿到新 id; // 消费者据此把它与 TurnID 区分开——后者 // 在整个回合中保持不变。 StreamID string // SessionID 是该流式事件所属的会话。它由 loop 在回合 // 边界打上(loop.streamStep),那里读取 Run 启动时所用的 // 会话;模型适配器跑在 loop 之下、没有 // 会话概念,所以留零值。路由该事件的消费者(WS hub) // 读它来定位正确的会话。 SessionID string // TurnID 是事件所属的助手回合。与 SessionID 一样,它由 // loop 打上,那里读取调用方用 // loop.WithTurnID 附上的回合标识;未附回合 id 时为零,所以消费者必须 // 把这两个字段当作尽力而为的关联,而不是硬保证。 TurnID string }