lellm_graph/stream_chunk.rs
1//! StreamChunk — Data Plane 数据面事件。
2//!
3//! 高频、数据透传、无嵌套包装。
4//! 与控制面 RuntimeEvent 分离,避免高频数据事件撑爆控制事件通道。
5//!
6//! 设计原则:只承载"需要实时展示给用户的内容",不混入状态变更等低频数据。
7//! StreamChunk 携带 Execution View(展示内容),不是 Message。
8//! State 保存完整 Message。两者永不互相引用。
9
10use std::time::Duration;
11
12// ─── ToolPhase ────────────────────────────────────────────────
13
14/// 工具执行生命周期阶段。
15///
16/// 与 LangGraph (`on_tool_start`/`on_tool_end`)、
17/// OpenAI Agents SDK (`tool_call_started`/`tool_call_finished`)、
18/// Claude Desktop (`tool_use`/`tool_result`) 一致。
19#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ToolPhase {
21 /// 工具已加入执行队列(尚未开始)
22 Queued,
23 /// 工具开始执行
24 Started,
25 /// 工具执行完成(成功或失败)
26 Finished,
27}
28
29// ─── StreamChunk ──────────────────────────────────────────────
30
31/// 数据面事件 — 高频、数据透传。
32///
33/// 统一流式协议,所有 Node(LLM、Tool、MCP、Workflow)共享。
34///
35/// **Tool 并发 emit 协议:**
36/// - Start 保证顺序 — 严格按照 ToolCall 顺序发射(A, B, C)
37/// - End 允许乱序 — 并发执行完成后按实际顺序发射(B, A, C),通过 call_id 关联
38#[derive(Debug, Clone)]
39pub enum StreamChunk {
40 /// 文本输出(LLM 生成的文本 token)
41 TextDelta(String),
42 /// 思考内容(LLM 的 reasoning/thinking block)
43 ThinkingDelta(String),
44 /// 工具生命周期事件(Queued / Started / Finished)
45 ToolLifecycle {
46 phase: ToolPhase,
47 call_id: String,
48 tool_name: String,
49 },
50 /// 工具执行结果(展示用,content 为 String,前端直接展示)
51 ///
52 /// 与 State Plane 的 `Message::ToolResult` 分离。
53 /// State 保存完整 Message(含 content_blocks, metadata, raw_response)。
54 /// 此变体仅用于实时展示。
55 ToolOutput {
56 call_id: String,
57 tool_name: String,
58 content: String,
59 is_error: bool,
60 duration: Duration,
61 },
62}