添加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

360
qiming-rcoder/CLAUDE.md Normal file
View File

@@ -0,0 +1,360 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## 项目概述
RCoder 是一个基于 ACP (Agent Client Protocol) 的 AI 驱动开发平台,使用 Rust 构建。该项目采用微服务架构,集成了 Docker 容器化部署、高性能反向代理和多种 AI 代理支持。
## 核心架构
### 工作空间结构
- **Workspace**: 使用 Cargo workspace 管理多个 crate
- **主要 crate**: `rcoder` (主应用), `agent_runner` (代理运行时), `shared_types` (共享类型), `docker_manager` (容器管理), `pingora-proxy` (反向代理)
### 容器化架构设计
项目采用动态容器化架构,每个项目对应一个独立的 Docker 容器:
- **RCoder 主服务**: HTTP API 服务 + 容器管理 + gRPC 客户端
- **Agent Runner 容器**: 每个项目独立的 AI 代理运行环境 + gRPC 服务器
- **Pingora 代理**: 高性能反向代理服务,支持端口路由
### 通信架构gRPC
RCoder 和 Agent Runner 之间使用 **gRPC** 进行内部通信,提供类型安全和高性能:
```
外部客户端 (HTTP/SSE)
RCoder (HTTP API Server)
↓ gRPC (Chat, CancelSession, SubscribeProgress)
Agent Runner (gRPC Server in Docker)
↓ Server Streaming (实时进度事件)
RCoder (转换为 SSE)
外部客户端 (SSE)
```
**核心 RPC 方法**
- `Chat`: 发送聊天请求到 agent_runner
- `SubscribeProgress`: Server Streaming实时推送进度事件
- `CancelSession`: 取消正在执行的会话
- `GetStatus`: 查询 Agent 状态
**Proto 定义位置**: `crates/shared_types/proto/agent.proto`
### 核心组件
- **DockerManager**: 全局容器管理器,负责容器生命周期
- **ContainerManager**: 项目级别的容器创建和管理
- **ProxyAgentManager**: ACP 代理管理器,处理代理生命周期
- **AppState**: 应用状态管理,使用 DashMap 进行并发访问
- **GrpcChannelPool**: gRPC 连接池,基于 DashMap 实现高效连接复用
- **AgentServiceImpl**: agent_runner 的 gRPC 服务实现
## 开发命令
### 基础构建和运行
```bash
# 构建所有 crates
cargo build --release
# 运行主服务 (默认端口 8087)
cargo run --bin rcoder
# 运行特定端口
cargo run --bin rcoder -- --port 8080 --enable-proxy
# 使用 Makefile (推荐)
make build # 本地编译
make install # 安装到 ~/.cargo/bin
make dev-build # Docker 镜像构建
make dev-up # 启动开发容器
```
### 开发环境命令
```bash
# 启动开发模式容器
make dev-build # 首次:构建 Docker 镜像
make dev-up # 启动容器
make dev-restart # 代码修改后重启容器
# 查看容器日志
make dev-logs
# 停止开发容器
make dev-down
```
### 测试和质量检查
```bash
# 运行所有测试
cargo test
# 运行特定 crate 测试
cargo test -p rcoder
cargo test -p docker_manager
# 代码质量
cargo fmt # 格式化代码
cargo clippy # 代码检查
cargo tree # 查看依赖树
```
### Docker 开发命令
```bash
# 构建 Docker 镜像
make docker-build
# 完整开发流程 (推荐)
make dev-build && make dev-up
# 更新镜像标签
make update-image-tag
```
## 重要技术细节
### gRPC 通信架构
- 使用 **Tonic 0.14.2** 实现 gRPC 服务端和客户端
- Proto 文件使用 **Protobuf oneof** 实现类型安全的事件系统,完全消除 JSON 序列化
- **GrpcChannelPool** 基于 DashMap 提供高效的连接复用
- **Server Streaming** 用于实时推送进度事件(替代轮询)
- **HTTP 回退机制**gRPC 失败时自动回退到 HTTP兼容性保障
- gRPC 默认端口:`50051`(定义在 `shared_types::GRPC_DEFAULT_PORT`
**关键文件**
- `crates/shared_types/proto/agent.proto` - Proto 定义
- `crates/rcoder/src/grpc/channel_pool.rs` - 连接池
- `crates/rcoder/src/grpc/chat_client.rs` - gRPC 客户端
- `crates/agent_runner/src/grpc/agent_service_impl.rs` - gRPC 服务实现
### ACP 协议集成
- 使用 `agent-client-protocol = "0.6"``agent_client_protocol = "0.4"` 实现多版本兼容
- AgentSideConnection 和 ClientSideConnection **未实现 Send trait**
- **必须**在 LocalSet 和 spawn_local 中使用这些连接
- 参考示例目录: `/Volumes/soddy/git_workspace/rcoder/tmp/agent-client-protocol/rust/examples`
### 并发模型和状态管理
- 使用 **DashMap** 替代 `Arc<RwLock<HashMap>>` 以获得更好的性能
- 使用写时复制 (CoW) 模式进行状态更新
- 主应用使用 `#[tokio::main(flavor = "current_thread")]`
- ACP 操作必须在 `LocalSet` 中执行以支持 `spawn_local`
### Docker 容器动态创建
- **多级隔离架构**: 支持三种隔离级别
- `project` (默认): 每个项目对应一个独立的 Docker 容器
- `tenant`: 租户级隔离,同一租户共享容器
- `space`: 空间级隔离,同一空间共享容器
- **容器复用**: 通过 `pod_id` 字段实现跨用户容器复用
- **自动架构检测**: 根据 OS 和 ARCH 自动选择合适的镜像
- **内部网络通信**: 容器间通过 Docker 内部网络直接通信,无需端口映射
- **路径自动解析**: 自动检测容器内路径到宿主机路径的映射
### 容器工作空间路径
| 隔离类型 | RCoder 路径 | Computer 路径 |
|---------|------------|--------------|
| project | `/app/project_workspace/{project_id}` | `/app/computer-project-workspace/{user_id}/{project_id}` |
| tenant/space | `/app/project_workspace/{tenant_id}/{space_id}/{project_id}` | `/app/computer-project-workspace/{tenant_id}/{space_id}/{project_id}` |
### 配置系统
多层级配置优先级 (从高到低):
1. **命令行参数** - `--port`, `--projects-dir`, `--enable-proxy`
2. **环境变量** - `RCODER_PORT`, `DOCKER_SOCKET_PATH`, `RCODER_DOCKER_IMAGE_*`
3. **配置文件** - `config.yml` (自动生成)
4. **默认配置** - 代码中的默认值
## 环境配置
### 核心环境变量
```bash
# 服务配置
RCODER_PORT=8087 # 服务端口
RUST_LOG=debug # 日志级别
# Docker 配置
DOCKER_SOCKET_PATH=/var/run/docker.sock # Docker socket 路径
RCODER_DOCKER_IMAGE=custom/image # 自定义镜像
RCODER_DOCKER_IMAGE_ARM64=arm64/image # ARM64 专用镜像
RCODER_DOCKER_IMAGE_AMD64=amd64/image # AMD64 专用镜像
# 代理配置
ANTHROPIC_API_KEY=sk-xxx # Claude API 密钥
COMPOSE_PROJECT_NAME=rcoder # Docker Compose 项目名
```
### 开发环境要求
- Rust 1.75+ (2024 Edition)
- Docker 和 Docker Compose
- Claude Code CLI (可选)
## API 接口
### 核心端点
- `POST /chat`: 发送聊天消息到 AI 代理 (支持 `pod_id`, `tenant_id`, `space_id`, `isolation_type` 多租户参数)
- `POST /computer/chat`: Computer Agent 聊天接口 (支持多租户参数)
- `GET /agent/progress/{session_id}`: SSE 进度流,接收实时通知
- `POST /agent/session/cancel`: 取消正在执行的任务
- `POST /agent/stop`: 停止 Agent
- `GET /agent/status/{project_id}`: 查询 Agent 状态
- `POST /pod/ensure`: 确保容器存在,支持多租户参数
- `POST /pod/restart`: 重启容器,支持多租户参数
- `GET /health`: 健康检查
### Pingora 反向代理
- `GET /proxy/{port}/{path}`: 端口路由到指定后端服务
- `GET /proxy/status`: 查看代理服务状态
- `GET /proxy/stats`: 查看代理统计信息
### 响应格式
所有 API 响应都使用统一的 HttpResult 格式:
```rust
struct HttpResult<T> {
success: bool,
data: Option<T>,
code: String, // 业务错误码
message: String, // 错误描述
tid: Option<String>, // 追踪ID
}
```
## 特殊注意事项
### 禁止事项
1. **禁止使用模拟响应逻辑** - 所有 AI 调用必须真实执行
2. **禁止编写 unsafe 代码** - 项目要求内存安全
3. **AgentSideConnection 必须在 LocalSet 中使用** - 由于未实现 Send trait
4. ** Always Response in 中文** - 所有响应必须使用中文
### Docker 容器管理
- **容器名称格式**: `rcoder-agent-{project_id}``rcoder-agent-{pod_id}` (当 pod_id 提供时)
- **镜像选择策略**: 通用镜像 > 架构特定镜像 > 默认回退镜像
- **网络模式**: 优先使用内部网络,支持 host 网络模式
- **安全配置**: 自动移除 NET_RAW 和 NET_ADMIN 权限
### 性能优化
- 使用 DashMap 进行并发访问,避免 RwLock 竞争
- 实现写时复制 (CoW) 模式,减少不必要的内存分配
- 使用 MPMC 架构处理多个 AI 请求
- 通过内部网络进行容器间通信,避免宿主机端口映射
### 错误处理
- 使用 anyhow 进行错误传播
- 使用 HttpResult 统一 API 响应格式
- 实现完整的错误追踪和日志记录
## 调试和开发
### 日志配置
```bash
# 启用详细日志
RUST_LOG=debug cargo run --bin rcoder
# 特定模块日志
RUST_LOG=rcoder=debug,tower_http=debug cargo run
# 在容器中启用调试
RUST_LOG=debug make dev-up
```
### 容器调试
```bash
# 查看容器状态
docker ps | grep rcoder
# 查看容器日志
make dev-logs
# 进入容器调试
docker exec -it <container_id> /bin/bash
```
### 网络调试
```bash
# 检查容器网络
docker network ls
docker network inspect rcoder_agent-network
# 测试容器间连通性
docker exec <container1> ping <container2_ip>
```
## 开发工作流程
1. **首次开发环境设置**:
```bash
make dev-build # 构建 Docker 镜像
make dev-up # 启动开发容器
```
2. **日常开发**:
```bash
# 修改代码后
make dev-restart # 重新编译并重启容器
```
3. **测试新功能**:
```bash
# 直接运行
cargo run --bin rcoder -- --port 8080
# 或使用容器
make dev-up
curl -X POST http://localhost:8087/chat -d '{"prompt":"hello"}'
```
4. **调试问题**:
```bash
# 查看详细日志
make dev-logs
RUST_LOG=debug make dev-restart
```
## 关键代码模式
### ACP 协议集成模式
```rust
// 正确的 LocalSet 使用模式
let local_set = LocalSet::new();
local_set.run_until(async move {
let (client_conn, handle_io) = ClientSideConnection::new(
client, outgoing, incoming, |fut| {
tokio::task::spawn_local(fut);
}
);
tokio::task::spawn_local(handle_io);
// ... 处理逻辑
}).await;
```
### DashMap 高效使用模式
```rust
// 使用 entry API 避免多次锁获取
let entry = state.project_and_agent_map.entry(project_id.clone());
match entry {
dashmap::mapref::entry::Entry::Occupied(mut occupied) => {
// 只在需要更新时进行写时复制
if needs_update {
let mut mutable_info = (**occupied.get()).clone();
mutable_info.update_field(value);
occupied.insert(Arc::new(mutable_info));
}
}
dashmap::mapref::entry::Entry::Vacant(vacant) => {
// 创建新条目
let new_info = ProjectAndContainerInfo::new(project_id);
vacant.insert(Arc::new(new_info));
}
}
```
### Docker 容器创建模式
```rust
// 容器配置模式
let container_config = DockerContainerConfig {
project_id: project_id.clone(),
image: get_docker_image_from_config(image, arm64_image, amd64_image, default_image),
host_path: resolve_container_path_to_host(&project_path).await?,
container_path: project_path.clone(),
port_bindings: HashMap::new(), // 内部网络,无需端口映射
network_name: Some(network_name),
// ... 其他配置
};
```