Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

tracking: MCP/ACP 协议与生命周期(5 项)—— 串行 IO + 缺失生命周期对象

Đang mở
#190 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức phù hợp với người mới
12/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
rust
Lĩnh vực
api, backend

Hướng nghiên cứu

This is a tracking issue with no code of its own; the work is in the child issues #183, #179, #180 (ACP, src/acp/server.rs, run_stdio around lines 1524-1556) and #181, #178 (MCP, src/mcp.rs). Start by reading run_stdio and process_line in src/acp/server.rs to see why the &mut W writer blocks running prompts as separate tasks. Done means each child issue's acceptance checks pass, with the four cluster-level acceptance tests as the final check.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

优先级 P1 · 依赖:无 · 类型:tracking(簇设计入口,不产出代码;子单全部落地后关闭)
记号:正文中的「不变量 #N」指 .dev/AGENTS.md 编号,不是 issue 编号;#150 这类才是 issue。本簇子单头部写 depends-on: #N 表示落地串行(同文件/同契约),不会与语义阻塞混淆。

基线 HEAD = 14bac15a(子单同基线)。本单来自一次全仓审计:先按根因归簇,再拆成可独立验收的子单。

共同根因

两条协议通道都是「能用表面、不能用实际」,而且根因同型:串行 IO + 缺失的生命周期对象。

MCP:#178 旧式 HTTP+SSE transport 完全不可用——spawn_http_sse 读到 endpoint 事件就把流丢掉(src/mcp.rs:544-611),read_sse_response 忽略 _post_url 重新 GET(:1204-1272)等于每次读取另开一个服务端会话;parse_sse_endpoint 返回原始 data、相对路径直接 POST(:1002-1008、:1281-1301)。#181 同文件的另外三处:tools/call 硬编码 10s 读超时且生产调用方无法覆盖(src/mcp.rs:340、388,src/mcp_server.rs:309、crates/recursive-cli/src/cli/builder.rs:500)、服务端发起的 ping/roots/list 被跳过不回复(:1131-1200)、能力字段按 as_bool() 读而规范服务端发对象(:645-653,对比 src/mcp_server.rs:134)。

ACP:run_stdio 串行 await process_line(src/acp/server.rs:1524-1556),而 prompt 在循环内 await runtime.run() 跑完整轮(:1307)→ 取消消息在轮中被积压,下一轮又被 refresh_cancel_token(:1286)换掉令牌;规范形态的无 id 通知被直接丢弃(:1696-1700 的 // Notifications (no id): silently discard)→ 模块头(:36-58)描述的「两阶段协作取消」在链路上不可达(#179)。EOF 也被 Ok(Ok(None)) → sleep(100ms) → continue 变成永不死去的 10 次/秒空转,60s 空闲超时永远不触发(:1524-1535,#183)。会话装配更是空的:AcpPermissionHook 无构造点(src/acp/permission.rs:114-171)、client-fs 工具绑定到 _tool 后丢弃(server.rs:612-636)却打 tool ready、mcp_servers 只存不 spawn(#180)。

子单与依赖

子单 依赖 范围
#183 无 ACP:EOF 即关停;空闲超时按固定 Instant 计算
#179 depends-on: #183 ACP:prompt 任务化 + 常驻读循环;cancel registry 按 sessionId;通知形态 cancel 在早退前分派
#180 depends-on: #179 ACP:每会话装配 registry(client-fs + AcpPermissionHook + spawn mcpServers 并登记 pid)
#181 无 MCP stdio:tools/call 独立可配超时;回服务端请求;能力判定 `object
#178 depends-on: #181 MCP legacy SSE:常驻 reader task + pending: HashMap<Id, oneshot>;Url::join 解析 endpoint

落地思路

  1. E 簇有两条可并行的子链:ACP(#183→#179→#180,全在 src/acp/)与 MCP(#181→#178,全在 src/mcp.rs),互不冲突。
  2. ACP 的难点是并发结构,不是功能:run_stdio 要拆成 (a) 读循环 (b) 每会话 prompt 任务 (c) writer 任务——现在 writer 是 &mut W 传进循环,任务化后必须改成 mpsc<Value> + 单一 writer task,否则借用检查过不去。这是 #179 的真正工作量。
  3. #180 先做 spike:需要确认客户端 capabilities 声明与 agent→client RPC 的路由方式(session/request_permission 要从 prompt 任务里回写),这是唯一需要与 ACP 协议对齐的点;建议先跑通「收到 request_permission 帧」再谈完整装配。
  4. MCP 侧先 #181 再 #178:两者同文件,且 #181 的 per-call 超时与 capability 判定是 #178 的 reader task 分发响应的前提。
  5. 与其它簇无文件重叠,可与其他簇并行。

簇级验收

  1. 本地起最小 SSE 服务端:initialize 成功、同一 sessionId 全程复用、tools/list 可返回;
  2. 长耗时(>10s)MCP 工具成功;{} 能力下 list_resources 可用;服务端 ping 收到回复;
  3. ACP:mock provider 阻塞在流中时,发通知形态 cancel 能中断该轮且 stopReason=cancelled;关闭 stdin 后 run_stdio 返回;
  4. ACP 会话的 tools/list 含 fs 工具,且工具调用时客户端收到 session/request_permission。

边界

不含 ACP 的功能性扩展(如新的 agent 能力);不含 MCP 的认证与协议版本升级(#104 的范围)。#178/#181 只修「不可用」与「不合规」,不改协议版本。

实施顺序、PR 拆分与验收矩阵(补充 · 2026-10-10)

两条可并行的子链(不同文件)

链 顺序 文件
ACP #183 → #179 → #180 src/acp/*
MCP #181 → #178 src/mcp.rs

#179 的真正工作量在并发结构:run_stdio(src/acp/server.rs:1524-1556)串行 await process_line(...),而 process_line 的签名是 (line, writer: &mut W, state: &mut ServerState, sessions: &mut AcpSessionManager, …)——&mut W 使得"prompt 放到独立任务"无法直接做到。因此 #179 必须先把 writer 改成 mpsc::Sender<Value> + 单一 writer task,再任务化 prompt。这一点不写清楚,实现者会卡在借用检查上。

#180 先做一次 spike:需要确认 (a) 客户端 capabilities 的读取位置,(b) session/request_permission 这类 agent→client RPC 在任务化之后怎么回写(同一个 writer 通道),(c) mcpServers 的 spawn 与 pid 登记点。建议 spike 的完成判据就是"能收到一帧 session/request_permission"。

跨簇重叠:无(src/acp/、src/mcp.rs 不被其它簇触碰)→ 本簇可与其他簇并行。

PR 拆分:一子单一 PR;#179 会比较大(读循环 + writer 任务 + cancel registry),建议在 PR 内分三个 commit(结构重构 / 通知形态 cancel / 测试),便于审阅。

簇级验收 → 测试映射:见正文四条;ACP 三条落在 src/acp/server.rs 的 #[cfg(test)](已有 duplex writer 夹具可复用),MCP 两条落在 src/mcp.rs 单测 + 一个新的 loopback e2e。

Ngôn ngữ chính
Rust
Star
4
Fork
0
Merge trung bình
5 giờ 32 phút
Pull request đã merge (30 ngày)
7

Chuẩn bị môi trường

  • Có Dockerfile hoặc tệp Docker Compose
  • Không có mẫu pull request
  • Không có hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của jeffkit/recursive

Tất cả issue của jeffkit/recursive

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.