Files
qiming/qiming-rcoder/.qoder/repowiki/zh/content/API端点参考/代理进度流接口.md
2026-06-01 13:54:52 +08:00

305 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 代理进度流接口
<cite>
**本文引用的文件**
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [crates/rcoder/src/handler/chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs)
- [crates/shared_types/src/grpc/agent.rs](file://crates/shared_types/src/grpc/agent.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向 RCoder 项目的“代理进度流”接口,聚焦于 GET /agent/progress/{session_id} 的 Server-Sent EventsSSE实现。该接口提供实时的 AI 任务执行进度更新,涵盖代码生成、文件操作等事件类型;同时说明 SSE 文本流格式、事件类型分类、客户端重连机制,以及 session_id 的生成与有效期管理策略,并给出 JavaScript 客户端示例的对接思路与最佳实践。
## 项目结构
- 该接口在两个服务中均有实现:
- agent_runner直接消费内部会话缓存推送统一的 UnifiedSessionMessage。
- rcoder作为代理层将外部容器的 SSE 流透传给客户端。
- 路由注册位于 agent_runner 的路由文件中,暴露 /agent/progress/{session_id}。
```mermaid
graph TB
subgraph "Agent Runner 服务"
R["路由注册<br/>/agent/progress/{session_id}"]
H1["SSE处理器<br/>agent_session_notification"]
C["会话缓存<br/>SessionCache/SessionData"]
end
subgraph "Shared Types"
M["UnifiedSessionMessage<br/>统一消息模型"]
end
R --> H1
H1 --> C
C --> M
```
图表来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L52)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L16-L30)
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L52)
## 核心组件
- SSE 处理器:负责建立 SSE 连接、发送心跳、将消息事件化并推送。
- 会话缓存:维护每个 session_id 的消息通道与取消令牌,支持新连接覆盖旧连接。
- 统一消息模型:将不同类型的会话更新统一为 UnifiedSessionMessage便于前端解析。
- 代理层rcoder当需要透传外部容器的 SSE 时,将容器端 SSE 流透传至客户端。
章节来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L24-L103)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L16-L30)
## 架构总览
SSE 进度流的总体交互如下:
- 客户端发起 GET /agent/progress/{session_id} 建立 SSE 连接。
- 服务端根据 session_id 获取或创建会话数据,建立消息通道与取消令牌。
- 服务端立即发送一次心跳事件,随后周期性发送心跳,并将收到的统一消息转换为 SSE 事件推送。
- 若连接被取消(如新连接建立或用户取消),旧连接会自然断开。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Handler as "SSE处理器"
participant Cache as "会话缓存"
participant Worker as "会话工作线程"
participant Model as "统一消息模型"
Client->>Handler : "GET /agent/progress/{session_id}"
Handler->>Cache : "创建/获取 SessionData 并建立新连接"
Handler->>Client : "发送初始心跳事件"
Worker-->>Handler : "推送 UnifiedSessionMessage"
Handler->>Client : "按事件类型发送事件如 prompt_start/prompt_end/tool_call 等"
Handler->>Client : "周期性发送心跳事件"
Handler-->>Client : "连接被取消/断开时终止推送"
```
图表来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L67-L103)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L16-L30)
## 详细组件分析
### SSE 文本流格式与事件类型
- 文本流遵循标准 SSE 格式,每条消息包含事件类型与数据两部分。
- 事件类型与 UnifiedSessionMessage 的映射关系:
- prompt_start会话开始
- prompt_end会话结束含结束原因
- agent_message_chunkAgent 文本响应片段
- agent_thought_chunkAgent 思考过程片段
- tool_call工具调用通知
- tool_call_update工具调用状态更新
- available_commands_update可用命令更新
- current_mode_update当前模式更新
- heartbeat心跳消息
- 数据体为 JSON结构遵循 UnifiedSessionMessage包含 session_id、message_type、sub_type、data、timestamp。
章节来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L165-L246)
### SSE 处理器agent_runner
- 建立新连接:为每个 session_id 创建新的 SessionData 并插入缓存,确保每次连接全新开始。
- 发送心跳:首次立即发送一次心跳事件,随后以固定间隔(如 30 秒)发送心跳。
- 事件分发:将收到的 UnifiedSessionMessage 按 message_type 与 sub_type 转换为对应的事件名并推送。
- 取消与断开:监听取消令牌与通道关闭,及时退出循环并记录日志。
```mermaid
flowchart TD
Start(["建立连接"]) --> NewSession["创建/获取 SessionData 并建立新连接"]
NewSession --> SendHB["发送初始心跳事件"]
SendHB --> Loop{"循环接收消息"}
Loop --> |收到消息| MapEvent["按消息类型映射事件名"]
MapEvent --> Yield["yield SSE 事件"]
Yield --> Loop
Loop --> |取消令牌触发| Close["断开连接"]
Loop --> |通道关闭| Close
Close --> End(["结束"])
```
图表来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
章节来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
### 会话缓存与连接管理
- SessionData持有命令通道、当前发送器与取消令牌支持创建新连接并设置当前发送器与取消令牌。
- SessionWorker维护环形缓冲区按需缓冲非心跳消息并将消息实时推送到当前发送器。
- 项目-会话映射ensure_project_session 确保同一项目仅对应一个活跃会话,必要时清理旧会话数据。
- 主动关闭close_current_connection 主动触发取消令牌并丢弃发送器,促使接收端感知断开。
```mermaid
classDiagram
class SessionData {
+new(max_size)
+create_new_connection(buffer_size)
+push_message(message)
+close_current_connection()
}
class SessionWorker {
+spawn(max_size, command_rx, current_sender, current_cancel)
+run()
}
class UnifiedSessionMessage {
+session_id
+message_type
+sub_type
+data
+timestamp
}
SessionData --> SessionWorker : "spawn"
SessionWorker --> UnifiedSessionMessage : "推送"
```
图表来源
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L24-L103)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L16-L30)
章节来源
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L24-L103)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L140-L222)
### 代理层 SSE 透传rcoder
- 当需要代理外部容器的 SSE 时rcoder 会根据 session_id 查找对应容器,建立到容器 SSE 端点的连接,并将容器的 SSE 流透传给客户端。
- 透传逻辑按双换行符切分事件,解析 event/data 字段,避免重复 data: 前缀,然后直接透传事件。
- 错误处理:容器连接失败或读取失败时,发送 error 事件并记录日志。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Proxy as "rcoder SSE代理"
participant Container as "容器SSE端点"
Client->>Proxy : "GET /agent/progress/{session_id}"
Proxy->>Container : "建立到容器SSE的连接"
Container-->>Proxy : "SSE事件流按双换行符分隔"
Proxy->>Proxy : "解析event/data并去重"
Proxy-->>Client : "透传SSE事件"
Proxy-->>Client : "错误时发送error事件"
```
图表来源
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L106-L299)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L207-L299)
章节来源
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L106-L299)
### session_id 的生成与有效期管理
- 生成机制:在聊天处理流程中,当创建项目会话状态时,会为项目设置 session_id并更新最后活动时间。项目-会话映射通过 ensure_project_session 保证唯一性。
- 有效期管理:服务端未对 session_id 设置硬性过期时间;连接断开或取消会触发清理。若需要过期控制,可在业务侧增加会话超时策略(例如定期清理长时间无活动的会话)。
- 会话切换:当同一项目的新会话建立时,旧会话数据会被清理,确保不会跨会话污染。
章节来源
- [crates/rcoder/src/handler/chat_handler.rs](file://crates/rcoder/src/handler/chat_handler.rs#L272-L302)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L80-L95)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L282-L354)
### 客户端重连机制与最佳实践
- 心跳检测:服务端会周期性发送 heartbeat 事件,前端应基于心跳判断连接是否仍活跃。
- 自动重连:建议实现指数退避的自动重连策略,避免频繁重试造成压力。
- 事件处理根据事件类型prompt_start/prompt_end/tool_call 等)更新 UI 状态,避免阻塞主线程。
- 错误处理:监听连接错误与 SessionPromptEnd 中的错误信息,向用户反馈并引导重试或取消。
章节来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
### 与 gRPC 订阅接口的关系
- 项目中提供了基于 gRPC 的订阅进度流接口subscribe_progress可替代传统的 /agent/progress/{session_id} SSE 接口。
- 若采用 gRPC 方案,前端需使用 gRPC 客户端订阅进度流,事件类型与数据结构保持一致。
章节来源
- [crates/shared_types/src/grpc/agent.rs](file://crates/shared_types/src/grpc/agent.rs#L232-L236)
## 依赖分析
- 路由依赖:/agent/progress/{session_id} 在 agent_runner 的路由中注册。
- 处理器依赖SSE 处理器依赖会话缓存与统一消息模型。
- 代理层依赖rcoder 的代理处理器依赖容器映射与 SSE 透传逻辑。
- 项目-会话映射:通过 ensure_project_session 保证同一项目仅有一个活跃会话。
```mermaid
graph LR
Router["路由"] --> SSEHandler["SSE处理器"]
SSEHandler --> SessionCache["会话缓存"]
SessionCache --> UnifiedMsg["统一消息模型"]
ProxyHandler["rcoder代理处理器"] --> ContainerSSE["容器SSE端点"]
```
图表来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L52)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L106-L299)
- [crates/shared_types/src/model/agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L16-L30)
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L52)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L106-L299)
## 性能考虑
- 心跳频率:默认 30 秒一次,可根据网络状况调整,避免过多心跳占用带宽。
- 缓冲策略SessionWorker 使用环形缓冲区,非心跳消息优先缓冲,心跳消息直通,减少延迟。
- 取消与断开:通过 CancellationToken 与通道关闭快速退出,避免资源泄漏。
- 透传效率rcoder 代理层按双换行符切分事件,避免重复解析,提高透传效率。
章节来源
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L395-L475)
- [crates/agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L173-L222)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L156-L262)
## 故障排查指南
- 404 未找到容器:当 session_id 对应的活跃容器不存在时,返回 404 并携带错误码。
- 建立 SSE 连接失败:容器 SSE 连接失败或读取失败时,发送 error 事件并记录错误。
- 连接被取消:当新连接建立或用户取消任务时,旧连接会主动断开。
- 心跳缺失:若长时间未收到 heartbeat应触发重连流程。
章节来源
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L106-L153)
- [crates/rcoder/src/handler/agent_session_notification.rs](file://crates/rcoder/src/handler/agent_session_notification.rs#L207-L259)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L400-L477)
## 结论
RCoder 的代理进度流接口通过 SSE 提供了稳定、低延迟的实时进度推送能力。其核心在于:
- 统一消息模型与事件类型映射,便于前端解析;
- 会话缓存与取消令牌机制,确保连接可控与资源回收;
- 代理层透传能力,满足多容器场景;
- 心跳与断开策略,保障连接健康与稳定性。
建议在前端实现自动重连与指数退避、基于事件类型的状态机更新,并结合业务侧的会话超时策略,构建健壮的实时进度体验。
## 附录
### API 定义与示例
- 端点GET /agent/progress/{session_id}
- 内容类型text/event-stream
- 响应SSE 事件流事件类型与数据体见“SSE 文本流格式与事件类型”。
章节来源
- [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L52)
- [crates/agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
### JavaScript 客户端对接要点(概念性说明)
- 使用浏览器内置 EventSource API 建立连接,监听不同事件类型并更新 UI。
- 实现自动重连:监听 error 与 close 事件,采用指数退避策略重连。
- 心跳检测:收到 heartbeat 事件后刷新心跳计时器,超时则触发重连。
- 错误处理:监听 error 事件与 SessionPromptEnd 中的错误信息,向用户反馈并引导操作。
[本节为概念性说明,不直接分析具体源码文件]