ACP 完整语义适配总体方案¶
文档状态:Active
实施状态:P0-P7 completed(本地可验证范围);P8 release gates in progress(真实 MCP/Zed/Linux 互通与全量门禁)
目标协议:ACP v1 stable(具体 schema 在 P0 锁定)
实现约束:使用官方 Python SDKagent-client-protocol,不使用deepagents-acp
权威进度台账:progress.md
架构决策记录:decisions.md
1. 结论¶
Synapse 将新增独立的 ACP Agent 适配层,对外完整实现锁定版本 ACP v1 的 Agent 侧语义,对内复用现有 Agent assembly、RuntimeManager、SessionRuntime、语义流事件、会话存储和 MCP 基础设施。
实施可以分阶段交付,但最终目标不缩减:
- 覆盖锁定 schema 中全部必选 Agent 方法和语义。
- 对锁定 schema 中每项稳定可选能力作出实现,并在能力矩阵中逐项验收。
- capability 声明与运行行为来自同一真源。
- 内容、流事件、权限、取消、错误、并发和资源释放都属于协议实现范围。
- stdio JSON-RPC 由官方 SDK 承担,Synapse 不重复实现协议编解码。
- ACP 适配层不直接调用 Deep Agent 原始
astream(),必须经过现有 headless runtime。
2. 范围定义¶
2.1 包含¶
- ACP v1 stable Agent 角色。
- stdio transport。
- 初始化、能力协商和协议错误。
- 完整 prompt turn、内容块和 session update 语义。
- Permission/HITL 闭环。
- 锁定 schema 中稳定的会话生命周期方法。
- 会话级 MCP servers。
- Agent 对 ACP Client filesystem、terminal、permission 等反向 RPC 的使用。
- session config、commands、usage、metadata、认证等稳定能力。
- Windows/Linux 兼容和真实 ACP Client 验收。
2.2 不包含¶
- ACP v2 draft;待其稳定后另立升级阶段。
- 自研 JSON-RPC transport 或复制官方 SDK schema。
- 实现一个通用 ACP Client 产品。
- 使用
deepagents-acp作为运行时依赖。 - 未经 capability 协商调用 Client 可选服务。
- 将 ACP Client 传入的 MCP 凭据持久化到 Synapse 全局配置。
3. 完整实现定义¶
ACP 是 capability-driven 协议。这里的“完整语义”按以下标准验收:
- 锁定 schema 中所有必选 Agent 方法均实现。
- 锁定 schema 中每个稳定可选 Agent 方法和 capability 均进入能力矩阵,不允许遗漏。
- 最终声明的每项 capability 都有成功、错误、取消和资源释放测试。
- 未声明能力仍须按协议返回正确的不支持行为,不能静默接收或丢弃。
- 所有稳定 ContentBlock、SessionUpdate 和 stop reason 联合类型均有显式转换策略。
- capability、handler 和测试矩阵可互相追溯。
- SDK 负责 wire schema,不代表 Synapse 自动获得业务语义;业务状态机必须独立验收。
P0 会基于实际 SDK 源码和 schema 生成最终矩阵。P0 前不写死 SDK 版本和方法签名。
4. 当前基础¶
可直接复用:
| 能力 | 当前实现 |
|---|---|
| Agent 组装 | src/synapse/app/agent.py |
| 无 UI turn 执行 | src/synapse/runtime/agent_loop/turn.py |
| 多会话管理 | src/synapse/runtime/sessions/manager.py |
| 单会话状态、取消、订阅 | src/synapse/runtime/sessions/runtime.py |
| UI 无关语义事件 | src/synapse/runtime/streaming/events.py |
| 有界事件回放 | src/synapse/runtime/sessions/events.py |
| HITL 解析与 resume payload | src/synapse/runtime/hitl.py |
| 会话元数据 | src/synapse/sessions/store.py |
| checkpoint 历史读取 | src/synapse/sessions/transcript.py |
| MCP 配置和连接池 | src/synapse/integrations/mcp_client.py |
| 图片附件 | src/synapse/content/multimodal.py |
当前缺口:
- ACP 独立进程入口和 stdout 隔离。
- ACP session descriptor 与 session-scoped resources。
- 完整 ContentBlock codec。
TurnEvent到 ACP SessionUpdate 的稳定状态机。- Permission request 在同一 ACP prompt 内 resume。
- load/resume/fork/list/delete 等生命周期的精确语义。
- Client-provided MCP 的会话隔离。
- Client filesystem/terminal backend。
- Plan、diff、结构化 tool 内容和完整 usage 事件。
- capability 单一真源和协议合规测试。
5. 目标架构¶
ACP Client
-> official ACP SDK / stdio JSON-RPC
-> SynapseACPAgent
├─ CapabilityRegistry
├─ ACPSessionManager
├─ ContentCodec
├─ ACPEventBridge
├─ PermissionCoordinator
├─ ClientServiceGateway
└─ ACPMcpAdapter
-> RuntimeManager / SessionRuntime
-> AgentTurnRuntime
-> Synapse Deep Agent
建议目录:
src/synapse/acp/
├── __init__.py
├── server.py
├── agent.py
├── capabilities.py
├── models.py
├── sessions.py
├── content.py
├── events.py
├── permissions.py
├── client_services.py
├── mcp.py
└── errors.py
SDK schema 类型只允许出现在 synapse.acp 边界。runtime、sessions、integrations 不反向依赖 acp。
6. 核心领域模型¶
完整实现前先引入会话描述,避免后续为 cwd、MCP 和 Client capability 推翻 factory:
@dataclass(frozen=True, slots=True)
class ACPSessionDescriptor:
session_id: str
cwd: Path
additional_directories: tuple[Path, ...]
mcp_servers: tuple[object, ...]
client_capabilities: object
config_options: Mapping[str, object]
每个 ACP session 至少拥有:
- 独立
SessionRuntime。 - 固定 cwd 和额外根目录。
- 独立 MCP scope。
- Client capability snapshot。
- 活跃 prompt、pending permissions 和 event bridge。
- 可取消的有界输出队列。
7. 关键语义¶
7.1 Prompt 生命周期¶
一个 ACP session/prompt 可以包含多个 Synapse turn:普通 turn 及若干 HITL resume turn。对 ACP Client 而言,它们仍是同一个 prompt request。
prompt
-> submit turn
-> stream updates
-> waiting approval?
-> request_permission
-> submit resume turn
-> stream updates
-> final stop reason
7.2 事件桥¶
SessionEventBroker 回调可能发生在 Agent runtime 线程;ACP SDK 运行于服务 asyncio loop。桥接必须使用 loop.call_soon_threadsafe 和有界队列,不能在 broker callback 中直接 await。
- Tool、permission 和终态事件不得丢失。
- 文本 delta 可合并但不得乱序。
- 慢 Client 必须触发有界背压策略,不能无限积压。
7.3 会话级 MCP¶
ACP session/new/load/resume 传入的 MCP servers 只属于当前 session:
- 转换为 Synapse
McpServerConfig。 - 使用 session scope key 建立连接池。
- 构建该 session 的 Agent tools。
- session 关闭时释放。
- 不写入全局 MCP 配置,不泄漏到其他 session。
7.4 Client 反向服务¶
当 Client 声明 filesystem/terminal capability 时,Synapse 可以通过 Client RPC 获取未保存 buffer 或 IDE terminal。未声明时回退本地 backend;所有路径仍受 workspace 和安全策略约束。
8. 阶段划分¶
| 阶段 | 目标 | 方案 |
|---|---|---|
| P0 | 锁定 SDK/schema、能力矩阵和测试护栏 | phase-0-protocol-baseline.md |
| P1 | stdio 入口、初始化和核心会话 | phase-1-core-transport.md |
| P2 | 完整 prompt/content/update 语义 | phase-2-prompt-semantics.md |
| P3 | Permission/HITL 闭环 | phase-3-permissions.md |
| P4 | 完整会话生命周期和历史 | phase-4-session-lifecycle.md |
| P5 | 会话级 MCP servers | phase-5-session-mcp.md |
| P6 | Client filesystem/terminal 反向服务 | phase-6-client-services.md |
| P7 | Config、commands、usage、metadata、auth | phase-7-advanced-capabilities.md |
| P8 | 合规、跨平台、真实客户端和发布收口 | phase-8-compliance.md |
阶段允许增量发布,但每个阶段只声明已经过门禁的 capability。最终 P8 对 P0 矩阵逐项清零。
9. 跨阶段约束¶
agent-client-protocol必须精确锁版本,升级必须新增决策记录和 schema diff。- ACP stdout 只允许协议消息,日志只写 stderr。
- 所有输入大小、队列、历史回放、分页和日志必须有界。
- Client 环境变量、MCP env、headers、token 不得写日志或落盘。
- 同一 session 禁止重叠 prompt;不同 session 按配置并发。
- capability 不能先于实现和测试开启。
- 任何协议对象都必须使用 SDK model/helper 构造,禁止手写不受校验的 wire dict,除非 SDK 明确要求。
- Windows 和 Linux 都是发布门禁。
10. 总体验收¶
- P0 能力矩阵全部关闭,无未解释空项。
- 所有必选和声明能力有协议级测试。
- 所有稳定联合类型有转换或明确的不声明策略。
- Permission、cancel、disconnect、并发竞争均保持状态一致。
- 会话 MCP、Client terminal 和 filesystem 无跨 session 泄漏。
- Zed 和一个官方 SDK 驱动 Client 完成端到端测试。
uv run --no-sync ruff check .通过。- ACP 相关测试及全量测试通过。
- 文档明确 SDK 版本、schema 版本、能力列表和客户端配置。
实时状态和任务勾选只维护在 progress.md。