16 KiB
16 KiB
代理状态查询接口
**本文引用的文件列表** - [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)目录
简介
本文档面向 RCoder 项目的“代理状态查询”API,聚焦 GET /agent/status/{project_id} 端点,系统性说明其 HTTP 方法、路径参数、响应格式与数据模型,并深入解释条件序列化机制(仅当代理存活时才包含详细字段)。同时提供成功响应示例(含代理运行中与未运行两种状态),并阐述该接口在客户端 UI 展示与自动化监控系统中的典型使用场景与集成方式。
项目结构
该接口位于两个模块中均有实现,分别服务于不同的运行形态:
- agent_runner 模块:基于 ACP 代理的实现,使用全局 DashMap 存储项目与代理信息。
- rcoder 模块:基于容器化 Agent 的实现,使用 AppState 中的项目到代理映射。
二者共享同一 AgentStatusResponse 数据模型与统一的 HTTP 包装格式。
graph TB
subgraph "API层"
Router["路由注册<br/>/agent/status/{project_id}"]
HandlerAR["agent_runner 状态处理器"]
HandlerRC["rcoder 状态处理器"]
end
subgraph "数据模型"
ModelResp["AgentStatusResponse"]
ModelProv["ModelProviderSafeInfo"]
HttpWrap["HttpResult<T>"]
end
subgraph "状态存储"
MapAR["PROJECT_AND_AGENT_INFO_MAP<br/>DashMap<String, ProjectAndAgentInfo>"]
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
- crates/agent_runner/src/handler/agent_status_handler.rs
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/agent_runner/src/proxy_agent/acp_agent.rs
- crates/shared_types/src/model/agent_model.rs
- crates/shared_types/src/model/model_provider.rs
- crates/shared_types/src/model/http_result.rs
章节来源
核心组件
- 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
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/shared_types/src/model/agent_model.rs
- crates/shared_types/src/model/http_result.rs
架构总览
下图展示从客户端到处理器、再到状态存储与响应封装的整体调用链路。
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
- crates/agent_runner/src/handler/agent_status_handler.rs
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/shared_types/src/model/agent_model.rs
- crates/shared_types/src/model/http_result.rs
详细组件分析
端点定义与路由
- 方法:GET
- 路径:/agent/status/{project_id}
- 路由注册位置:在 agent_runner 模块的路由工厂中注册
- OpenAPI 注解:包含参数说明、响应示例与标签
章节来源
处理器逻辑(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
- crates/agent_runner/src/proxy_agent/acp_agent.rs
处理器逻辑(rcoder)
- 输入校验:同上
- 查询逻辑:从 AppState.project_and_agent_map 获取代理信息
- 成功分支:构造完整 AgentStatusResponse
- 失败分支:构造简化 AgentStatusResponse
章节来源
数据模型: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 非空时序列化对应字段
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 {
<<enum>>
+Anthropic
+OpenAI
}
AgentStatusResponse --> ModelProviderSafeInfo : "可选关联"
图表来源
章节来源
条件序列化机制
- 仅当 is_alive 为 true 时,才会序列化 session_id、status、last_activity、created_at、model_provider
- 该机制通过 serde 的 skip_serializing_if 实现,避免在代理未运行时返回冗余字段
章节来源
HTTP 包装与响应格式
- 统一包装:HttpResult,包含 code、message、data、tid、success
- 成功响应:success=true,data 为 AgentStatusResponse
- 失败响应:success=false,data=null,error 包含错误码与消息
章节来源
状态存储与生命周期
- agent_runner:使用全局 DashMap 存储 ProjectAndAgentInfo,键为 project_id
- rcoder:使用 AppState.project_and_agent_map 存储代理信息
- 清理任务:在 Agent 生命周期结束时,原子性移除映射项,触发生命周期守卫 Drop,完成资源清理
章节来源
依赖关系分析
- 路由到处理器:路由注册将 GET /agent/status/{project_id} 绑定到处理器函数
- 处理器到存储:处理器从全局 DashMap 或 AppState 中查询项目代理信息
- 处理器到模型:构造 AgentStatusResponse 并通过 HttpResult 包装
- 模型到外部:AgentStatusResponse 依赖 ModelProviderSafeInfo,后者来自 ModelProviderConfig 的安全信息转换
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
- crates/agent_runner/src/handler/agent_status_handler.rs
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/agent_runner/src/proxy_agent/acp_agent.rs
- crates/shared_types/src/model/agent_model.rs
- crates/shared_types/src/model/model_provider.rs
性能考量
- 查询复杂度:DashMap 的读取为 O(1) 平均复杂度,适合高频状态查询
- 序列化开销:条件序列化避免在代理未运行时序列化冗余字段,降低响应体积
- 并发安全:DashMap 提供无锁读取能力,减少锁竞争
- 日志与追踪:处理器记录请求与结果,便于定位问题与性能分析
故障排查指南
- 参数错误:当 project_id 为空时,返回 INVALID_PARAMS 错误
- 代理不存在:返回 is_alive=false 的简化响应
- 代理清理:确认清理任务是否正确移除映射项,避免脏读
- 模型提供商安全信息:确认 to_safe_info 转换是否成功,避免敏感信息泄露
章节来源
- crates/agent_runner/src/handler/agent_status_handler.rs
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/rcoder/src/proxy_agent/cleanup_task.rs
- crates/shared_types/src/model/model_provider.rs
结论
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
- crates/rcoder/src/handler/agent_status_handler.rs
- crates/shared_types/src/model/http_result.rs
响应示例(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
- crates/rcoder/src/handler/agent_status_handler.rs
数据模型字段详解
- 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
- crates/shared_types/src/model/agent_model.rs
- crates/shared_types/src/model/model_provider.rs
使用场景与集成建议
- 客户端 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 进行统一处理
章节来源