# Agent SSE Events 本文档记录 Agent Runtime 产生的所有 Server-Sent Events (SSE) 事件,用于前端实时展示。 ## 事件流转架构 ``` pipeline.emit() ↓ AgentScopeEventPipeline.emit() ├─→ store.persist() → 持久化到数据库 └─→ bus.publish() → 发布到 Redis Stream ↓ 前端通过 GET /runs/{thread_id}/events 读取 ``` ## 事件统一格式 所有事件在 Redis 中传输时都包含以下字段: ```typescript { type: string, // 事件类型 threadId: string, // 会话 ID runId: string, // 运行 ID data: object // 事件数据 } ``` --- ## 1. Orchestrator 生命周期事件 ### run.started Agent 开始运行时触发。 ```typescript { type: "run.started", threadId: "xxx", runId: "yyy", data: {} } ``` ### run.finished Agent 成功完成时触发。 ```typescript { type: "run.finished", threadId: "xxx", runId: "yyy", data: {} } ``` ### run.error Agent 运行出错时触发。 ```typescript { type: "run.error", threadId: "xxx", runId: "yyy", data: { message: "runtime execution failed" } } ``` --- ## 2. Step 阶段事件 ### step.start 阶段开始时触发。 ```typescript { type: "step.start", threadId: "xxx", runId: "yyy", data: { stepName: "router" | "worker" } } ``` ### step.finish 阶段结束时触发。 ```typescript { type: "step.finish", threadId: "xxx", runId: "yyy", data: { stepName: "router" | "worker" } } ``` --- ## 3. Worker 运行时事件 ### 3.1 文本消息事件 #### text.start 文本消息开始时触发。 ```typescript { type: "text.start", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", role: "assistant", stage: "worker" } } ``` #### text.delta 文本内容增量更新时触发。 ```typescript { type: "text.delta", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", delta: "这是新增的文本内容", stage: "worker" } } ``` #### text.end 文本消息结束时触发,包含完整输出和使用统计。 ```typescript { type: "text.end", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", role: "assistant", stage: "worker", workerAgentOutput: { status: "success" | "partial_success" | "failed", answer: "主回复文本", key_points: ["要点1", "要点2"], result_type: "execution_report" | "clarification" | "error_report" | "unknown", suggested_actions: ["建议操作1"], error: null | { code: string, message: string }, ui_hints: { ... } | null // 仅在 ui_mode 非空时存在 }, model: "gpt-4o", inputTokens: 1000, outputTokens: 500, cost: 0.025, latencyMs: 1500 } } ``` **workerAgentOutput 详细结构:** ```typescript // WorkerAgentOutputLite { status: "success" | "partial_success" | "failed", answer: string, key_points: string[], result_type: "execution_report" | "clarification" | "error_report" | "unknown", suggested_actions: string[], error: { code: string, message: string } | null } // WorkerAgentOutputRich (当 ui.ui_mode 非空时) { // ... WorkerAgentOutputLite 字段 ui_hints: { ui_mode: string, ui_state: object, actions: UiHintAction[] } } ``` --- ### 3.2 工具调用事件 #### tool.start 工具调用开始时触发。 ```typescript { type: "tool.start", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", toolCallId: "call-abc", toolName: "calendar_read", stage: "worker" } } ``` #### tool.args 工具调用参数时触发。 ```typescript { type: "tool.args", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", toolCallId: "call-abc", toolName: "calendar_read", args: { start_date: "2024-01-01", end_date: "2024-01-07" }, stage: "worker" } } ``` #### tool.end 工具调用结束时触发。 ```typescript { type: "tool.end", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", toolCallId: "call-abc", toolName: "calendar_read", stage: "worker" } } ``` #### tool.result 工具执行结果时触发。 ```typescript { type: "tool.result", threadId: "xxx", runId: "yyy", data: { messageId: "msg-xxx", toolCallId: "call-abc", toolName: "calendar_read", stage: "worker", toolAgentOutput: { tool_name: "calendar_read", tool_call_id: "call-abc", tool_call_args: { start_date: "2024-01-01", end_date: "2024-01-07" }, status: "success" | "failed", result_summary: "找到3个事件...", ui_hints: null, attachments: null } } } ``` **toolAgentOutput 详细结构:** ```typescript { tool_name: string, tool_call_id: string, tool_call_args: object | null, status: "success" | "failed", result_summary: string, ui_hints: object | null, attachments: Array<{ bucket: string, path: string, mime_type: string, url: string }> | null } ``` --- ## 使用统计字段 `text.end` 事件中包含使用统计: | 字段 | 类型 | 说明 | |------|------|------| | `model` | string | 使用的模型名称 | | `inputTokens` | number | 输入 token 数量 | | `outputTokens` | number | 输出 token 数量 | | `cost` | number | 花费(美元) | | `latencyMs` | number | 延迟(毫秒) | --- ## 前端接收示例 ```javascript const eventSource = new EventSource(`/runs/${threadId}/events`); eventSource.addEventListener('run.started', (e) => { console.log('Agent started:', JSON.parse(e.data)); }); eventSource.addEventListener('step.start', (e) => { console.log('Step started:', JSON.parse(e.data)); }); eventSource.addEventListener('text.delta', (e) => { const data = JSON.parse(e.data); console.log('Text delta:', data.data.delta); }); eventSource.addEventListener('tool.start', (e) => { const data = JSON.parse(e.data); console.log('Tool called:', data.data.toolName); }); eventSource.addEventListener('tool.result', (e) => { const data = JSON.parse(e.data); console.log('Tool result:', data.data.toolAgentOutput); }); eventSource.addEventListener('text.end', (e) => { const data = JSON.parse(e.data); console.log('Worker output:', data.data.workerAgentOutput); console.log('Usage:', { inputTokens: data.data.inputTokens, outputTokens: data.data.outputTokens, cost: data.data.cost }); }); eventSource.addEventListener('run.finished', (e) => { console.log('Agent finished:', JSON.parse(e.data)); }); eventSource.addEventListener('run.error', (e) => { console.log('Agent error:', JSON.parse(e.data)); }); ```