添加qiming-rcoder模块

This commit is contained in:
Codex
2026-06-01 13:54:52 +08:00
parent 8092c4b1f8
commit 4b1a580132
539 changed files with 151650 additions and 0 deletions

View File

@@ -0,0 +1,345 @@
# ACP代理集成
<cite>
**本文档引用的文件**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [acp_adapter/src/types.rs](file://crates/acp_adapter/src/types.rs)
- [agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
- [agent_runner/src/proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
- [agent_runner/src/handler/chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
- [agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
- [agent_runner/src/handler/agent_cancel_handler.rs](file://crates/agent_runner/src/handler/agent_cancel_handler.rs)
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_runner/src/model.rs](file://crates/agent_runner/src/model.rs)
- [shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 简介
本文档详细阐述了ACP代理集成的技术实现重点说明acp_agent模块如何通过acp_adapter crate实现与ACP协议适配器的通信。文档涵盖了请求转发、状态同步、错误传播机制以及消息序列化/反序列化过程、连接管理策略和超时处理机制。同时,文档还解释了协议版本兼容性、异常处理和性能优化措施,并通过实际交互示例展示聊天请求的完整流程。
## 项目结构
项目采用模块化设计,主要分为以下几个核心模块:
- `acp_adapter`: 提供与ACP协议适配器通信的核心功能
- `agent_runner`: 负责代理服务的运行和管理
- `shared_types`: 共享的数据类型和模型定义
```mermaid
graph TD
subgraph "核心模块"
A[acp_adapter] --> |提供| B[agent_runner]
C[shared_types] --> |共享类型| A
C --> |共享类型| B
end
subgraph "代理类型"
B --> D[Claude Code Agent]
B --> E[Codex Agent]
end
subgraph "通信协议"
A --> F[ACP协议]
F --> G[子进程通信]
end
```
**图源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
**本节源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
## 核心组件
系统的核心组件包括ACP适配器、代理服务管理器和会话状态管理器。ACP适配器负责处理与代理的底层通信代理服务管理器负责启动和管理不同类型的代理服务会话状态管理器则负责维护会话的生命周期和状态同步。
**本节源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
## 架构概述
系统采用分层架构设计通过抽象层实现不同AI代理的统一接入。核心架构包括协议抽象层、代理管理层和会话管理层。
```mermaid
graph TD
A[客户端] --> B[HTTP API]
B --> C[代理管理层]
C --> D[协议抽象层]
D --> E[ACP适配器]
E --> F[具体代理]
F --> G[Claude Code]
F --> H[Codex]
style D fill:#f9f,stroke:#333,stroke-width:2px
style C fill:#bbf,stroke:#333,stroke-width:2px
```
**图源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
## 详细组件分析
### ACP适配器分析
ACP适配器模块提供了与ACP兼容的AI代理通信的核心功能包括连接管理、会话生命周期、消息处理和MCP集成。
#### 类图
```mermaid
classDiagram
class AcpAdapter {
+initialize()
+new_session()
+load_session()
+prompt()
+cancel()
}
class SessionState {
+Initializing
+Connected
+Prompting
+Paused
+Closed
+Error
}
class StreamUpdate {
+UserMessageChunk
+AgentMessageChunk
+AgentThoughtChunk
+ToolCall
+SessionStateChanged
+PromptStarted
+PromptCompleted
+Error
}
AcpAdapter --> SessionState : "使用"
AcpAdapter --> StreamUpdate : "生成"
```
**图源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [acp_adapter/src/types.rs](file://crates/acp_adapter/src/types.rs)
#### 请求处理流程
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Handler as "Chat Handler"
participant Agent as "ACP Agent"
participant Adapter as "ACP Adapter"
Client->>Handler : 发送聊天请求
Handler->>Agent : 创建代理服务
Agent->>Adapter : 初始化连接
Adapter->>Agent : 返回连接信息
Agent->>Adapter : 发送Prompt请求
Adapter->>Client : 流式返回响应
Client->>Handler : 接收响应
```
**图源**
- [agent_runner/src/handler/chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
- [agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
**本节源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [acp_adapter/src/types.rs](file://crates/acp_adapter/src/types.rs)
- [agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
### 代理服务管理分析
代理服务管理器负责启动和管理不同类型的代理服务通过统一的接口实现不同AI代理的接入。
#### 代理服务类图
```mermaid
classDiagram
class AcpAgentService {
<<trait>>
+start_agent_service()
+agent_type_name()
}
class ClaudeCodeAgent {
+start_claude_code_acp_agent_service()
}
class CodexAgent {
+start_codex_acp_agent_service()
}
AcpAgentService <|-- ClaudeCodeAgent
AcpAgentService <|-- CodexAgent
```
**图源**
- [agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
#### 代理启动流程
```mermaid
flowchart TD
Start([启动代理服务]) --> CheckExistence["检查代理是否存在"]
CheckExistence --> |存在| Reuse["复用现有代理"]
CheckExistence --> |不存在| Create["创建新代理"]
Create --> StartProcess["启动子进程"]
StartProcess --> Initialize["初始化ACP连接"]
Initialize --> CreateSession["创建会话"]
CreateSession --> SetupChannels["设置通信通道"]
SetupChannels --> Monitor["监控代理状态"]
Monitor --> End([代理服务启动完成])
```
**图源**
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
**本节源**
- [agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
### 会话状态管理分析
会话状态管理器负责维护会话的生命周期和状态同步,确保消息的正确传递和状态的一致性。
#### 会话缓存流程
```mermaid
flowchart TD
A[客户端建立SSE连接] --> B[创建SessionData]
B --> C[插入SESSION_CACHE]
C --> D[创建消息通道]
D --> E[监听消息队列]
E --> F[推送消息到客户端]
F --> G{连接是否活跃?}
G --> |是| E
G --> |否| H[清理资源]
```
**图源**
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
#### 消息处理流程
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Handler as "Handler"
participant Cache as "SessionCache"
participant Agent as "Agent"
Client->>Handler : 建立SSE连接
Handler->>Cache : 创建SessionData
Cache->>Handler : 返回消息通道
loop 消息处理
Agent->>Cache : 发送消息
Cache->>Handler : 推送消息
Handler->>Client : 发送SSE事件
end
Client->>Handler : 断开连接
Handler->>Cache : 清理资源
```
**图源**
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
- [agent_runner/src/proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
**本节源**
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_runner/src/handler/agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
- [agent_runner/src/proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
## 依赖分析
系统依赖关系清晰,各模块之间通过定义良好的接口进行通信,降低了耦合度。
```mermaid
graph TD
A[agent_runner] --> B[acp_adapter]
A --> C[shared_types]
B --> D[agent_client_protocol]
C --> E[protobuf]
style A fill:#f96,stroke:#333
style B fill:#6f9,stroke:#333
style C fill:#96f,stroke:#333
```
**图源**
- [Cargo.toml](file://Cargo.toml)
- [crates/agent_runner/Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [crates/acp_adapter/Cargo.toml](file://crates/acp_adapter/Cargo.toml)
**本节源**
- [Cargo.toml](file://Cargo.toml)
- [crates/agent_runner/Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [crates/acp_adapter/Cargo.toml](file://crates/acp_adapter/Cargo.toml)
## 性能考虑
系统在设计时充分考虑了性能优化,主要体现在以下几个方面:
1. **连接复用**: 通过PROJECT_AND_AGENT_INFO_MAP静态映射实现项目与代理服务的一对一复用避免频繁创建和销毁代理服务。
2. **异步处理**: 使用Tokio异步运行时通过LocalSet管理非Send的ACP连接确保高性能的异步I/O操作。
3. **通道优化**: 采用无界通道(unbounded_channel)进行消息传递,避免阻塞,同时通过环形缓冲区(HeapRb)管理消息队列,提高内存使用效率。
4. **锁优化**: 使用DashMap替代传统HashMap提供高性能的并发访问减少锁竞争。
5. **资源管理**: 通过CancellationToken实现优雅的资源清理确保代理服务在取消时能够正确释放资源。
**本节源**
- [agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [agent_runner/src/service/session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
## 故障排除指南
### 常见问题及解决方案
#### 代理启动失败
**症状**: 启动代理服务时返回"启动ACP Agent服务失败"错误。
**可能原因**:
1. 环境变量配置不正确
2. 代理可执行文件未找到
3. 项目目录权限问题
**解决方案**:
1. 检查相关环境变量(如ANTHROPIC_API_KEY)是否正确设置
2. 确认`claude-code-acp``codex-acp-agent`命令是否在PATH中
3. 检查项目目录的读写权限
#### 消息推送中断
**症状**: SSE连接建立后消息推送突然中断。
**可能原因**:
1. 代理服务异常退出
2. 网络连接问题
3. 超时设置过短
**解决方案**:
1. 检查代理服务的日志输出
2. 增加连接超时时间
3. 实现客户端重连机制
#### 并发请求被拒绝
**症状**: 连续发送多个请求时,后续请求返回"Agent正在执行任务"错误。
**原因**: 系统设计为每个项目ID对应一个代理服务禁止并发请求以避免状态混乱。
**解决方案**:
1. 等待当前任务完成后发送新请求
2. 为不同任务使用不同的项目ID
3. 实现请求队列机制
**本节源**
- [agent_runner/src/handler/chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
- [agent_runner/src/handler/agent_cancel_handler.rs](file://crates/agent_runner/src/handler/agent_cancel_handler.rs)
- [agent_runner/src/proxy_agent/claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
## 结论
ACP代理集成系统通过清晰的分层架构和模块化设计实现了与不同AI代理的统一接入。系统通过acp_adapter crate提供了协议抽象层使得上层应用可以无缝切换不同的代理实现。通过高效的连接管理、状态同步和错误处理机制系统确保了稳定可靠的通信。未来可以考虑增加更多类型的代理支持以及优化资源利用率和响应性能。

View File

@@ -0,0 +1,333 @@
# Claude Code代理实现
<cite>
**本文引用的文件**
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs)
- [util.rs](file://crates/claude-code-agent/src/util.rs)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向系统集成者与开发者全面阐述Claude Code代理在rcoder中的实现细节与使用方式。重点覆盖以下方面
- 如何封装Claude Code代理的特定行为子进程启动、ACPI/O协议交互、MCP服务器配置、会话管理等
- 初始化参数、运行时配置与自定义通信模式
- 与通用代理框架的集成方式AcpAgentService、AgentType、生命周期管理
- 特殊错误处理逻辑与异常传播机制
- 性能特征、资源消耗模式与与其他代理的差异点
- 配置示例与调用流程说明帮助在系统中启用与使用Claude Code代理
## 项目结构
Claude Code代理位于agent_runner的代理层围绕“子进程+ACPI/O协议”的模式实现配合通用代理框架与生命周期管理形成稳定的运行时闭环。
```mermaid
graph TB
subgraph "代理运行器"
AR["agent_runner<br/>代理运行与调度"]
ACP["ACPI/O客户端<br/>AcpAgentClient"]
SVC["AcpAgentService<br/>统一启动接口"]
CHU["通道工具<br/>channel_utils"]
LIFECYCLE["生命周期守卫<br/>AgentLifecycleGuard"]
end
subgraph "Claude Code库"
LIB["claude-code-agent<br/>lib.rs"]
UTIL["util.rs<br/>安装/命令/状态管理"]
end
subgraph "共享类型"
AT["AgentType<br/>代理类型"]
AM["Agent模型<br/>AgentStatus/ProjectAndAgentInfo"]
ERR["AppError<br/>应用错误"]
MCP["MCP配置<br/>create_default_mcp_servers"]
end
AR --> SVC
SVC --> |"Claude"| AR
AR --> |"启动子进程"| LIB
LIB --> UTIL
AR --> |"会话/通道"| CHU
AR --> |"生命周期管理"| LIFECYCLE
AR --> |"模型/环境变量"| AT
AR --> |"会话状态/错误"| AM
AR --> |"错误处理"| ERR
AR --> |"MCP服务器"| MCP
```
图表来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs#L1-L9)
章节来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs#L1-L9)
## 核心组件
- Claude Code代理启动器负责启动子进程、建立ACPI/O连接、创建会话、配置MCP服务器、管理通道与生命周期。
- 通用代理服务接口AcpAgentService为不同代理类型提供统一启动入口Claude分支委托给claude_code_agent.rs。
- 通道工具统一处理取消与Prompt请求的发送、超时保护、状态更新与错误上报。
- 生命周期管理AgentLifecycleGuard封装子进程、stderr任务与取消令牌支持优雅停止与强制清理。
- 模型/环境变量映射AgentType提供Claude所需的环境变量映射支持从配置覆盖与环境变量注入。
- MCP服务器配置默认启用context7与fetch等MCP服务器便于增强能力。
- Claude Code库提供安装、命令选择、状态检查与登录命令生成等辅助能力。
章节来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
## 架构总览
Claude Code代理采用“子进程+ACPI/O协议”的架构通过AgentType与AcpAgentService抽象实现与通用代理框架的无缝集成同时利用生命周期守卫与通道工具保障运行时稳定性与可观测性。
```mermaid
sequenceDiagram
participant Caller as "调用方"
participant AcpSvc as "AcpAgentService"
participant Runner as "Claude启动器"
participant Proc as "子进程(claude-code-acp)"
participant AcpCli as "ACPI/O客户端"
participant Utils as "通道工具"
participant Life as "生命周期守卫"
Caller->>AcpSvc : "start_agent_service(chat_prompt, model_provider)"
AcpSvc->>Runner : "start_claude_code_acp_agent_service(...)"
Runner->>Proc : "spawn子进程(工作目录/环境变量)"
Runner->>AcpCli : "ClientSideConnection.new(...)"
Runner->>AcpCli : "initialize(...)"
Runner->>AcpCli : "new_session/load_session(...)"
Runner->>Utils : "spawn_cancel_handler_for_agent(...)"
Runner->>Utils : "spawn_prompt_handler_for_agent(...)"
Runner->>Life : "new_claude(...)"
Runner-->>Caller : "返回AcpConnectionInfo(会话ID/通道/停止句柄)"
Note over Runner,AcpCli : "stderr读取任务独立运行"
```
图表来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
## 详细组件分析
### Claude Code代理启动器claude_code_agent.rs
- 启动子进程以claude-code-acp为命令合并模型提供商配置生成环境变量设置工作目录捕获stdin/stdout/stderr。
- ACPI/O连接使用ClientSideConnection建立双向通信LocalSet保证非Send任务在本地线程运行。
- 初始化与会话initialize后尝试load_session兼容未来SDK失败则回退new_session会话ID通过oneshot通道返回。
- MCP服务器通过create_default_mcp_servers创建context7与fetch等服务器注入会话请求。
- 通道与任务spawn_cancel_handler_for_agent与spawn_prompt_handler_for_agent分别处理取消与Promptstderr独立任务读取并记录。
- 生命周期new_claude创建AgentLifecycleGuard结合CancellationToken与子进程/stderr任务支持优雅停止与强制清理。
```mermaid
flowchart TD
Start(["启动Claude代理"]) --> Spawn["启动子进程<br/>合并环境变量/工作目录"]
Spawn --> IO["创建ACPI/O连接<br/>ClientSideConnection"]
IO --> Init["initialize()"]
Init --> Session{"load_session成功"}
Session --> |是| GotSession["使用已有会话ID"]
Session --> |否| NewSession["new_session()"]
GotSession --> Ready["会话就绪"]
NewSession --> Ready
Ready --> MCP["配置MCP服务器(context7/ fetch)"]
MCP --> Channels["启动取消/Prompt通道任务"]
Channels --> Stderr["启动stderr读取任务"]
Stderr --> Guard["创建生命周期守卫"]
Guard --> Done(["返回AcpConnectionInfo"])
```
图表来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
章节来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
### 通用代理服务接口agent_service.rs
- AcpAgentService为不同代理类型提供统一启动入口Claude分支委托给claude_code_agent.rs。
- AgentType::Claude实现agent_type_name返回“Claude”便于日志与监控识别。
章节来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
### 通道工具channel_utils.rs
- 取消处理超时保护默认10秒发送CancelNotification返回成功/失败响应并将Agent状态恢复为Idle。
- Prompt处理校验session_id一致性提取request_id写入会话上下文MAP发送SessionPromptStart成功发送SessionPromptEnd失败发送SessionPromptError与SessionPromptEnd。
- 状态管理通过PROJECT_AND_AGENT_INFO_MAP更新Agent状态与最后活动时间。
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
### 生命周期管理agent_model.rs
- AgentLifecycleGuard封装Claude资源子进程、stderr任务、取消令牌支持graceful_stop与force_cleanup。
- 提供cancel、is_stopped、cancellation_token、agent_type等统一接口实现AgentLifecycle trait。
- Drop时自动清理确保资源不泄漏。
章节来源
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
### 模型/环境变量映射agent_type.rs
- Claude环境变量映射从进程环境变量聚合ANTHROPIC_*键固定开启“跳过权限”参数支持从ModelProviderConfig覆盖。
- 从ModelProviderConfig推断Agent类型anthropic->Claude默认Claude。
章节来源
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
### MCP服务器配置mcp_config.rs
- 默认启用context7与fetch MCP服务器不使用API密钥提供基础能力。
- 提供创建默认MCP服务器列表的函数便于在会话创建时注入。
章节来源
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
### Claude Code库util.rs/lib.rs
- ClaudeCodeAcpManager安装/更新、状态检查、命令获取、登录命令生成、清理旧版本等。
- ClaudeCodeAcpConfig最小版本、包名、入口路径、二进制名、自定义命令、忽略系统版本等。
- lib.rs导出util模块提供安装与命令相关便捷函数。
章节来源
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs#L1-L9)
### 与通用代理框架的集成acp_agent.rs
- 通过AgentType::start_agent_service分派到Claude实现创建ProjectAndAgentInfo并插入全局映射。
- 若模型配置变化触发Agent重启否则复用现有Agent服务直接发送Prompt请求。
- 构建PromptRequest时将request_id放入meta便于通道工具提取与上下文关联。
章节来源
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
## 依赖关系分析
- Claude启动器依赖
- AgentType环境变量映射、代理类型
- AcpAgentClient/AcpConnectionInfoACPI/O连接信息
- create_default_mcp_serversMCP服务器
- channel_utils取消/Prompt通道
- AgentLifecycleGuard生命周期
- 通用代理服务:
- AcpAgentService为AgentType实现具体代理启动逻辑
- Claude Code库
- util.rs提供安装与命令管理能力lib.rs导出
```mermaid
graph LR
AT["AgentType"] --> SVC["AcpAgentService"]
SVC --> CC["Claude启动器"]
CC --> CHU["通道工具"]
CC --> LIFECYCLE["生命周期守卫"]
CC --> MCP["MCP配置"]
CC --> LIB["claude-code-agent(lib)"]
LIB --> UTIL["util.rs"]
```
图表来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs#L1-L9)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
章节来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [lib.rs](file://crates/claude-code-agent/src/lib.rs#L1-L9)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
## 性能考量
- 子进程与I/O
- 子进程stdin/stdout/stderr通过tokio::process与tokio-util compat封装避免阻塞。
- ACPI/O连接在LocalSet中运行避免跨线程Send限制。
- 通道与任务:
- 取消/Prompt通道均为无缓冲或有限缓冲避免内存膨胀stderr独立任务降低主循环压力。
- 取消超时保护默认10秒防止阻塞导致的资源占用。
- 会话与复用:
- 以project_id为维度复用Agent服务减少重复启动成本模型配置变更时触发重启避免状态污染。
- MCP服务器
- 默认启用context7/ fetch按需扩展避免不必要的依赖。
- 资源清理:
- 生命周期守卫支持优雅停止与强制清理,避免僵尸进程与资源泄漏。
[本节为通用性能讨论,不直接分析具体文件]
## 故障排查指南
- 启动失败:
- 子进程无法启动检查claude-code-acp命令是否存在、工作目录权限、环境变量是否正确注入。
- ACPI/O初始化失败查看initialize返回错误确认协议版本与客户端信息。
- 会话创建失败回退load_session失败时自动new_session若仍失败检查MCP服务器配置与网络访问。
- 运行时错误:
- 取消超时通道工具默认10秒超时适当调整或检查远端Agent处理能力。
- 通道发送失败:检查接收端是否关闭,或上游是否频繁重启。
- stderr异常stderr任务独立运行注意日志中警告与错误行。
- 生命周期问题:
- 优雅停止无效确认CancellationToken是否被正确取消子进程与stderr任务是否被清理。
- 资源泄漏检查Drop逻辑是否触发必要时强制清理。
章节来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
## 结论
Claude Code代理通过“子进程+ACPI/O协议”的稳定架构结合通用代理框架与生命周期管理提供了可复用、可观测、可扩展的代理实现。其特性包括
- 明确的初始化与会话管理流程
- 可配置的MCP服务器与环境变量映射
- 统一的取消/Prompt通道与状态管理
- 完备的生命周期与资源清理
- 与通用代理框架的无缝集成
[本节为总结性内容,不直接分析具体文件]
## 附录
### 配置示例与调用流程
- 启用Claude Code代理
- 在配置中将default_agent设为Claude或通过AgentType::Claude显式指定。
- 确保环境变量包含ANTHROPIC_*如ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL等或通过ModelProviderConfig注入。
- 启动时会自动尝试加载或安装claude-code-acp必要时可使用登录命令生成凭据。
- 调用流程:
- 调用AcpAgentService::start_agent_service(chat_prompt, model_provider)
- 返回AcpConnectionInfo包含session_id、prompt_tx、cancel_tx与stop_handle
- 通过prompt_tx发送PromptRequest通过cancel_tx发送CancelNotification
- 使用stop_handle进行优雅停止或强制清理
章节来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [util.rs](file://crates/claude-code-agent/src/util.rs#L1-L758)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md#L308-L375)

View File

@@ -0,0 +1,364 @@
# Codex代理实现
<cite>
**本文引用的文件**
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs)
- [crates/agent_runner/src/utils/mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs)
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
- [crates/shared_types/src/model/agent_type.rs](file://crates/shared_types/src/model/agent_type.rs)
- [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs)
- [crates/codex-acp-agent/src/lib.rs](file://crates/codex-acp-agent/src/lib.rs)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs)
- [README.md](file://README.md)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“Codex代理实现”的技术文档聚焦于rcoder工程中codex_agent模块的设计与实现阐述其与Codex ACP代理的交互方式、启动流程、命令执行与结果解析以及特定于Codex代理的配置选项、性能特征与限制条件。同时记录与通用代理运行时环境的集成细节以及与其他AI代理的兼容性处理并提供实际使用示例与最佳实践建议。
## 项目结构
- 代码组织采用多crate工作区核心运行时位于agent_runnerCodex ACP代理以独立二进制形式存在通过子进程方式启动并与主服务建立ACP连接。
- 关键模块:
- codex_agent负责启动Codex ACP子进程、建立ACP连接、会话管理、Prompt与取消处理。
- acp_agent通用代理服务调度与复用逻辑按项目维度管理Agent生命周期。
- channel_utils统一的Prompt与Cancel通道处理封装会话通知与状态更新。
- agent_serviceACP代理服务抽象与实现选择Codex/Claude
- agent_stop_handle生命周期守卫统一优雅停止与资源回收。
- mcp_config默认MCP服务器配置增强代理能力。
- shared_types跨crate共享的数据结构与生命周期接口。
- codex-acp-agentCodex ACP代理二进制入口与库导出。
```mermaid
graph TB
subgraph "运行时"
AR["agent_runner<br/>代理运行时"]
CFG["配置系统<br/>config.rs"]
ST["共享类型<br/>shared_types"]
end
subgraph "Codex ACP"
BIN["codex-acp-agent 二进制<br/>bin/codex-acp-agent.rs"]
LIB["codex-acp-agent 库<br/>lib.rs"]
end
subgraph "协议与工具"
ACP["Agent Client Protocol<br/>外部协议"]
MCP["MCP 服务器配置<br/>mcp_config.rs"]
end
AR --> BIN
AR --> ST
AR --> CFG
AR --> MCP
BIN --> ACP
LIB --> ACP
```
图表来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/agent_runner/src/utils/mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs#L1-L46)
- [crates/codex-acp-agent/src/lib.rs](file://crates/codex-acp-agent/src/lib.rs#L1-L18)
章节来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/agent_runner/src/utils/mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs#L1-L46)
- [crates/codex-acp-agent/src/lib.rs](file://crates/codex-acp-agent/src/lib.rs#L1-L18)
## 核心组件
- Codex ACP子进程启动与连接管理负责启动codex-acp-agent二进制、准备环境变量与CLI覆盖参数、建立ClientSideConnection、初始化ACP、创建/加载会话、管理stderr输出与生命周期。
- 代理服务调度与复用按项目维度缓存Agent信息支持模型配置变化时的重启复用现有Agent减少启动开销。
- 通道处理工具统一处理Prompt与Cancel请求发送会话开始/结束/错误通知更新Agent状态。
- 生命周期守卫统一管理子进程与stderr任务支持优雅停止与强制清理。
- MCP服务器配置默认启用context7与fetch等MCP服务器增强代理能力。
- 配置系统:命令行、环境变量、配置文件与默认配置的多层优先级。
章节来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L82-L126)
- [crates/agent_runner/src/utils/mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L1-L270)
## 架构总览
Codex代理通过子进程方式与主服务交互主服务负责
- 选择Agent类型Codex/Claude并调用相应启动函数。
- 为Codex准备模型提供商配置与环境变量构建CLI覆盖参数。
- 启动codex-acp-agent二进制建立ACP连接初始化会话。
- 通过通道将用户Prompt发送到代理接收结果并通过SSE通知前端。
- 管理生命周期,支持取消与优雅停止。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Runner as "代理运行时<br/>acp_agent.rs"
participant Codex as "Codex ACP 启动器<br/>codex_agent.rs"
participant Proc as "子进程<br/>codex-acp-agent"
participant Conn as "ACP 连接"
participant Chan as "通道处理<br/>channel_utils.rs"
Client->>Runner : "提交聊天请求"
Runner->>Codex : "start_codex_acp_agent_service(...)"
Codex->>Proc : "spawn 子进程并传入CLI覆盖参数"
Proc-->>Conn : "建立ClientSideConnection"
Codex->>Conn : "initialize / new_session"
Conn-->>Codex : "返回SessionId"
Runner->>Chan : "发送PromptRequest"
Chan->>Conn : "prompt(...)"
Conn-->>Chan : "返回结果/错误"
Chan-->>Runner : "推送Session通知"
Runner-->>Client : "SSE 实时进度/结果"
Client->>Runner : "取消请求"
Runner->>Chan : "发送Cancel通知"
Chan->>Conn : "cancel(...)"
Conn-->>Chan : "取消结果"
Chan-->>Runner : "推送Session结束"
```
图表来源
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs#L1-L46)
## 详细组件分析
### Codex ACP启动与会话管理
- 启动流程
- 依据ModelProviderConfig生成环境变量与CLI覆盖参数固定使用“custom”模型提供商名称确保与后续配置一致。
- 通过tokio::process::Command启动codex-acp-agent二进制设置stdin/stdout/stderr管道与工作目录。
- 建立ClientSideConnection并初始化ACP随后创建或加载会话返回会话ID与Prompt/Cancel通道。
- 启动stderr读取任务将子进程输出转发到日志。
- 创建生命周期守卫绑定项目ID、会话ID、子进程与取消令牌支持优雅停止。
- 命令执行与结果解析
- 通过通道将PromptRequest发送到代理代理执行后返回stop_reason等信息。
- 通道处理工具负责将开始、结束、错误等会话通知推送给前端。
- 取消与错误处理
- 通过CancelNotification在超时时间内调用代理cancel超时则返回超时响应。
- 后台任务失败时通过Prompt通道发送错误内容块触发错误通知与结束事件。
```mermaid
flowchart TD
Start(["启动Codex ACP子进程"]) --> Env["准备环境变量与CLI覆盖参数"]
Env --> Spawn["spawn 子进程"]
Spawn --> IO["建立ClientSideConnection"]
IO --> Init["initialize / new_session"]
Init --> Session["获得SessionId"]
Session --> Prompt["发送PromptRequest"]
Prompt --> Result{"执行结果"}
Result --> |成功| NotifyOK["推送SessionPromptEnd"]
Result --> |失败| NotifyErr["推送SessionPromptError<br/>再推送SessionPromptEnd"]
NotifyOK --> Stop["优雅停止/取消"]
NotifyErr --> Stop
Stop --> End(["结束"])
```
图表来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
章节来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
### 代理服务调度与复用
- 项目维度的Agent复用以DashMap存储ProjectAndAgentInfo按project_id映射到Agent服务避免重复启动。
- 模型配置变化检测当ModelProviderConfig变化时删除旧Agent并重建新Agent保证配置一致性。
- Prompt构建将系统提示词、用户输入与附件合并为ContentBlocks注入request_id到meta便于会话上下文追踪。
- 会话通知通过push_session_update_with_project推送SessionPromptStart/End/Error事件。
```mermaid
classDiagram
class AcpAgentService {
+start_agent_service(chat_prompt, model_provider) AcpConnectionInfo
+agent_type_name() str
}
class AgentType {
+from_model_provider(model_provider) AgentType
+codex_model_provider(model_provider) (ConfigToml, envs)
}
class AcpAgentWorker {
+agent_worker(request_rx)
+build_prompt_to_acp_agent(prompt, session_id) PromptRequest
}
class ProjectAndAgentInfo {
+project_id : string
+session_id : SessionId
+prompt_tx : mpsc
+cancel_tx : mpsc
+model_provider : Option<ModelProviderConfig>
+status : AgentStatus
+last_activity : DateTime
+created_at : DateTime
+stop_handle : Option<AgentLifecycle>
}
AcpAgentService <|.. AgentType : "实现"
AcpAgentWorker --> AcpAgentService : "调用"
AcpAgentWorker --> ProjectAndAgentInfo : "读写"
```
图表来源
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/shared_types/src/model/agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
章节来源
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [crates/shared_types/src/model/agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
### 生命周期与资源管理
- 生命周期守卫统一管理子进程与stderr任务支持graceful_stop、cancel、force_cleanup等操作。
- 资源类型CodexSubProcess与Claude类似均包含child_process与stderr_task。
- 取消令牌通过CancellationToken协调取消信号确保任务自然退出后再强制清理。
```mermaid
stateDiagram-v2
[*] --> 启动
启动 --> 运行中 : "子进程启动/会话创建"
运行中 --> 取消中 : "收到取消信号"
取消中 --> 停止中 : "超时/取消完成"
停止中 --> 已停止 : "优雅停止/强制清理"
已停止 --> [*]
```
图表来源
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L82-L126)
章节来源
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L82-L126)
### MCP服务器与能力增强
- 默认MCP服务器context7与fetch用于扩展代理能力如网络访问、前端模板等
- 配置生成create_default_mcp_servers返回MCP服务器列表可在会话创建时传入。
章节来源
- [crates/agent_runner/src/utils/mcp_config.rs](file://crates/agent_runner/src/utils/mcp_config.rs#L1-L225)
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L228-L246)
### 配置与兼容性
- 模型提供商配置ModelProviderConfig包含id/name/base_url/api_key/requires_openai_auth/default_model/api_protocol等字段。
- Agent类型映射AgentType::from_model_provider根据provider.name映射到Codex/Claude。
- 环境变量与CLI覆盖Codex通过codex_model_provider生成环境变量与CLI覆盖参数固定使用“custom”模型提供商名称。
- 兼容性AgentType实现AcpAgentService支持按AgentType选择启动函数README提供多代理配置示例。
章节来源
- [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L1-L132)
- [crates/shared_types/src/model/agent_type.rs](file://crates/shared_types/src/model/agent_type.rs#L1-L257)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [README.md](file://README.md#L107-L130)
## 依赖关系分析
- 运行时依赖
- agent_client_protocolACP协议类型与ClientSideConnection。
- tokio/tokio-util异步运行时与流适配。
- tracing/dashmap日志与并发Map。
- 外部二进制
- codex-acp-agent通过子进程方式运行支持-cli覆盖配置。
- 共享类型
- AgentType、ModelProviderConfig、AgentLifecycle等跨crate共享。
```mermaid
graph LR
codex_agent["codex_agent.rs"] --> acp_proto["agent_client_protocol"]
codex_agent --> tokio["tokio/tokio_util"]
codex_agent --> tracing_dash["tracing/dashmap"]
acp_agent["acp_agent.rs"] --> shared_types["shared_types"]
channel_utils["channel_utils.rs"] --> shared_types
agent_service["agent_service.rs"] --> shared_types
codex_bin["codex-acp-agent 二进制"] --> codex_lib["codex-acp-agent 库"]
codex_lib --> acp_proto
```
图表来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/codex-acp-agent/src/lib.rs](file://crates/codex-acp-agent/src/lib.rs#L1-L18)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs#L1-L46)
章节来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L1-L398)
- [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L1-L392)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/agent_runner/src/proxy_agent/agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [crates/codex-acp-agent/src/lib.rs](file://crates/codex-acp-agent/src/lib.rs#L1-L18)
- [crates/codex-acp-agent/src/bin/codex-acp-agent.rs](file://crates/codex-acp-agent/src/bin/codex-acp-agent.rs#L1-L46)
## 性能考量
- 启动开销
- 子进程启动与ACP初始化带来额外开销通过项目维度复用Agent可显著降低重复启动成本。
- 模型配置变化触发Agent重启应在配置稳定时减少频繁变更。
- I/O与通道
- Prompt与Cancel通过无阻塞通道传输避免阻塞主循环通道处理工具对取消调用设置超时防止阻塞。
- MCP服务器
- 默认启用context7与fetch等MCP服务器可能增加额外I/O与资源消耗可根据需求裁剪。
- 日志与stderr
- 后台stderr读取任务在取消时会退出避免长时间占用建议在生产环境合理设置日志级别。
[本节为通用性能讨论,不直接分析具体文件]
## 故障排查指南
- 启动失败
- 检查codex-acp-agent二进制是否可执行、CLI覆盖参数是否正确、环境变量是否包含API密钥。
- 查看stderr任务输出定位初始化失败原因如base_url/api_key/model_provider配置错误
- 取消超时
- 通道处理工具对cancel调用设置了超时保护超时会返回超时响应适当调整代理侧处理能力或网络状况。
- 会话不一致
- 通道处理工具会在收到Prompt时强制覆盖session_id为当前会话确保一致性若出现异常检查会话ID传递与Meta字段。
- 生命周期清理
- 优雅停止会先发送取消信号再强制清理子进程与stderr任务若出现僵尸进程检查取消令牌与Drop逻辑。
章节来源
- [crates/agent_runner/src/proxy_agent/codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L313-L335)
- [crates/agent_runner/src/proxy_agent/channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
## 结论
Codex代理通过子进程与ACP协议实现与主服务的解耦集成具备良好的可配置性与可扩展性。通过项目维度的Agent复用、统一的通道处理与生命周期管理系统在稳定性与性能之间取得平衡。结合MCP服务器与模型提供商配置可灵活适配多种场景。建议在生产环境中关注stderr日志、取消超时与模型配置变更策略以提升整体可靠性。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 使用示例与最佳实践
- 启动与配置
- 使用命令行参数或环境变量设置端口与项目目录;首次运行会自动生成默认配置文件。
- Codex代理需要正确的API密钥与base_url可通过ModelProviderConfig或环境变量注入。
- 交互流程
- 提交聊天请求后系统会按项目维度复用Agent若模型配置变化则自动重启Agent。
- 通过SSE实时接收会话开始、结束与错误通知支持取消正在执行的任务。
- 最佳实践
- 将模型配置与API密钥集中管理避免频繁变更导致Agent重启。
- 合理裁剪MCP服务器减少不必要的I/O与资源消耗。
- 在生产环境开启适当的日志级别,便于快速定位问题。
章节来源
- [crates/agent_runner/src/config.rs](file://crates/agent_runner/src/config.rs#L1-L270)
- [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L1-L132)
- [README.md](file://README.md#L440-L527)

View File

@@ -0,0 +1,249 @@
# 代理服务
<cite>
**本文档引用的文件**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
- [agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [docker_manager.rs](file://crates/docker_manager/src/manager.rs)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs)
- [main.rs](file://crates/agent_runner/src/main.rs)
- [agent-abstraction-layer-design.md](file://specs/agent-abstraction-layer-design.md)
</cite>
## 目录
1. [介绍](#介绍)
2. [核心组件](#核心组件)
3. [代理服务设计与实现](#代理服务设计与实现)
4. [与Docker管理器的集成](#与docker管理器的集成)
5. [异步任务调度与会话管理](#异步任务调度与会话管理)
6. [错误恢复与生命周期管理](#错误恢复与生命周期管理)
7. [与ACP适配器的交互模式](#与acp适配器的交互模式)
8. [多代理类型支持](#多代理类型支持)
9. [服务初始化与关闭逻辑](#服务初始化与关闭逻辑)
10. [结论](#结论)
## 介绍
代理服务是AI开发平台的核心组件负责管理AI代理的整个生命周期。该服务通过统一的接口抽象支持多种AI代理类型如Codex、Claude Code并利用容器化技术实现资源隔离和高效管理。本文档详细阐述了代理服务的设计与实现重点分析了AgentService结构体的核心作用、与Docker管理器的集成方式、异步任务调度机制以及错误恢复策略。
## 核心组件
代理服务的核心组件包括AgentService结构体、Docker管理器、会话缓存和清理任务。这些组件协同工作确保AI代理的高效、稳定运行。AgentService结构体作为统一接口封装了不同代理类型的启动和管理逻辑。Docker管理器负责容器的创建、启动和销毁实现资源的动态分配和隔离。会话缓存用于存储和管理会话状态支持SSEServer-Sent Events实时消息推送。清理任务则定期检查并清理闲置的代理实例优化资源利用率。
## 代理服务设计与实现
代理服务的设计遵循模块化和可扩展的原则,通过定义清晰的接口和抽象,实现了不同代理类型的统一管理。核心是`AcpAgentService` trait它定义了启动和管理ACP代理服务的统一接口。该trait的实现通过为`AgentType`枚举类型提供`async_trait`,实现了对不同代理类型的统一处理。
```mermaid
classDiagram
class AcpAgentService {
<<trait>>
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
+agent_type_name() &'static str
}
class AgentType {
+Claude
+Codex
}
AcpAgentService <|-- AgentType
```
**图源**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L7-L61)
`AcpConnectionInfo`结构体封装了与代理通信所需的关键信息包括会话ID、用于发送提示的通道、用于发送取消通知的通道以及代理停止句柄。这种设计使得外部组件可以通过这些通道与代理进行异步通信实现了非阻塞的消息传递。
**本节源码**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L31-L41)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L31-L41)
## 与Docker管理器的集成
代理服务通过`docker_manager` crate与Docker守护进程进行交互实现了AI代理的容器化运行。`DockerManager`结构体作为核心管理器封装了Docker客户端和配置信息提供了创建、启动、停止和清理容器的高级接口。
```mermaid
sequenceDiagram
participant 代理服务
participant Docker管理器
participant Docker守护进程
代理服务->>Docker管理器 : create_container(config)
Docker管理器->>Docker守护进程 : 检查镜像是否存在
alt 镜像不存在
Docker守护进程-->>Docker管理器 : 返回不存在
Docker管理器->>Docker守护进程 : pull_image(image)
end
Docker管理器->>Docker守护进程 : create_container(options, config)
Docker守护进程-->>Docker管理器 : container_id
Docker管理器->>Docker守护进程 : start_container(container_id)
Docker守护进程-->>Docker管理器 : 启动成功
Docker管理器-->>代理服务 : DockerContainerInfo
```
**图源**
- [docker_manager.rs](file://crates/docker_manager/src/manager.rs#L81-L294)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L129)
`DockerManager``create_container`方法是容器化运行AI代理实例的关键。该方法首先检查指定的镜像是否存在于本地如果不存在则从远程仓库拉取。然后它使用提供的配置创建容器包括挂载点、环境变量、端口映射和资源限制。最后启动容器并返回包含容器信息的`DockerContainerInfo`结构体。这种设计确保了每个AI代理实例都在独立的容器环境中运行实现了资源隔离和安全防护。
**本节源码**
- [docker_manager.rs](file://crates/docker_manager/src/manager.rs#L81-L294)
- [docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs#L21-L129)
## 异步任务调度与会话管理
代理服务采用异步任务调度机制,通过`tokio`运行时和`mpsc`通道实现高效的并发处理。`AcpAgentClient`结构体实现了`agent_client_protocol::Client` trait处理来自代理的会话通知。当收到`session_notification`时,它会解析通知内容,提取`request_id`,并将其与`session_id`关联,然后将更新推送到全局会话缓存。
```mermaid
flowchart TD
Start([收到session_notification]) --> ExtractSessionId["提取session_id"]
ExtractSessionId --> CheckMeta["检查meta中是否有request_id"]
CheckMeta --> |有| UseMetaId["使用meta中的request_id"]
CheckMeta --> |无| FindProjectId["通过session_id查找project_id"]
FindProjectId --> GetRequestId["从SESSION_REQUEST_CONTEXT获取request_id"]
GetRequestId --> |获取成功| UseContextId["使用context中的request_id"]
GetRequestId --> |获取失败| NoRequestId["未找到request_id"]
UseMetaId --> PushUpdate["推送AgentSessionUpdate"]
UseContextId --> PushUpdate
NoRequestId --> PushUpdate
PushUpdate --> End([完成])
```
**图源**
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L232-L257)
会话管理通过`SESSION_CACHE``PROJECT_SESSION_MAP`两个全局`DashMap`实现。`SESSION_CACHE``session_id`为键,存储`SessionData`后者包含用于SSE消息推送的通道和取消令牌。`PROJECT_SESSION_MAP`则维护`project_id``session_id`的映射,确保一个项目只对应一个活跃的会话。`push_session_update_with_project`函数在推送消息时,会自动检查并清理旧的会话数据,保证了会话状态的一致性。
**本节源码**
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L16-L355)
## 错误恢复与生命周期管理
代理服务通过`AgentLifecycleGuard`结构体实现基于RAIIResource Acquisition Is Initialization原则的生命周期管理。当`AgentLifecycleGuard``drop`时,其内部的`Drop`实现会自动清理代理资源,如停止子进程和取消异步任务。这种设计简化了资源管理,避免了资源泄漏。
```mermaid
classDiagram
class AgentLifecycleGuard {
+new_claude(...) AgentLifecycleGuard
+new_codex(...) AgentLifecycleGuard
+graceful_stop() Result~()~
+cancel()
+is_stopped() bool
}
class AgentResources {
<<enumeration>>
+Claude
+CodexSubProcess
+CodexEmbedded
}
AgentLifecycleGuard --> AgentLifecycleInner : 包含
AgentLifecycleInner --> AgentResources : 包含
```
**图源**
- [agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L21-L326)
`AgentLifecycleGuard``graceful_stop`方法实现了优雅停止代理的逻辑。它首先发送取消信号,然后根据代理类型执行相应的清理操作,如等待子进程退出或取消异步任务。`cancel`方法则用于非阻塞地发送取消信号。`is_stopped`方法检查代理是否已停止。这些方法共同构成了一个健壮的错误恢复机制,确保在各种异常情况下都能正确清理资源。
**本节源码**
- [agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L140-L204)
## 与ACP适配器的交互模式
代理服务通过`AcpAgentClient`与ACPAgent Client Protocol适配器进行交互。`AcpAgentClient`实现了`agent_client_protocol::Client` trait处理来自代理的各种请求如权限请求、文件读写和会话通知。当代理需要执行文件操作时`AcpAgentClient`会调用相应的`tokio::fs`函数,并将结果返回给代理。
```mermaid
sequenceDiagram
participant 代理
participant AcpAgentClient
participant 文件系统
代理->>AcpAgentClient : write_text_file(args)
AcpAgentClient->>文件系统 : create_dir_all(parent)
文件系统-->>AcpAgentClient : 创建成功
AcpAgentClient->>文件系统 : create_file(path)
文件系统-->>AcpAgentClient : 文件句柄
AcpAgentClient->>文件系统 : write_all(content)
文件系统-->>AcpAgentClient : 写入成功
AcpAgentClient-->>代理 : WriteTextFileResponse
```
**图源**
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L78-L98)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L100-L110)
`AcpAgentClient`还负责处理会话通知,如`AgentMessageChunk``AgentMessageComplete`。它将这些通知转换为`UnifiedSessionMessage`,并通过`push_session_update`函数推送到会话缓存最终通过SSE推送给前端客户端。这种交互模式实现了代理与外部系统的松耦合提高了系统的可维护性和可扩展性。
**本节源码**
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L232-L257)
## 多代理类型支持
代理服务通过`AgentType`枚举和`AcpAgentService` trait的实现支持多种代理类型如Codex和Claude Code。`AgentType`枚举定义了不同的代理类型,而`AcpAgentService` trait的实现则为每种类型提供了具体的启动逻辑。
```mermaid
classDiagram
class AcpAgentService {
<<trait>>
+start_agent_service(...) Result~AcpConnectionInfo~
}
class AgentType {
+Claude
+Codex
}
AcpAgentService <|-- AgentType
class start_claude_code_acp_agent_service {
+command_path : &str
+command_args : Vec~String~
+spawn_args : Vec~String~
+merged_envs : HashMap~String, String~
}
class start_codex_acp_agent_service {
+command_path : &str
+cli_args : Vec~String~
+merged_envs : HashMap~String, String~
}
AgentType --> start_claude_code_acp_agent_service : 启动
AgentType --> start_codex_acp_agent_service : 启动
```
**图源**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L30-L59)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L310)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L25-L397)
`start_claude_code_acp_agent_service``start_codex_acp_agent_service`函数分别负责启动Claude Code和Codex代理。它们通过`tokio::process::Command`启动子进程,并建立`ClientSideConnection`进行通信。这些函数还处理环境变量和CLI参数的配置确保代理能够正确初始化。这种设计实现了多代理类型的统一接口抽象使得添加新的代理类型变得简单而直观。
**本节源码**
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L28-L310)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L25-L397)
## 服务初始化与关闭逻辑
代理服务的初始化在`main.rs`文件的`main`函数中完成。它首先初始化遥测系统然后解析命令行参数和配置文件。接着它创建项目工作目录并启动清理任务。最后它创建HTTP服务器并监听指定端口。
```mermaid
flowchart TD
Start([main函数开始]) --> InitTelemetry["初始化遥测系统"]
InitTelemetry --> ParseArgs["解析命令行参数"]
ParseArgs --> LoadConfig["加载配置文件"]
LoadConfig --> CreateDir["创建项目工作目录"]
CreateDir --> StartCleanup["启动清理任务"]
StartCleanup --> SpawnWorker["启动agent_worker线程"]
SpawnWorker --> StartProxy["启动Pingora代理服务"]
StartProxy --> CreateRouter["创建HTTP路由"]
CreateRouter --> BindListener["绑定TCP监听器"]
BindListener --> Serve["启动HTTP服务器"]
Serve --> AwaitProxy["等待代理服务完成"]
AwaitProxy --> End([main函数结束])
```
**图源**
- [main.rs](file://crates/agent_runner/src/main.rs#L29-L178)
服务的关闭逻辑由`tokio`运行时的正常退出机制处理。当HTTP服务器停止时`main`函数会等待代理服务完成,然后正常退出。清理任务和`agent_worker`线程也会随之停止。`init_telemetry`函数设置了全局的文本传播器,确保了`trace_id`的生成和传播,便于后续的性能分析和故障排查。
**本节源码**
- [main.rs](file://crates/agent_runner/src/main.rs#L29-L178)
- [main.rs](file://crates/agent_runner/src/main.rs#L181-L231)
## 结论
代理服务通过精心设计的架构和实现成功地管理了AI代理的整个生命周期。它利用Rust的异步特性和类型系统实现了高效、安全和可扩展的代理管理。与Docker管理器的集成确保了资源的隔离和安全而异步任务调度和会话管理机制则保证了系统的高性能和实时性。错误恢复和生命周期管理策略进一步增强了系统的健壮性。通过统一的接口抽象代理服务支持多种代理类型为未来的扩展奠定了坚实的基础。整体而言该服务是AI开发平台中不可或缺的核心组件为用户提供了一个稳定、高效的AI代理运行环境。

View File

@@ -0,0 +1,536 @@
# 代理运行器架构
<cite>
**本文档引用的文件**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [lib.rs](file://crates/agent_runner/src/lib.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [router.rs](file://crates/agent_runner/src/router.rs)
- [model.rs](file://crates/agent_runner/src/model.rs)
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [lib.rs](file://crates/acp_adapter/src/lib.rs)
- [lib.rs](file://crates/docker_manager/src/lib.rs)
- [lib.rs](file://crates/pingora-proxy/src/lib.rs)
- [lib.rs](file://crates/shared_types/src/lib.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 简介
代理运行器是一个基于Rust的高性能AI代理管理平台旨在为AI驱动的开发提供完整的代理集成解决方案。该系统通过ACPAgent Client Protocol协议与不同的AI代理如Codex、Claude Code进行通信实现了代理生命周期管理、会话状态维护和异步任务调度等核心功能。系统采用模块化设计通过Pingora反向代理实现高性能的请求路由并通过Docker管理器实现资源隔离和容器化部署。代理运行器支持多代理架构通过抽象层设计实现了不同AI代理的无缝集成。
## 项目结构
代理运行器采用Rust工作区workspace结构包含多个独立的crates每个crate负责特定的功能模块。这种模块化设计提高了代码的可维护性和可扩展性。
```mermaid
graph TD
A[代理运行器] --> B[agent_runner]
A --> C[acp_adapter]
A --> D[claude-code-agent]
A --> E[codex-acp-agent]
A --> F[docker_manager]
A --> G[pingora-proxy]
A --> H[rcoder]
A --> I[shared_types]
B --> J[HTTP服务器]
B --> K[代理服务]
B --> L[会话管理]
C --> M[ACP协议适配]
F --> N[Docker容器管理]
G --> O[反向代理]
I --> P[共享数据类型]
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [lib.rs](file://crates/agent_runner/src/lib.rs)
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
## 核心组件
代理运行器的核心组件包括代理服务管理、会话状态维护、ACP协议适配和Docker资源管理。这些组件协同工作实现了AI代理的全生命周期管理。
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [lib.rs](file://crates/agent_runner/src/lib.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
## 架构概述
代理运行器采用分层架构设计从上到下分为HTTP接口层、业务逻辑层、代理服务层和基础设施层。这种分层设计确保了系统的高内聚、低耦合特性。
```mermaid
graph TD
A[HTTP接口层] --> B[业务逻辑层]
B --> C[代理服务层]
C --> D[基础设施层]
A --> E[API路由]
A --> F[请求处理]
B --> G[会话管理]
B --> H[状态维护]
C --> I[ACP适配]
C --> J[代理通信]
D --> K[Docker管理]
D --> L[资源隔离]
E --> M[chat_handler]
F --> N[agent_service]
G --> O[session_cache]
H --> P[AgentStatus]
I --> Q[acp_adapter]
J --> R[claude_code_agent]
K --> S[docker_manager]
L --> T[container隔离]
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [router.rs](file://crates/agent_runner/src/router.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [docker_manager/src/lib.rs](file://crates/docker_manager/src/lib.rs)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [router.rs](file://crates/agent_runner/src/router.rs)
## 详细组件分析
### 代理生命周期管理
代理运行器通过`agent_worker`任务管理所有AI代理的生命周期。每个代理服务与一个项目ID关联实现了代理的复用和资源优化。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Handler as "chat_handler"
participant AgentWorker as "agent_worker"
participant AgentService as "代理服务"
Client->>Handler : POST /chat
Handler->>AgentWorker : 发送LocalSetAgentRequest
AgentWorker->>AgentWorker : 检查现有代理
alt 代理存在
AgentWorker->>AgentService : 复用现有代理
AgentService-->>AgentWorker : 返回会话ID
else 代理不存在
AgentWorker->>AgentService : 创建新代理
AgentService-->>AgentWorker : 返回会话ID
end
AgentWorker->>Handler : 发送ChatPromptResponse
Handler-->>Client : 返回响应
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs#L58-L76)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L196-L341)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
### 会话状态维护
会话状态维护是代理运行器的核心功能之一,通过`SESSION_CACHE``PROJECT_SESSION_MAP`两个全局数据结构实现。
```mermaid
classDiagram
class SessionData {
+command_tx : UnboundedSender~SessionCommand~
+current_sender : Arc~Mutex~Option~Sender~UnifiedSessionMessage~~~~
+current_cancel : Arc~Mutex~Option~CancellationToken~~~
+new(max_size : usize) Arc~Self~
+message_count() usize
+create_new_connection(buffer_size : usize) Result~(Receiver~UnifiedSessionMessage~, CancellationToken)~
+push_message(message : UnifiedSessionMessage)
+close_current_connection()
}
class SessionWorker {
-max_size : usize
-command_rx : UnboundedReceiver~SessionCommand~
-current_sender : Arc~Mutex~Option~Sender~UnifiedSessionMessage~~~~
-current_cancel : Arc~Mutex~Option~CancellationToken~~~
+spawn(max_size : usize, command_rx : UnboundedReceiver~SessionCommand~, current_sender : Arc~Mutex~Option~Sender~UnifiedSessionMessage~~~~, current_cancel : Arc~Mutex~Option~CancellationToken~~~)
+run()
}
class SessionCommand {
+Push{message : UnifiedSessionMessage}
+Clear{ack : oneshot : : Sender~usize~}
+MessageCount{ack : oneshot : : Sender~usize~}
}
SessionData --> SessionWorker : "spawn"
SessionWorker --> SessionCommand : "处理"
SessionData --> SessionCommand : "发送命令"
```
**图表来源**
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L25-L222)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L142-L171)
**章节来源**
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
### ACP协议适配器
ACP协议适配器是代理运行器与AI代理通信的核心组件实现了ACP协议的客户端功能。
```mermaid
classDiagram
class AcpAgentClient {
+request_permission(args : RequestPermissionRequest) Result~RequestPermissionResponse, Error~
+write_text_file(args : WriteTextFileRequest) Result~WriteTextFileResponse, Error~
+read_text_file(args : ReadTextFileRequest) Result~ReadTextFileResponse, Error~
+session_notification(args : SessionNotification) Result~(), Error~
+ext_method(request : ExtRequest) Result~ExtResponse, Error~
+ext_notification(notification : ExtNotification) Result~(), Error~
}
class Client {
<<trait>>
+request_permission(args : RequestPermissionRequest) Result~RequestPermissionResponse, Error~
+write_text_file(args : WriteTextFileRequest) Result~WriteTextFileResponse, Error~
+read_text_file(args : ReadTextFileRequest) Result~ReadTextFileResponse, Error~
+session_notification(args : SessionNotification) Result~(), Error~
+ext_method(request : ExtRequest) Result~ExtResponse, Error~
+ext_notification(notification : ExtNotification) Result~(), Error~
}
AcpAgentClient --|> Client : "实现"
class AcpConnectionInfo {
+session_id : SessionId
+prompt_tx : UnboundedSender~PromptRequest~
+cancel_tx : UnboundedSender~CancelNotificationRequest~
+stop_handle : Option~AgentStopHandleArc~
}
class AcpAgentService {
<<trait>>
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
+agent_type_name() &'static str
}
AcpAgentService <-- AcpConnectionInfo : "返回"
AcpAgentClient <-- AcpConnectionInfo : "使用"
```
**图表来源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L43-L255)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
**章节来源**
- [acp_adapter/src/lib.rs](file://crates/acp_adapter/src/lib.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
### 多代理支持实现
代理运行器通过`AgentType`枚举和特征对象实现了对多种AI代理的支持包括Claude和Codex。
```mermaid
classDiagram
class AgentType {
<<enum>>
+Claude
+Codex
}
class AcpAgentService {
<<trait>>
+start_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
+agent_type_name() &'static str
}
AgentType --|> AcpAgentService : "实现"
class ClaudeCodeAgent {
+start_claude_code_acp_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
}
class CodexAgent {
+start_codex_acp_agent_service(chat_prompt : ChatPrompt, model_provider : Option~ModelProviderConfig~) Result~AcpConnectionInfo~
}
AcpAgentService <|-- ClaudeCodeAgent : "具体实现"
AcpAgentService <|-- CodexAgent : "具体实现"
AgentType --> ClaudeCodeAgent : "调用"
AgentType --> CodexAgent : "调用"
```
**图表来源**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
**章节来源**
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
### 异步任务调度
代理运行器采用Rust的异步运行时模型通过Tokio运行时和LocalSet实现了高效的异步任务调度。
```mermaid
flowchart TD
A[主异步运行时] --> B[HTTP服务器]
A --> C[清理任务]
A --> D[代理服务]
D --> E[独立OS线程]
E --> F[单线程Tokio运行时]
F --> G[LocalSet]
G --> H[agent_worker]
H --> I[ACP连接]
H --> J[通道处理器]
B --> K[请求处理]
K --> L[发送LocalSetAgentRequest]
L --> H
C --> M[定期清理]
M --> N[清理空闲会话]
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs#L58-L76)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L196-L341)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
### 资源隔离策略
代理运行器通过Docker管理器实现了严格的资源隔离确保每个AI代理在独立的容器环境中运行。
```mermaid
classDiagram
class DockerManager {
+new(config : DockerManagerConfig) DockerResult~Self~
+create_container(config : ContainerConfig) DockerResult~Container~
+start_container(container_id : &str) DockerResult~()
+stop_container(container_id : &str) DockerResult~()
+remove_container(container_id : &str) DockerResult~()
+list_containers() DockerResult~Vec~ContainerInfo~~
}
class ContainerConfig {
+image : String
+name : String
+ports : Vec~PortMapping~
+volumes : Vec~VolumeMapping~
+env_vars : Vec~EnvVar~
+network_mode : String
}
class PortMapping {
+host_port : u16
+container_port : u16
}
class VolumeMapping {
+host_path : String
+container_path : String
}
class EnvVar {
+name : String
+value : String
}
DockerManager --> ContainerConfig : "使用"
ContainerConfig --> PortMapping : "包含"
ContainerConfig --> VolumeMapping : "包含"
ContainerConfig --> EnvVar : "包含"
```
**图表来源**
- [docker_manager/src/lib.rs](file://crates/docker_manager/src/lib.rs)
- [docker_manager/src/manager.rs](file://crates/docker_manager/src/manager.rs)
**章节来源**
- [docker_manager/src/lib.rs](file://crates/docker_manager/src/lib.rs)
### 错误恢复机制
代理运行器实现了多层次的错误恢复机制,确保系统的稳定性和可靠性。
```mermaid
flowchart TD
A[错误发生] --> B{错误类型}
B --> C[可恢复错误]
B --> D[不可恢复错误]
C --> E[重试机制]
E --> F[指数退避]
F --> G[最大重试次数]
G --> H{重试成功?}
H --> |是| I[继续执行]
H --> |否| J[降级处理]
D --> K[优雅降级]
K --> L[返回默认值]
L --> M[记录错误日志]
M --> N[发送告警]
I --> O[正常流程]
J --> O
N --> O
P[监控系统] --> Q[错误指标]
Q --> R[告警系统]
R --> S[运维人员]
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs#L31-L232)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L142-L161)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L235-L247)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
### 可扩展性考虑
代理运行器的设计充分考虑了可扩展性,通过模块化架构和配置驱动的方式支持未来的功能扩展。
```mermaid
graph TD
A[核心框架] --> B[插件系统]
A --> C[配置管理]
A --> D[服务发现]
B --> E[新代理类型]
B --> F[新协议适配]
B --> G[新存储后端]
C --> H[动态配置]
C --> I[热更新]
C --> J[配置验证]
D --> K[服务注册]
D --> L[健康检查]
D --> M[负载均衡]
A --> N[监控系统]
N --> O[指标收集]
N --> P[日志聚合]
N --> Q[分布式追踪]
O --> R[Prometheus]
P --> S[ELK]
Q --> T[OpenTelemetry]
```
**图表来源**
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [config.rs](file://crates/agent_runner/src/config.rs)
- [main.rs](file://crates/agent_runner/src/main.rs)
**章节来源**
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [config.rs](file://crates/agent_runner/src/config.rs)
### 性能监控
代理运行器集成了全面的性能监控系统通过OpenTelemetry实现分布式追踪和指标收集。
```mermaid
graph TD
A[应用代码] --> B[Tracing]
B --> C[OpenTelemetry]
C --> D[Exporter]
D --> E[Jaeger]
D --> F[Prometheus]
D --> G[Zipkin]
A --> H[Metrics]
H --> I[Counter]
H --> J[Histogram]
H --> K[Gauge]
I --> L[请求计数]
J --> M[响应时间]
K --> N[并发数]
A --> O[Logging]
O --> P[JSON日志]
P --> Q[ELK]
C --> R[Trace Context]
R --> S[跨服务追踪]
T[监控面板] --> U[指标可视化]
U --> V[告警规则]
V --> W[通知系统]
```
**图表来源**
- [main.rs](file://crates/agent_runner/src/main.rs#L181-L231)
- [Cargo.toml](file://crates/agent_runner/Cargo.toml#L65-L69)
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
### 与docker_manager的集成
代理运行器与Docker管理器深度集成实现了容器化部署和资源管理。
```mermaid
sequenceDiagram
participant AgentRunner as "代理运行器"
participant DockerManager as "Docker管理器"
participant DockerDaemon as "Docker守护进程"
AgentRunner->>DockerManager : 创建容器请求
DockerManager->>DockerDaemon : 创建容器
DockerDaemon-->>DockerManager : 容器ID
DockerManager->>DockerDaemon : 启动容器
DockerDaemon-->>DockerManager : 启动成功
DockerManager-->>AgentRunner : 容器准备就绪
AgentRunner->>DockerManager : 发送命令
DockerManager->>DockerDaemon : 执行命令
DockerDaemon-->>DockerManager : 命令输出
DockerManager-->>AgentRunner : 返回结果
AgentRunner->>DockerManager : 停止容器
DockerManager->>DockerDaemon : 停止容器
DockerDaemon-->>DockerManager : 停止成功
DockerManager-->>AgentRunner : 清理完成
```
**图表来源**
- [docker_manager/src/lib.rs](file://crates/docker_manager/src/lib.rs)
- [docker_manager/src/manager.rs](file://crates/docker_manager/src/manager.rs)
**章节来源**
- [docker_manager/src/lib.rs](file://crates/docker_manager/src/lib.rs)
## 依赖分析
代理运行器的依赖关系清晰,各模块之间的耦合度低,便于维护和扩展。
```mermaid
graph TD
A[agent_runner] --> B[acp_adapter]
A --> C[shared_types]
A --> D[pingora-proxy]
A --> E[claude-code-agent]
A --> F[codex-acp-agent]
A --> G[docker_manager]
B --> H[agent-client-protocol]
C --> I[grpc]
D --> J[axum]
D --> K[reqwest]
E --> L[agent-client-protocol]
F --> M[agent-client-protocol]
G --> N[bollard]
A --> O[tokio]
A --> P[axum]
A --> Q[tracing]
A --> R[serde]
A --> S[dashmap]
O --> T[异步运行时]
P --> U[Web框架]
Q --> V[日志追踪]
R --> W[序列化]
S --> X[并发映射]
```
**图表来源**
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
- [Cargo.toml](file://crates/acp_adapter/Cargo.toml)
- [Cargo.toml](file://crates/pingora-proxy/Cargo.toml)
**章节来源**
- [Cargo.toml](file://crates/agent_runner/Cargo.toml)
## 性能考虑
代理运行器在设计时充分考虑了性能因素,采用了多种优化策略。
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
## 故障排除指南
当代理运行器出现问题时,可以按照以下步骤进行排查。
**章节来源**
- [main.rs](file://crates/agent_runner/src/main.rs)
- [acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
## 结论
代理运行器通过精心设计的架构和实现提供了一个高性能、可扩展的AI代理管理平台。系统采用模块化设计各组件职责清晰耦合度低。通过ACP协议适配器实现了与不同AI代理的无缝集成。异步任务调度和资源隔离策略确保了系统的高效性和稳定性。全面的监控和错误恢复机制为系统的可靠运行提供了保障。整体架构具有良好的可扩展性能够适应未来的需求变化。

View File

@@ -0,0 +1,356 @@
# 会话缓存机制
<cite>
**本文引用的文件**
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs)
- [model.rs](file://crates/agent_runner/src/model.rs)
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性阐述 session_cache 模块如何管理 AI 代理会话状态,涵盖缓存数据结构设计、生命周期管理策略、并发访问控制机制、缓存项的创建/更新/清理流程,以及与代理服务的交互模式。文档还记录内存使用特征、过期策略与性能优化措施,并提供聊天交互与进度查询的实际使用场景示例。
## 项目结构
围绕会话缓存的关键文件组织如下:
- 会话缓存核心session_cache.rs
- SSE 进度通知agent_session_notification.rs
- 聊天入口与会话清理chat_handler.rs
- 清理任务与资源回收cleanup_task.rs
- 统一消息模型与通知agent_session_notify.rs、model.rs
- 代理侧会话通知转发proxy_agent/mod.rs
```mermaid
graph TB
subgraph "会话缓存层"
SC["SessionData<br/>环形缓冲区+命令通道"]
PC["PROJECT_SESSION_MAP<br/>项目-会话映射"]
GC["全局缓存 SESSION_CACHE<br/>按session_id索引"]
end
subgraph "代理侧"
AC["AcpAgentClient<br/>session_notification回调"]
PRJ["PROJECT_AND_AGENT_INFO_MAP<br/>项目-代理状态"]
end
subgraph "HTTP处理层"
SSE["SSE 进度接口<br/>agent_session_notification.rs"]
CHAT["聊天接口<br/>chat_handler.rs"]
end
subgraph "清理与回收"
CLEAN["清理任务<br/>cleanup_task.rs"]
end
AC --> |"推送通知"| SC
SSE --> |"建立SSE并创建SessionData"| GC
CHAT --> |"清理旧会话/新会话"| GC
CLEAN --> |"定期扫描并清理"| GC
CLEAN --> |"清理映射"| PC
AC --> |"回填request_id上下文"| AC
```
图表来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L211-L258)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L211-L258)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
## 核心组件
- 全局会话缓存 SESSION_CACHE以 session_id 为键,存储每个会话的 SessionData。
- 项目-会话映射 PROJECT_SESSION_MAP确保同一项目仅有一个活跃会话变更时自动清理旧会话。
- SessionData封装环形缓冲区、命令通道、当前发送器与取消令牌负责消息入队、实时推送与连接关闭。
- SessionWorker后台工作者消费命令通道维护环形缓冲区按需实时推送消息。
- 统一会话消息 UnifiedSessionMessage 与通知 SessionNotify标准化消息格式便于跨组件传递。
- SSE 进度接口 agent_session_notification为前端建立 SSE 连接,实时推送会话状态。
- 清理任务 cleanup_task定期扫描并清理闲置代理与孤立会话。
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L1-L180)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L1-L120)
## 架构总览
会话缓存的整体交互链路如下:
- 代理侧 AcpAgentClient 在收到 session_notification 后,构造 SessionNotify 并调用 push_session_update统一转为 UnifiedSessionMessage 写入 SessionData。
- SSE 进度接口 agent_session_notification 为每个 session_id 创建新的 SessionData 并插入 SESSION_CACHE随后创建连接并持续推送消息。
- 聊天接口 chat_handler 在发起新请求前,会清理旧会话,确保全新开始。
- 清理任务定期扫描 PROJECT_SESSION_MAP 与 SESSION_CACHE清理孤立会话与闲置代理。
```mermaid
sequenceDiagram
participant Agent as "代理(AcpAgentClient)"
participant Cache as "SessionData/Worker"
participant SSE as "SSE接口"
participant Front as "前端"
Agent->>Cache : "push_session_update(SessionNotify)"
Cache->>Cache : "SessionWorker : Push消息到环形缓冲区"
Cache->>Cache : "尝试实时推送至当前发送器"
SSE->>Cache : "create_new_connection(新建SessionData)"
Cache-->>SSE : "返回接收端+取消令牌"
loop "SSE循环"
Cache-->>SSE : "推送UnifiedSessionMessage"
SSE-->>Front : "SSE事件"
end
Note over SSE,Cache : "取消令牌触发或发送端关闭时SSE断开"
```
图表来源
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L105-L221)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
## 详细组件分析
### 会话缓存数据结构与生命周期
- 数据结构设计
- SESSION_CACHE全局 DashMap键为 session_id值为 Arc<SessionData>,保证并发安全与零拷贝共享。
- SessionData包含命令发送端、当前发送器与取消令牌的互斥保护避免竞态。
- SessionWorker持有环形缓冲区HeapRb按最大容量维护消息队列实时推送失败时自动清理当前发送器。
- PROJECT_SESSION_MAP全局 DashMap键为 project_id值为 session_id确保同一项目仅有一个活跃会话。
- 生命周期管理
- 新建SSE 接口为每个 session_id 创建新的 SessionData 并插入 SESSION_CACHE覆盖旧值确保“全新开始”。
- 销毁SessionWorker 退出时SessionData 仍驻留缓存;清理任务通过移除映射与缓存条目实现资源回收。
- 连接关闭:主动触发 CancellationToken 或显式关闭发送端,使接收端 recv() 返回 NoneSSE 自然断开。
```mermaid
classDiagram
class SessionData {
+command_tx
+current_sender
+current_cancel
+new(max_size)
+create_new_connection(buffer_size)
+push_message(message)
+close_current_connection()
+message_count()
}
class SessionWorker {
-max_size
-command_rx
-current_sender
-current_cancel
+spawn(...)
+run()
}
class UnifiedSessionMessage {
+session_id
+message_type
+sub_type
+data
+timestamp
+heartbeat(session_id)
}
class SessionNotify {
+to_unified_message()
}
SessionData --> SessionWorker : "spawn并消费命令"
SessionWorker --> UnifiedSessionMessage : "生产消息"
SessionNotify --> UnifiedSessionMessage : "转换"
```
图表来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L24-L221)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L1-L180)
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L1-L180)
### 并发访问控制机制
- 全局缓存与映射
- 使用 LazyLock 初始化 DashMap保证线程安全与延迟初始化。
- SessionData 内部对 current_sender/current_cancel 使用 Mutex 包裹,避免多处同时写入导致的竞争。
- 命令通道
- SessionData 内部使用无界 mpsc 通道接收命令SessionWorker 异步消费,避免阻塞代理通知路径。
- 取消令牌
- 每次创建新连接都会生成新的 CancellationToken旧连接一旦被新连接抢占或用户取消立即触发取消确保旧连接快速失效。
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
### 缓存项创建、更新与清理流程
- 创建
- SSE 接口为 session_id 创建 SessionData 并插入 SESSION_CACHE同时创建连接并返回接收端与取消令牌。
- 更新
- 代理侧 session_notification 回调将 SessionUpdate 转为 SessionNotify再转为 UnifiedSessionMessage通过 SessionData.push_message 入队。
- SessionWorker 将消息写入环形缓冲区,并尝试实时推送至当前发送器;若推送失败则清空当前发送器,避免脏写。
- 清理
- SSE 接口当取消令牌被触发或发送端关闭时SSE 断开,旧 SessionData 仍保留,等待清理任务回收。
- 清理任务:扫描 PROJECT_SESSION_MAP 与 SESSION_CACHE移除孤立会话与空闲代理减少内存占用。
```mermaid
flowchart TD
Start(["开始"]) --> Create["SSE接口创建SessionData并插入缓存"]
Create --> Push["代理推送SessionNotify->UnifiedSessionMessage"]
Push --> Buffer["SessionWorker写入环形缓冲区"]
Buffer --> Realtime{"实时推送成功?"}
Realtime --> |是| SSELoop["SSE循环推送消息"]
Realtime --> |否| ClearSender["清空当前发送器"]
SSELoop --> Cancel{"取消令牌触发/发送端关闭?"}
Cancel --> |是| Close["SSE断开旧SessionData保留"]
Cancel --> |否| Heartbeat["周期心跳"]
Close --> Cleanup["清理任务扫描并移除"]
Cleanup --> End(["结束"])
```
图表来源
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L105-L221)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
章节来源
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L105-L221)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
### 与代理服务的交互模式
- 代理侧 AcpAgentClient 实现 session_notification 回调,将 ACP SessionUpdate 转为 AgentSessionUpdate再包装为 SessionNotify最终调用 push_session_update 写入缓存。
- 若 SessionNotification.meta 中未携带 request_id则通过 PROJECT_AND_AGENT_INFO_MAP 查找 project_id再从 SESSION_REQUEST_CONTEXT 获取 request_id确保消息携带 request_id 以便前端关联。
```mermaid
sequenceDiagram
participant ACP as "ACP客户端"
participant Client as "AcpAgentClient"
participant Cache as "push_session_update"
participant Worker as "SessionWorker"
participant SSE as "SSE接口"
ACP->>Client : "session_notification(SessionUpdate)"
Client->>Client : "提取/回填request_id"
Client->>Cache : "SessionNotify -> UnifiedSessionMessage"
Cache->>Worker : "命令 : Push"
Worker->>Worker : "写入环形缓冲区"
Worker->>SSE : "尝试实时推送"
SSE-->>Client : "SSE循环接收并转发"
```
图表来源
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L231-L257)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
章节来源
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L231-L257)
### 过期策略与内存使用特征
- 过期策略
- 心跳消息SSE 接口在建立连接后立即发送心跳,并按周期发送心跳事件,用于维持连接活性。
- 取消与断开取消令牌触发或发送端关闭时SSE 断开SessionWorker 退出后SessionData 仍驻留缓存,等待清理任务回收。
- 孤立会话清理:清理任务扫描 SESSION_CACHE 中不在活跃映射中的 session_id若消息计数大于 0 则移除条目,否则标记为空会话清理。
- 内存使用特征
- 环形缓冲区:按最大容量维护最近消息,满时淘汰最旧消息,避免无限增长。
- 连接级缓存:每次 SSE 连接都会创建新的 SessionData覆盖旧值确保不会累积历史消息。
- 映射表PROJECT_SESSION_MAP 仅保存活跃映射,清理任务移除无效映射,降低内存压力。
章节来源
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L385-L475)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L173-L221)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
### 性能优化措施
- 极简设计
- SessionData 直接共享当前发送器与取消令牌,避免命令传递带来的额外开销。
- SessionWorker 直接从共享状态获取发送器,实时推送失败时立即清空,避免后续无效尝试。
- 通道与锁粒度
- 使用无界命令通道与细粒度 Mutex降低锁竞争概率。
- 心跳与断开
- 心跳事件降低连接空闲时的网络压力;取消令牌与发送端关闭确保旧连接快速失效,避免资源浪费。
- 清理策略
- 定期清理孤立会话与闲置代理,减少缓存与映射膨胀。
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L105-L221)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L241)
## 依赖关系分析
- 组件耦合
- session_cache 与 agent_session_notificationSSE 接口依赖 SessionData 的创建与连接能力。
- proxy_agent/mod 与 session_cache代理侧通知通过 push_session_update 写入缓存,二者通过统一消息模型解耦。
- chat_handler 与 session_cache聊天接口在发起新请求前清理旧会话确保全新开始。
- cleanup_task 与 session_cache/PROJECT_SESSION_MAP清理孤立会话与映射避免资源泄漏。
- 外部依赖
- DashMap 提供并发安全的哈希表。
- ringbuf HeapRb 提供高效环形缓冲区。
- tokio mpsc 提供异步通道与取消令牌。
```mermaid
graph LR
A["agent_session_notification.rs"] --> B["session_cache.rs"]
C["proxy_agent/mod.rs"] --> B
D["chat_handler.rs"] --> B
E["cleanup_task.rs"] --> B
E --> F["PROJECT_SESSION_MAP"]
```
图表来源
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L140)
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L211-L258)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
章节来源
- [model.rs](file://crates/agent_runner/src/model.rs#L1-L12)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L1-L180)
## 性能考量
- 环形缓冲区容量:根据业务负载调整最大容量,平衡内存占用与消息保留范围。
- 实时推送失败处理:推送失败时清空发送器,避免后续无效尝试;必要时增加接收端缓冲大小。
- 心跳频率:合理的心跳间隔可在保持连接活性与网络开销之间取得平衡。
- 清理周期:清理任务的间隔与闲置超时可根据系统负载动态调整,避免过于频繁或过少。
## 故障排查指南
- SSE 连接无法建立
- 检查 SSE 接口是否成功创建 SessionData 并插入 SESSION_CACHE。
- 确认 create_new_connection 是否返回接收端与取消令牌。
- 实时消息未到达前端
- 检查 SessionWorker 是否成功写入环形缓冲区与尝试实时推送。
- 若推送失败,确认当前发送器是否被清空,以及取消令牌是否被触发。
- 旧会话消息残留
- 确认 SSE 接口是否为每个 session_id 创建新的 SessionData 并覆盖旧值。
- 检查清理任务是否正确扫描并移除孤立会话。
- 代理通知未写入缓存
- 确认 AcpAgentClient 的 session_notification 回调是否正确提取 request_id 并调用 push_session_update。
- 检查 SessionData 是否存在且未被清理。
章节来源
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L105-L221)
- [proxy_agent/mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L240)
- [cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L156-L241)
## 结论
session_cache 模块通过 SessionData + SessionWorker + 环形缓冲区的组合,实现了高并发、低开销的会话状态缓存与实时推送。配合 SSE 进度接口、聊天入口清理策略与定期清理任务,系统在保证消息实时性的同时,有效控制内存与资源占用,满足 AI 代理会话状态管理的需求。
## 附录
### 实际使用场景示例
- 聊天交互
- 前端调用聊天接口后端为项目生成或复用会话清理旧会话后启动代理任务SSE 接口实时推送执行进度。
- 进度查询
- 前端通过 /agent/progress/{session_id} 建立 SSE 连接,接收 prompt_start、agent_message_chunk、tool_call 等事件,结合心跳维持连接活性。
章节来源
- [chat_handler.rs](file://crates/agent_runner/src/handler/chat_handler.rs#L176-L320)
- [agent_session_notification.rs](file://crates/agent_runner/src/handler/agent_session_notification.rs#L355-L483)

View File

@@ -0,0 +1,314 @@
# 清理任务
<cite>
**本文引用的文件**
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs)
- [crates/rcoder/src/proxy_agent/docker_container_agent.rs](file://crates/rcoder/src/proxy_agent/docker_container_agent.rs)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs)
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件面向“清理任务”模块系统性阐述其如何在代理终止后回收系统资源包括定时调度、闲置检测、容器与端口释放、SSE会话清理、孤立容器扫描、超时与错误处理策略以及与代理停止处理器的协作方式。文档同时提供配置项说明、性能影响评估与最佳实践建议帮助读者在不同场景下正确使用与扩展该模块。
## 项目结构
清理任务位于 rcoder 与 agent_runner 两个子 crate 中,分别针对不同的运行形态与状态管理:
- rcoder 清理任务:面向基于容器的代理,具备更完善的资源回收与超时控制,包含孤立容器扫描与端口释放。
- agent_runner 清理任务:面向本地进程型代理,采用 RAII 模式,通过移除映射触发生命周期守卫自动清理。
```mermaid
graph TB
subgraph "rcoder 清理任务"
RC_Config["CleanupConfig<br/>闲置超时/清理间隔/Docker停止超时"]
RC_AgentCleaner["AgentCleaner<br/>扫描/清理/统计"]
RC_State["AppState<br/>project_and_agent_map/sessions"]
RC_Docker["DockerManager<br/>统一停止接口"]
RC_PortMgr["PortManager<br/>端口分配/释放"]
RC_CleanupTask["start_cleanup_task()"]
end
subgraph "agent_runner 清理任务"
AR_Config["CleanupConfig<br/>闲置超时/清理间隔"]
AR_AgentCleaner["AgentCleaner<br/>扫描/清理/统计"]
AR_Maps["PROJECT_AND_AGENT_INFO_MAP<br/>SESSION_CACHE/PROJECT_SESSION_MAP"]
AR_CleanupTask["start_cleanup_task()"]
end
subgraph "代理停止处理器"
StopGuard["AgentLifecycleGuard<br/>Drop自动清理"]
end
RC_AgentCleaner --> RC_State
RC_AgentCleaner --> RC_Docker
RC_AgentCleaner --> RC_PortMgr
RC_CleanupTask --> RC_AgentCleaner
AR_AgentCleaner --> AR_Maps
AR_CleanupTask --> AR_AgentCleaner
StopGuard -.协作.-> AR_AgentCleaner
StopGuard -.协作.-> RC_AgentCleaner
```
图表来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L67-L106)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L18-L36)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L21-L32)
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L26-L36)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L1-L20)
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L67-L106)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L18-L36)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L21-L32)
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L26-L36)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L1-L20)
## 核心组件
- 清理配置 CleanupConfig
- rcoder 版本包含闲置超时、清理间隔、Docker 停止超时agent_runner 版本仅包含闲置超时与清理间隔。
- 清理统计 CleanupStats
- 记录清理总量、成功/失败数、孤立会话/SSE 消息清理数与最后清理时间。
- AgentCleaner
- 扫描闲置代理、清理孤立会话、销毁容器、释放端口、移除映射、触发生命周期守卫 Drop。
- AgentLifecycleGuard代理停止处理器
- 通过 Drop 自动清理资源,保证容器、进程、通道等资源得到回收。
- 端口管理 PortManager
- 在容器销毁时释放端口,避免端口泄漏。
- DockerManager 统一停止接口
- 提供运行时清理策略,支持优雅停止与强制停止,配合超时控制。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L67-L106)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L18-L36)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L21-L32)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L1-L20)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs#L252-L269)
## 架构总览
清理任务以“定时轮询 + RAII 回收”的方式工作:
- 定时器按清理间隔触发清理流程。
- 扫描阶段识别 Idle 状态且超时的代理,同时清理孤立会话与 SSE 消息。
- 对于 rcoder 场景,先销毁容器并释放端口,再移除映射,触发生命周期守卫 Drop 完成其余资源回收。
- 对于 agent_runner 场景,直接移除映射,生命周期守卫 Drop 触发资源清理。
```mermaid
sequenceDiagram
participant Timer as "定时器(interval)"
participant Cleaner as "AgentCleaner"
participant State as "AppState/Maps"
participant Docker as "DockerManager"
participant Guard as "AgentLifecycleGuard"
participant Port as "PortManager"
Timer->>Cleaner : tick()
Cleaner->>State : 读取project_and_agent_map/sessions
Cleaner->>Cleaner : 扫描Idle且超时的代理
alt rcoder场景
Cleaner->>Docker : 停止容器(runtime_cleanup)
Docker-->>Cleaner : 结果
Cleaner->>Port : 释放端口
Port-->>Cleaner : 完成
end
Cleaner->>State : 原子性移除映射(entry.remove_entry)
State-->>Guard : Drop触发自动清理
Cleaner-->>Timer : 统计与日志
```
图表来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L815)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L278-L292)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L236-L292)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L51-L59)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs#L252-L269)
## 详细组件分析
### 定时调度与清理流程
- rcoder 清理任务
- 使用 tokio::time::interval 控制清理间隔,每次清理前为整个清理流程设置超时上限,避免长时间阻塞。
- 清理流程包含:孤立会话清理、代理扫描与判定、容器销毁与端口释放、映射移除、生命周期守卫 Drop、统计更新。
- agent_runner 清理任务
- 同样使用 interval 驱动,但不涉及容器销毁与端口释放,直接移除映射触发 Drop。
```mermaid
flowchart TD
Start(["定时tick"]) --> Scan["扫描project_and_agent_map"]
Scan --> Filter{"Idle且超时?"}
Filter -- 否 --> NextTick["等待下次tick"]
Filter -- 是 --> Cleanup["执行清理"]
Cleanup --> RC{"rcoder场景?"}
RC -- 是 --> Stop["停止容器(runtime_cleanup)"]
Stop --> Release["释放端口"]
RC -- 否 --> Remove["移除映射(entry.remove_entry)"]
Release --> Remove
Remove --> Drop["生命周期守卫Drop自动清理"]
Drop --> Stats["更新统计/日志"]
Stats --> NextTick
```
图表来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L815)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L278-L292)
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L815)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L278-L292)
### 闲置检测与保护期
- 闲置超时判定:比较 last_activity 与当前时间,超过 idle_timeout 则视为可清理。
- 保护期策略新增最小保护时间例如容器创建后5分钟内不清理避免刚创建的容器被误清理。
- 缓冲时间:在 rcoder 版本中对 idle_timeout 添加1秒缓冲降低时间误差导致的误判。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L136-L200)
### 资源释放流程
- rcoder 场景
- 容器销毁:通过统一运行时清理接口停止容器,支持优雅停止与强制停止。
- 端口释放:若容器存在端口绑定,清理时释放对应端口。
- 映射移除:使用 DashMap 的 Entry API 原子性移除,触发生命周期守卫 Drop。
- agent_runner 场景
- 直接移除映射,生命周期守卫 Drop 自动清理子进程、stderr 任务等资源。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L643-L731)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L243-L276)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L236-L292)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L51-L59)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs#L252-L269)
### SSE 会话与孤立会话清理
- 扫描活跃会话集合,定位不在活跃映射中的会话作为“孤立会话”,清理其缓存与消息。
- 统计孤立会话数量与清理的 SSE 消息数量,便于监控与审计。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L202-L246)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L81-L154)
### 孤立容器扫描与清理rcoder
- 通过 DockerManager 列出匹配模式的容器,快速筛选 MAP 中缺失的“孤立容器”。
- 限制单次清理数量与总超时,避免阻塞主清理流程。
- 并行清理多个孤立容器,提升效率。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L602)
### 与代理停止处理器的协作
- 生命周期守卫在 Drop 时自动清理资源,确保即使清理任务未及时触发,也能回收资源。
- rcoder 场景下,清理任务优先销毁容器并释放端口,再移除映射,保证一致性。
- agent_runner 场景下,清理任务移除映射即可,守卫负责清理本地资源。
章节来源
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L236-L292)
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L643-L731)
### 超时处理与重试机制
- 整体清理超时:为一次完整的清理周期设置超时上限,超时后强制结束,避免阻塞。
- 单次清理超时:对容器销毁、孤立容器清理等关键步骤设置超时,超时后记录告警并继续后续流程。
- 重试策略:未实现显式的重试;遇到超时或错误时记录日志并继续,保证清理任务持续运行。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L815)
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L431-L453)
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L540-L599)
### 日志记录实践
- 关键节点均输出 info/warn/debug/error 日志包含项目ID、状态、耗时、清理结果等。
- 对超时、失败、保护期内跳过等情况进行明确标注,便于问题定位与审计。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L407-L419)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L214-L232)
## 依赖分析
- 清理任务依赖
- rcoderAppStateDashMap、DockerManager、PortManager、AgentLifecycleGuard。
- agent_runner全局映射PROJECT_AND_AGENT_INFO_MAP、SESSION_CACHE、PROJECT_SESSION_MAP、AgentLifecycleGuard。
- 外部依赖
- DockerManager 提供统一的容器停止接口,支持运行时清理策略。
- DashMap 提供并发安全的映射与原子性 Entry API保障清理过程的一致性。
```mermaid
graph LR
Cleanup["AgentCleaner"] --> State["AppState/DashMap"]
Cleanup --> Docker["DockerManager"]
Cleanup --> Port["PortManager"]
Cleanup --> Guard["AgentLifecycleGuard"]
Docker --> Stop["runtime_cleanup_container"]
```
图表来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L108-L113)
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L26-L36)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs#L252-L269)
章节来源
- [crates/rcoder/src/router.rs](file://crates/rcoder/src/router.rs#L26-L36)
- [crates/docker_manager/src/container_stop.rs](file://crates/docker_manager/src/container_stop.rs#L252-L269)
## 性能考虑
- 定时轮询频率
- 默认清理间隔为 5 分钟,建议结合业务负载与资源占用调整,避免过于频繁导致 CPU 唤醒开销。
- 扫描与清理复杂度
- 扫描阶段遍历映射,复杂度 O(N)rcoder 场景额外包含容器查询与并行清理,注意 Docker API 调用次数。
- 并发与超时
- 孤立容器清理采用并行任务,限制单次清理数量,避免阻塞主流程;整体清理设置超时上限,保证稳定性。
- 端口与容器资源
- 端口释放与容器停止均设置超时,防止长时间阻塞;建议监控清理耗时与失败率,及时调整超时参数。
[本节为通用性能讨论,不直接分析具体文件]
## 故障排查指南
- 清理任务未生效
- 检查定时器是否启动、清理间隔是否合理、日志中是否有“定时清理完成/失败/超时”记录。
- 容器未被清理
- rcoder 场景确认容器停止接口是否成功、端口是否释放、映射是否移除;查看超时与错误日志。
- 代理资源未回收
- 确认生命周期守卫 Drop 是否触发;检查映射移除是否成功;核对本地进程资源清理日志。
- 端口泄漏
- 检查容器销毁后是否调用端口释放;核对端口管理器释放日志。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L787-L815)
- [crates/rcoder/src/proxy_agent/port_manager.rs](file://crates/rcoder/src/proxy_agent/port_manager.rs#L51-L59)
- [crates/agent_runner/src/proxy_agent/agent_stop_handle.rs](file://crates/agent_runner/src/proxy_agent/agent_stop_handle.rs#L236-L292)
## 结论
清理任务通过“定时轮询 + RAII 回收”的设计在代理终止后可靠地回收容器、端口与会话等资源。rcoder 场景提供了更完善的超时控制、孤立容器扫描与端口释放能力agent_runner 场景则通过映射移除触发生命周期守卫 Drop实现轻量级资源回收。结合合理的配置与监控可在保证稳定性的同时最大化资源利用率。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 配置选项说明
- rcoder 清理配置 CleanupConfig
- idle_timeout代理闲置超时时间默认 30 分钟。
- cleanup_interval清理检查间隔默认 5 分钟。
- docker_stop_timeoutDocker 容器停止超时,默认 30 秒。
- agent_runner 清理配置 CleanupConfig
- idle_timeout代理闲置超时时间默认 30 分钟。
- cleanup_interval清理检查间隔默认 5 分钟。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L67-L89)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L18-L36)
### 启动与集成
- rcoder 启动清理任务
- 通过 start_cleanup_task(config, state) 启动,传入 AppState 与 CleanupConfig。
- agent_runner 启动清理任务
- 通过 start_cleanup_task(config) 启动,传入 CleanupConfig。
章节来源
- [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L823-L835)
- [crates/agent_runner/src/proxy_agent/cleanup_task.rs](file://crates/agent_runner/src/proxy_agent/cleanup_task.rs#L300-L310)

View File

@@ -0,0 +1,360 @@
# 通道工具
<cite>
**本文引用的文件**
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性地介绍代理运行器中“通道工具”channel_utils模块提供的异步通信能力重点说明其如何简化 Tokio 通道的使用,包括通道创建、消息转发、状态更新与错误处理等辅助函数。文档还解释了在代理运行器中各组件间通信的应用场景,如命令传递、状态更新和结果返回,并给出设计理念、性能特征与使用注意事项,以及典型使用模式的路径指引。
## 项目结构
通道工具位于代理运行器的代理层,围绕 ACP 协议的客户端连接与会话管理展开,配合全局会话缓存与通知广播,形成“命令通道 + 数据通道”的双通道通信体系。
```mermaid
graph TB
subgraph "代理层"
CU["channel_utils<br/>通用通道处理工具"]
MOD["proxy_agent/mod.rs<br/>会话上下文与通知入口"]
AS["agent_service.rs<br/>代理服务抽象"]
CA["claude_code_agent.rs<br/>Claude代理启动"]
CO["codex_agent.rs<br/>Codex代理启动"]
end
subgraph "服务层"
SC["service/session_cache.rs<br/>会话缓存与推送"]
end
subgraph "共享类型"
AM["shared_types/agent_model.rs<br/>模型与生命周期"]
AN["shared_types/agent_session_notify.rs<br/>统一通知模型"]
AE["shared_types/app_error.rs<br/>错误类型"]
end
CA --> CU
CO --> CU
CU --> SC
MOD --> SC
SC --> AN
AM --> CU
AE --> SC
```
图表来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L1-L256)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65)
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
## 核心组件
- 通用通道处理工具channel_utils
- 提供两类可复用的任务:取消处理任务与提示处理任务,分别封装对 Agent 的 cancel 与 prompt 调用、状态更新与通知广播。
- 设计要点:超时保护、状态机切换、请求上下文透传、错误链路闭环。
- 会话级上下文与通知入口proxy_agent/mod.rs
- 维护会话级 request_id 上下文映射,支持 session_notification 回调中获取 request_id。
- 实现 ACP 客户端的 session_notification将 Agent 的会话更新转换为统一通知并推送。
- 会话缓存与推送service/session_cache.rs
- 全局会话缓存、项目-会话映射、环形缓冲区与实时推送,提供 push_session_update 与 push_session_update_with_project 两个便捷函数。
- 代理服务抽象agent_service.rs
- 定义 AcpAgentService trait统一启动流程与代理类型名。
- 代理启动与通道绑定claude_code_agent.rs、codex_agent.rs
- 启动子进程/代理实例,创建 unbounded channel 用于取消与提示,绑定到通用通道处理工具。
- 共享模型与错误shared_types
- 统一的 Agent 状态、生命周期、通知模型与错误类型,保证跨模块一致性。
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L1-L256)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65)
## 架构总览
通道工具在代理运行器中的作用是“桥接外部命令与内部 Agent 执行”,并通过统一的通知模型将状态与结果广播给前端或上层服务。
```mermaid
sequenceDiagram
participant RC as "rcoder/上层"
participant AG as "代理启动器<br/>claude_code_agent.rs/codex_agent.rs"
participant CH as "通道工具<br/>channel_utils.rs"
participant AC as "Agent 客户端连接"
participant SV as "会话缓存<br/>session_cache.rs"
participant FE as "前端/订阅者"
RC->>AG : 发送取消/提示命令
AG->>CH : 通过 unbounded channel 分发
CH->>AC : 调用 cancel/prompt
AC-->>CH : 返回执行结果/错误
CH->>SV : 推送 SessionPromptStart/End/Error
SV-->>FE : 通过 SSE 广播统一通知
CH->>CH : 更新 Agent 状态Active/Idle
```
图表来源
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L232-L278)
## 详细组件分析
### 通用通道处理工具channel_utils
- 功能概览
- 取消处理任务:接收取消通知,调用 Agent.cancel带超时保护发送响应并恢复 Agent 状态。
- 提示处理任务:接收提示请求,校验/修正会话 ID提取 request_id更新 Agent 状态,发送开始通知,执行 prompt按成功/失败路径发送结束通知并恢复状态。
- 设计理念
- 超时保护:对 Agent.cancel 加入固定超时,避免阻塞通道处理。
- 状态机:在处理前后维护 Agent 状态Active/Idle确保状态与实际执行一致。
- 请求上下文:从 PromptRequest.meta 提取 request_id 并写入会话级上下文,便于后续通知携带。
- 通知闭环:无论成功或失败,均发送 SessionPromptEnd确保会话结束语义明确。
- 性能特征
- 使用 unbounded channel 降低背压压力,适合高吞吐的提示处理。
- 通过 tokio::task::spawn_local 在本地任务集中运行,减少跨线程调度开销。
- 通知广播通过统一模型与会话缓存,避免重复序列化与多路分发。
- 使用注意事项
- 会话 ID 不一致时会强制覆盖为目标会话,确保消息路由正确。
- request_id 为空时不会影响整体流程,但可能影响前端关联。
- 错误路径会同时发送 SessionPromptError 与 SessionPromptEnd确保前端能感知错误并结束会话。
```mermaid
flowchart TD
Start(["进入提示处理任务"]) --> CheckSID["校验/修正 session_id"]
CheckSID --> ExtractRID["从 meta 提取 request_id"]
ExtractRID --> UpdateStatus["更新 Agent 状态为 Active"]
UpdateStatus --> SaveCtx["写入会话级上下文project_id->request_id"]
SaveCtx --> NotifyStart["发送 SessionPromptStart"]
NotifyStart --> CallPrompt["调用 Agent.prompt()"]
CallPrompt --> Ok{"执行成功?"}
Ok --> |是| NotifyEnd["发送 SessionPromptEndstop_reason"]
Ok --> |否| NotifyErr["发送 SessionPromptError含 code/message"]
NotifyErr --> NotifyEnd2["发送 SessionPromptEndCancelled"]
NotifyEnd --> ResetStatus["恢复 Agent 状态为 Idle"]
NotifyEnd2 --> ResetStatus
ResetStatus --> End(["任务继续监听新消息"])
```
图表来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L92-L229)
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
### 会话级上下文与通知入口proxy_agent/mod.rs
- 功能概览
- 维护会话级 request_id 上下文映射project_id -> request_id避免锁竞争。
- 实现 ACP 客户端的 session_notification优先从 meta 获取 request_id否则通过 session_id 查找 project_id 再从上下文获取,最终将 AgentSessionUpdate 转换为统一通知并推送。
- 设计理念
- 以 project_id 为键的上下文映射,确保同一项目多次请求自动覆盖为最新值,避免过期 request_id 影响。
- 通知转换严格遵循统一模型,保证前端消费一致性。
- 使用注意事项
- 若 meta 与上下文均无 request_id通知仍会成功推送但前端可能缺少请求关联信息。
章节来源
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L1-L256)
### 会话缓存与推送service/session_cache.rs
- 功能概览
- 全局会话缓存DashMap按 session_id 分组,使用环形缓冲区保存最近消息,实时推送至当前连接。
- 提供 push_session_update 与 push_session_update_with_project 两个便捷函数,后者自动处理项目-会话映射变更并清理旧数据。
- SessionWorker 通过命令通道管理推送、清理与统计。
- 设计理念
- 极简优化:直接共享当前连接状态,避免命令传递带来的额外复杂度。
- 心跳与实时推送:心跳消息单独处理,避免缓冲区占用。
- 会话映射一致性ensure_project_session 在 session_id 变更时清理旧数据并更新映射,避免脏数据污染。
- 使用注意事项
- 当前连接关闭时会显式 drop 发送端,接收端 recv() 立即返回 None确保及时感知断开。
- 清理旧会话数据时会移除缓存条目,注意不要在清理后继续向旧会话推送。
```mermaid
classDiagram
class SessionData {
+command_tx
+current_sender
+current_cancel
+create_new_connection(buffer_size)
+push_message(message)
+close_current_connection()
}
class SessionWorker {
+max_size
+command_rx
+current_sender
+current_cancel
+run()
}
class SessionCache {
+push_session_update(session_id, notify)
+push_session_update_with_project(project_id, session_id, notify)
+ensure_project_session(project_id, session_id)
}
SessionData --> SessionWorker : "spawn"
SessionCache --> SessionData : "管理"
```
图表来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
章节来源
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
### 代理服务抽象与启动agent_service.rs、claude_code_agent.rs、codex_agent.rs
- 功能概览
- AcpAgentService 抽象统一启动流程,不同代理类型通过其实现启动。
- 启动时创建取消与提示通道,绑定到通用通道处理工具,启动后等待取消信号。
- 设计理念
- 通过 trait 解耦代理类型,统一生命周期管理。
- 通道绑定与任务分离,便于扩展与维护。
- 使用注意事项
- 通道使用 unbounded channel注意避免无限增长导致内存压力。
- 取消信号通过 CancellationToken 传播,确保子进程/连接正确退出。
章节来源
- [agent_service.rs](file://crates/agent_runner/src/proxy_agent/agent_service.rs#L1-L62)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
### 统一通知模型与错误类型shared_types
- 功能概览
- 统一通知模型SessionNotify与统一消息UnifiedSessionMessage支持多种消息类型与子类型。
- 错误类型AppError统一错误表示支持从 tokio mpsc SendError 转换。
- 设计理念
- 前后端一致的事件模型,便于前端消费与状态机驱动。
- 错误结构保留 code 与 message便于前端展示与诊断。
- 使用注意事项
- 错误路径中 data 直接包含 code 与 message前端无需二次解析。
章节来源
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
- [app_error.rs](file://crates/shared_types/src/model/app_error.rs#L1-L65)
## 依赖分析
- 组件耦合
- channel_utils 依赖代理运行器的全局映射(项目-代理信息)与会话缓存推送函数。
- proxy_agent/mod.rs 依赖 shared_types 的通知模型与会话缓存推送函数。
- 代理启动器claude_code_agent.rs、codex_agent.rs依赖 channel_utils 与 ACP 客户端连接。
- 外部依赖
- tokio mpsc、dashmap、ringbuf、tokio-util CancellationToken 等。
- 循环依赖
- 通过模块拆分与函数边界清晰,未发现循环依赖迹象。
```mermaid
graph LR
CU["channel_utils.rs"] --> SC["service/session_cache.rs"]
CU --> AM["shared_types/agent_model.rs"]
MOD["proxy_agent/mod.rs"] --> SC
MOD --> AN["shared_types/agent_session_notify.rs"]
CA["claude_code_agent.rs"] --> CU
CO["codex_agent.rs"] --> CU
SC --> AN
AM --> CU
```
图表来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L1-L256)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L1-L230)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L1-L256)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L1-L355)
- [claude_code_agent.rs](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- [codex_agent.rs](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- [agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L1-L483)
- [agent_session_notify.rs](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
## 性能考量
- 通道选择
- 提示处理使用 unbounded channel降低背压适合高并发提示场景。
- 取消处理使用 unbounded channel结合超时保护避免阻塞。
- 状态与上下文
- 使用 DashMap 与 LazyLock 保证全局状态访问的低锁争用。
- 会话级上下文使用 project_id 作为键,避免锁竞争。
- 缓冲与推送
- 环形缓冲区限制内存占用,实时推送失败时自动降级为丢弃旧数据。
- 心跳消息不计入缓冲,避免阻塞。
- 生命周期
- CancellationToken 与显式 drop 发送端,确保连接断开的确定性与及时性。
[本节为通用性能讨论,不直接分析具体文件]
## 故障排查指南
- 取消超时
- 现象:取消请求响应为超时。
- 排查:确认 Agent.cancel 是否阻塞,检查超时阈值与网络状况。
- 参考路径:[取消处理任务](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L18-L89)
- 提示失败
- 现象:提示执行失败,前端收到错误通知。
- 排查:检查 Agent.prompt 返回的错误结构,确认错误消息是否包含 code 与 message。
- 参考路径:[提示处理任务错误分支](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L190-L224)
- 通知未到达
- 现象:前端未收到 SessionPromptStart/End/Error。
- 排查:确认 push_session_update_with_project 是否正确更新项目-会话映射;检查 SessionData 是否仍在运行。
- 参考路径:[会话缓存推送](file://crates/agent_runner/src/service/session_cache.rs#L232-L278)
- request_id 缺失
- 现象:前端无法关联请求。
- 排查:确认 PromptRequest.meta 是否包含 request_id若缺失检查 session_notification 是否能通过 project_id 从上下文获取。
- 参考路径:[会话通知入口](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L209)
章节来源
- [channel_utils.rs](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L18-L224)
- [session_cache.rs](file://crates/agent_runner/src/service/session_cache.rs#L232-L278)
- [mod.rs](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L209)
## 结论
通道工具通过“取消处理任务 + 提示处理任务”的双通道模式,将外部命令与内部 Agent 执行解耦,配合统一通知模型与会话缓存,实现了高效、稳定且可扩展的异步通信。其设计理念强调超时保护、状态机一致性与上下文透传,既满足高并发场景下的性能需求,又保证了错误路径的可观测性与前端体验的一致性。
[本节为总结性内容,不直接分析具体文件]
## 附录
### 典型使用模式(路径指引)
- 启动代理并绑定通道
- Claude 代理:[启动流程与通道绑定](file://crates/agent_runner/src/proxy_agent/claude_code_agent.rs#L1-L311)
- Codex 代理:[启动流程与通道绑定](file://crates/agent_runner/src/proxy_agent/codex_agent.rs#L294-L318)
- 取消处理任务
- [通用取消处理函数](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L18-L89)
- 提示处理任务
- [通用提示处理函数](file://crates/agent_runner/src/proxy_agent/channel_utils.rs#L92-L229)
- 会话通知入口
- [session_notification 实现](file://crates/agent_runner/src/proxy_agent/mod.rs#L149-L209)
- 会话缓存与推送
- [统一推送函数](file://crates/agent_runner/src/service/session_cache.rs#L232-L278)
- [项目-会话映射更新](file://crates/agent_runner/src/service/session_cache.rs#L282-L354)
- 统一通知模型
- [通知转统一消息](file://crates/shared_types/src/model/agent_session_notify.rs#L82-L163)
- 错误类型
- [AppError 定义与转换](file://crates/shared_types/src/model/app_error.rs#L1-L65)