# 代理状态查询接口 **本文引用的文件列表** - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs) - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs) - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs) - [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs) - [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考量](#性能考量) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文档面向 RCoder 项目的“代理状态查询”API,聚焦 GET /agent/status/{project_id} 端点,系统性说明其 HTTP 方法、路径参数、响应格式与数据模型,并深入解释条件序列化机制(仅当代理存活时才包含详细字段)。同时提供成功响应示例(含代理运行中与未运行两种状态),并阐述该接口在客户端 UI 展示与自动化监控系统中的典型使用场景与集成方式。 ## 项目结构 该接口位于两个模块中均有实现,分别服务于不同的运行形态: - agent_runner 模块:基于 ACP 代理的实现,使用全局 DashMap 存储项目与代理信息。 - rcoder 模块:基于容器化 Agent 的实现,使用 AppState 中的项目到代理映射。 二者共享同一 AgentStatusResponse 数据模型与统一的 HTTP 包装格式。 ```mermaid graph TB subgraph "API层" Router["路由注册
/agent/status/{project_id}"] HandlerAR["agent_runner 状态处理器"] HandlerRC["rcoder 状态处理器"] end subgraph "数据模型" ModelResp["AgentStatusResponse"] ModelProv["ModelProviderSafeInfo"] HttpWrap["HttpResult"] end subgraph "状态存储" MapAR["PROJECT_AND_AGENT_INFO_MAP
DashMap"] AppStateRC["AppState.project_and_agent_map"] end Router --> HandlerAR Router --> HandlerRC HandlerAR --> MapAR HandlerRC --> AppStateRC HandlerAR --> ModelResp HandlerRC --> ModelResp ModelResp --> ModelProv HandlerAR --> HttpWrap HandlerRC --> HttpWrap ``` 图表来源 - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L70) - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L70-L122) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L72-L132) - [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L22-L25) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L116-L132) - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) 章节来源 - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L70) ## 核心组件 - HTTP 端点:GET /agent/status/{project_id} - 路由注册:在 agent_runner 模块中通过路由工厂注册 - 处理器: - agent_runner:从全局 DashMap 读取项目代理信息 - rcoder:从 AppState 中的项目到代理映射读取 - 数据模型:AgentStatusResponse(包含项目ID、存活标志、会话ID、状态、最后活动时间、创建时间、模型提供商安全信息) - 条件序列化:仅当 is_alive 为 true 时,序列化 session_id、status、last_activity、created_at、model_provider - HTTP 包装:统一返回 HttpResult 结构,包含 code、message、data、tid、success 字段 章节来源 - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L70-L122) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L72-L132) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) ## 架构总览 下图展示从客户端到处理器、再到状态存储与响应封装的整体调用链路。 ```mermaid sequenceDiagram participant Client as "客户端" participant Router as "Axum 路由" participant Handler as "AgentStatus 处理器" participant Store as "状态存储" participant Model as "AgentStatusResponse" participant Wrap as "HttpResult 包装" Client->>Router : "GET /agent/status/{project_id}" Router->>Handler : "Path(project_id)" Handler->>Handler : "校验 project_id" alt "存在代理" Handler->>Store : "查询项目代理信息" Store-->>Handler : "ProjectAndAgentInfo" Handler->>Model : "构造 AgentStatusResponseis_alive=true" Handler->>Wrap : "封装为 HttpResult.success" Wrap-->>Client : "200 OK JSON" else "不存在代理" Handler->>Model : "构造 AgentStatusResponseis_alive=false" Handler->>Wrap : "封装为 HttpResult.success" Wrap-->>Client : "200 OK JSON" end ``` 图表来源 - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L70) - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L70-L122) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L72-L132) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) ## 详细组件分析 ### 端点定义与路由 - 方法:GET - 路径:/agent/status/{project_id} - 路由注册位置:在 agent_runner 模块的路由工厂中注册 - OpenAPI 注解:包含参数说明、响应示例与标签 章节来源 - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L70) - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L11-L69) ### 处理器逻辑(agent_runner) - 输入校验:去除空白字符,若为空则返回参数错误 - 查询逻辑:从全局 DashMap 中按 project_id 获取代理信息 - 成功分支:构造完整 AgentStatusResponse(包含 session_id、status、last_activity、created_at、model_provider) - 失败分支:构造简化 AgentStatusResponse(仅 project_id、is_alive=false) 章节来源 - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L70-L122) - [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L22-L25) ### 处理器逻辑(rcoder) - 输入校验:同上 - 查询逻辑:从 AppState.project_and_agent_map 获取代理信息 - 成功分支:构造完整 AgentStatusResponse - 失败分支:构造简化 AgentStatusResponse 章节来源 - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L72-L132) - [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L661-L680) ### 数据模型:AgentStatusResponse - 字段说明: - project_id:项目ID - is_alive:代理是否存活 - session_id:会话ID(仅当 is_alive 为 true 时存在) - status:代理服务状态(仅当 is_alive 为 true 时存在) - last_activity:最后活动时间(仅当 is_alive 为 true 时存在) - created_at:创建时间(仅当 is_alive 为 true 时存在) - model_provider:模型提供商安全信息(仅当 is_alive 为 true 时存在) - 条件序列化:使用 serde 的 skip_serializing_if 仅在 Option 非空时序列化对应字段 ```mermaid classDiagram class AgentStatusResponse { +string project_id +bool is_alive +string? session_id +AgentStatus? status +DateTime? last_activity +DateTime? created_at +ModelProviderSafeInfo? model_provider } class ModelProviderSafeInfo { +string id +string name +ModelApiProtocol api_protocol +string default_model } class ModelApiProtocol { <> +Anthropic +OpenAI } AgentStatusResponse --> ModelProviderSafeInfo : "可选关联" ``` 图表来源 - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L116-L132) 章节来源 - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L116-L132) ### 条件序列化机制 - 仅当 is_alive 为 true 时,才会序列化 session_id、status、last_activity、created_at、model_provider - 该机制通过 serde 的 skip_serializing_if 实现,避免在代理未运行时返回冗余字段 章节来源 - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) ### HTTP 包装与响应格式 - 统一包装:HttpResult,包含 code、message、data、tid、success - 成功响应:success=true,data 为 AgentStatusResponse - 失败响应:success=false,data=null,error 包含错误码与消息 章节来源 - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) ### 状态存储与生命周期 - agent_runner:使用全局 DashMap 存储 ProjectAndAgentInfo,键为 project_id - rcoder:使用 AppState.project_and_agent_map 存储代理信息 - 清理任务:在 Agent 生命周期结束时,原子性移除映射项,触发生命周期守卫 Drop,完成资源清理 章节来源 - [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L22-L25) - [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L661-L680) ## 依赖关系分析 - 路由到处理器:路由注册将 GET /agent/status/{project_id} 绑定到处理器函数 - 处理器到存储:处理器从全局 DashMap 或 AppState 中查询项目代理信息 - 处理器到模型:构造 AgentStatusResponse 并通过 HttpResult 包装 - 模型到外部:AgentStatusResponse 依赖 ModelProviderSafeInfo,后者来自 ModelProviderConfig 的安全信息转换 ```mermaid graph LR Router["router.rs"] --> HandlerAR["agent_status_handler.rs (agent_runner)"] Router --> HandlerRC["agent_status_handler.rs (rcoder)"] HandlerAR --> Map["PROJECT_AND_AGENT_INFO_MAP"] HandlerRC --> AppState["AppState.project_and_agent_map"] HandlerAR --> Model["AgentStatusResponse"] HandlerRC --> Model Model --> SafeInfo["ModelProviderSafeInfo"] ``` 图表来源 - [crates/agent_runner/src/router.rs](file://crates/agent_runner/src/router.rs#L40-L70) - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L70-L122) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L72-L132) - [crates/agent_runner/src/proxy_agent/acp_agent.rs](file://crates/agent_runner/src/proxy_agent/acp_agent.rs#L22-L25) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L116-L132) ## 性能考量 - 查询复杂度:DashMap 的读取为 O(1) 平均复杂度,适合高频状态查询 - 序列化开销:条件序列化避免在代理未运行时序列化冗余字段,降低响应体积 - 并发安全:DashMap 提供无锁读取能力,减少锁竞争 - 日志与追踪:处理器记录请求与结果,便于定位问题与性能分析 ## 故障排查指南 - 参数错误:当 project_id 为空时,返回 INVALID_PARAMS 错误 - 代理不存在:返回 is_alive=false 的简化响应 - 代理清理:确认清理任务是否正确移除映射项,避免脏读 - 模型提供商安全信息:确认 to_safe_info 转换是否成功,避免敏感信息泄露 章节来源 - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L75-L84) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L79-L84) - [crates/rcoder/src/proxy_agent/cleanup_task.rs](file://crates/rcoder/src/proxy_agent/cleanup_task.rs#L661-L680) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L79-L88) ## 结论 GET /agent/status/{project_id} 接口以简洁稳定的响应模型提供了代理状态查询能力。通过条件序列化与统一的 HTTP 包装,既能满足客户端 UI 的直观展示需求,也能为自动化监控系统提供一致的数据格式。在 agent_runner 与 rcoder 两套实现中,接口语义保持一致,便于跨形态部署与迁移。 ## 附录 ### 接口规范摘要 - 方法:GET - 路径:/agent/status/{project_id} - 路径参数: - project_id:string,必填,项目ID - 成功响应(200 OK): - data:AgentStatusResponse - success:true - 失败响应(400): - error:包含错误码与消息 - success:false 章节来源 - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L11-L69) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L13-L67) - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) ### 响应示例(JSON) - 代理运行中(is_alive=true) - data 字段包含:project_id、is_alive、session_id、status、last_activity、created_at、model_provider - 代理未运行(is_alive=false) - data 字段包含:project_id、is_alive(false),其余字段省略 章节来源 - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L21-L49) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L21-L51) ### 数据模型字段详解 - project_id:string,项目标识 - is_alive:bool,代理是否存活 - session_id:string,会话ID(仅存活时存在) - status:枚举,代理状态(Active/Idle/Terminating,仅存活时存在) - last_activity:时间戳,最后活动时间(仅存活时存在) - created_at:时间戳,创建时间(仅存活时存在) - model_provider:对象,模型提供商安全信息(仅存活时存在) 章节来源 - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L32-L41) - [crates/shared_types/src/model/agent_model.rs](file://crates/shared_types/src/model/agent_model.rs#L70-L97) - [crates/shared_types/src/model/model_provider.rs](file://crates/shared_types/src/model/model_provider.rs#L116-L132) ### 使用场景与集成建议 - 客户端 UI: - 轮询查询 /agent/status/{project_id},根据 is_alive 控制按钮可用性与状态提示 - 若 is_alive=true,显示 session_id、status、last_activity 等细节,帮助用户了解代理运行状况 - 自动化监控: - 以 is_alive 作为健康指标,结合 last_activity 判断代理是否处于僵尸状态 - 将 model_provider 信息纳入监控面板,便于追踪模型提供商与默认模型 - 错误处理: - 对 400 参数错误进行明确提示,引导用户修正 project_id - 对 5xx 内部错误通过 HttpResult.error 的 code 与 message 进行统一处理 章节来源 - [crates/shared_types/src/model/http_result.rs](file://crates/shared_types/src/model/http_result.rs#L24-L103) - [crates/agent_runner/src/handler/agent_status_handler.rs](file://crates/agent_runner/src/handler/agent_status_handler.rs#L75-L84) - [crates/rcoder/src/handler/agent_status_handler.rs](file://crates/rcoder/src/handler/agent_status_handler.rs#L79-L84)