> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeus.agentspro.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# 流式传输

> Zeus SSE 流式传输 — 事件流、分块策略与前端消费

Zeus 使用 Server-Sent Events (SSE) 将 Agent 的推理过程和工具调用实时流式传输到前端。本页描述流式传输的完整链路、事件类型和分块行为。

***

## Streaming Pipeline

```mermaid theme={null}
graph LR
    subgraph Backend["后端"]
        LLM["LLM 推理"]
        Agent["DeepAgent"]
        FastAPI["FastAPI"]
    end

    subgraph Frontend["前端"]
        NextAPI["Next.js API"]
        StreamProcessor["StreamProcessor"]
        Stores["Zustand Stores"]
        UI["Chat UI"]
    end

    LLM -->|"token 流"| Agent
    Agent -->|"SSE Events"| FastAPI
    FastAPI -->|"SSE Stream"| NextAPI
    NextAPI -->|"SSE Stream"| StreamProcessor
    StreamProcessor -->|"状态更新"| Stores
    Stores -->|"渲染"| UI
```

流式传输采用端到端 SSE 透传：Python 后端生成事件 → Next.js API 代理转发 → 前端 StreamProcessor 消费。

***

## Event Types

### Core Events

| SSE 事件             | 触发时机            | 关键字段                                           |
| ------------------ | --------------- | ---------------------------------------------- |
| `text`             | LLM 每输出一个 token | `content`, `role`                              |
| `tool_call`        | LLM 决定调用工具      | `tool_name`, `parameters`, `requires_approval` |
| `tool_call_result` | 工具执行完成          | `tool_name`, `result`, `is_error`              |
| `complete`         | Agent 执行结束      | `content`, `summary`                           |
| `error`            | 发生异常            | `error`, `error_code`, `details`               |
| `token_usage`      | LLM 调用结束后       | `prompt_tokens`, `completion_tokens`           |

沙盒工具（`sandbox_exec_py`、`sandbox_exec_sh` 等）的执行结果通过标准的 `tool_call_result` 事件返回，不使用单独的事件类型。

***

## Event Mapping

DeepAgents 框架内部事件到 SSE 消息的映射关系：

```mermaid theme={null}
graph LR
    subgraph DeepAgentsEvents["DeepAgents 内部事件"]
        e1["on_chat_model_stream"]
        e2["on_chat_model_end"]
        e3["on_tool_end"]
        e4["on_interrupt"]
    end

    subgraph SSEMessages["SSE 消息"]
        m1["TextMessage"]
        m2["ToolCallMessage"]
        m3["ToolCallResultMessage"]
        m4["CompleteMessage"]
        m5["ErrorMessage"]
        m6["TokenUsageMessage"]
    end

    e1 -->|"token 流"| m1
    e2 -->|"tool_calls 检测"| m2
    e2 -->|"usage_metadata"| m6
    e3 -->|"工具结果"| m3
    e4 -->|"HITL 中断"| m2
```

### Tool Call ID Queue

为了正确匹配 `on_tool_end` 事件与对应的工具调用，运行时维护一个 FIFO 队列（按工具名分组存储 `tool_call_id`）。`on_chat_model_end` 时入队，`on_tool_end` 时出队匹配。

***

## Frontend StreamProcessor

前端 `handleStreamMessage()` 消费 SSE 流，将事件路由到对应的状态管理：

```mermaid theme={null}
flowchart TD
    fetch["fetch POST /api/agent/invoke"]
    reader["ReadableStream Reader"]
    parse["解析 SSE data 行"]

    subgraph Handlers["事件路由"]
        h_text["TextMessage → 追加 token"]
        h_tool["ToolCallMessage → 添加到 trajectory"]
        h_result["ToolCallResultMessage → 更新状态"]
        h_complete["CompleteMessage → 标记完成"]
        h_error["ErrorMessage → Toast 通知"]
    end

    subgraph Stores["状态更新"]
        chat["chatStore — 消息列表"]
        trajectory["trajectoryStore — 工具调用 + Todos"]
        approval["pendingApprovals — 待审批队列"]
    end

    fetch --> reader --> parse --> Handlers
    Handlers --> Stores
```

***

## Tool Call Streaming（流式工具调用）

工具调用支持两阶段流式传输：先通过 `tool_call_chunk` 流式展示参数，再通过 `tool_call` 发送完整参数。

### 前端期望的事件顺序

```
tool_call_chunk  (首个分块，创建流式预览卡片)
tool_call_chunk  (后续分块，追加参数文本)
tool_call_chunk  (继续追加...)
tool_call        (完整参数，替换流式卡片为最终版)
tool_call_result (工具执行结果)
```

| SSE 事件            | 触发时机         | 关键字段                                               |
| ----------------- | ------------ | -------------------------------------------------- |
| `tool_call_chunk` | LLM 流式输出工具参数 | `tool_call_id`, `tool_name`, `args_chunk`, `index` |
| `tool_call`       | 参数完整后        | `tool_name`, `parameters`（完整 dict）                 |

`stream-processor.ts` 收到 `tool_call_chunk` 时创建/更新流式预览卡片（带 `streamingArgs`），收到 `tool_call` 时将其替换为带完整 `parameters` 的最终卡片。

### ai-backend（LangChain）

LangChain 的事件天然匹配这个顺序：

```
on_chat_model_stream → tool_call_chunks → 发 tool_call_chunk（流式碎片）
on_chat_model_end    → tool_calls 完整 → 发 tool_call（完整参数）
```

`on_chat_model_end` 时 LLM 已经生成完了所有参数，`tc.get("args", {})` 直接拿到完整的 dict。

***

## Chunking & Batching

### 消息批处理

前端合并快速连续的文本更新，以约 **60fps** 的频率批量刷新 UI，避免过度渲染。

### 虚拟滚动

对长对话使用虚拟滚动，只渲染可视区域的消息卡片，提升滚动性能。

### 选择性状态持久化

只持久化必要的状态（如 `sessionId` 和 `messageIds`），完整消息内容从服务器按需加载。
