DeepChat ACP v1 Reliability 任务账本详解:能力门禁、会话闭环与真实 Agent 验证矩阵
DeepChat ACP v1 Reliability 任务账本详解:能力门禁、会话闭环与真实 Agent 验证矩阵
本文以 DeepChat 仓库中的 tasks.md 为主体,完整解读 ACP(Agent Client Protocol)v1 可靠性工作的 14 个任务域与 106 项任务条目,并结合 spec.md、plan.md 以及 src/main/agent/acp/ 下的真实实现代码,说明每项任务的协议边界、门禁条件与验收方式。读完后,你可以掌握 ACP 初始化能力快照、认证流程、会话导入/恢复/关闭生命周期、session/update 缓冲路由、prompt 内容映射、权限桥接、终端与文件系统安全约束的完整设计,以及最终质量门(quality gate)的验证方法。
文档定位:任务账本在 SDD 三件套中的角色
docs/features/acp-v1-reliability/ 是一个标准的 SDD(Spec-Driven Development)目录,包含三份文档:
- spec.md:定义产品契约、能力协议要求矩阵与互操作矩阵,是"验收合同";
- plan.md:定义运行时流程(Runtime Flow)、数据所有权模型与分 5 个增量落地的实施计划;
- tasks.md:将 spec 的验收合同拆成 106 个可勾选的任务条目,按 14 个领域分组。
tasks.md 头部有一个重要状态声明:当前状态为 active,全部 106 个未勾选项仍是"未对账的规划账本"(unreconciled planning ledger),不能从附近的 ASLR 工作或零散勾选推断完成状态;完成必须以代码、测试和真实 agent 证据为准。同时它明确了模块所有权:直接 ACP 归 AcpAgentRuntime / AcpAgentInstance(对应源码 acpAgentRuntime.ts 与 acpAgentInstance.ts),而 acpProvider.ts 仅为"DeepChat 会话选择了 ACP provider"这一兼容路径服务。当前模块划分的权威描述见 agent-system.md。
任务域总览
| 章节 | 主题 | 核心关注点 |
|---|---|---|
| 0 | Review Gate | spec/plan 评审门禁,SDD 目录在合并或明确放弃前保持 active |
| 1 | 能力与初始化 | initialize 结果解析、能力快照、错误分类 |
| 2 | 认证 | agent / env_var / terminal 三种 auth method 与 logout |
| 3 | 会话目录/导入/生命周期 | list/import/resume/detach/close/fork 及 AcpSessionLink 持久化 |
| 4 | session/update 路由 | 按 sessionId 的更新缓冲、TTL、乱序保护 |
| 5 | Prompt Turn 与输入内容 | current-turn-only 格式化、多模态能力门禁 |
| 6 | 会话更新与输出内容 | chunk/usage/session_info/plan 的映射语义 |
| 7 | 工具调用与权限 | request_permission 与 tool_call 进度语义分离 |
| 8 | 文件系统 | workdir 授权、1-based 行号、二进制/大小限制 |
| 9 | 终端 | 直接 spawn、UTF-8 安全截断、kill/release 幂等 |
| 10 | 模式/配置项/斜杠命令 | config state 归一化、legacy mode 兼容 |
| 11 | 诊断 UI | 设置页诊断区、i18n、renderer 测试 |
| 12 | Registry 与真实 Agent 矩阵 | DimCode / Claude Code ACP / Codex ACP 实机验证 |
| 13 | 最终质量门 | format/i18n/lint/typecheck 与 ACP 测试套件 |
第 1 域:能力与初始化(Capability and Initialization)
这是整个可靠性工作的地基,包含 6 个任务:
- 为完整解析 initialize 结果添加测试:
agentInfo、agentCapabilities、sessionCapabilities、promptCapabilities、authMethods、mcpCapabilities; - 在 ACP 进程句柄上扩展一个轻量能力快照(capability snapshot);
- 从快照解析支持位:
loadSession、sessionList、sessionResume、sessionClose、sessionFork、authLogout; - 更新 initialize 调试日志,包含协议版本、客户端能力、agent 能力与认证方式;
- 保证
buildClientCapabilities只声明已实现的能力; - 为初始化失败增加显式错误分类:协议不匹配、进程退出、协议流关闭、超时。
对应实现已落在 acpCapabilities.ts:buildCapabilitySnapshot() 从 InitializeResponse 中提取 protocolVersion、agentInfo、agentCapabilities、sessionCapabilities、promptCapabilities、authMethods、mcpCapabilities,并生成 supports 布尔位(loadSession、sessionList、sessionResume、sessionClose、sessionFork);buildClientCapabilities() 则按 enableFs / enableTerminal / enableTerminalAuth 开关决定向 agent 声明 fs.readTextFile/writeTextFile、terminal,以及仅在交互终端认证已可用时声明 auth.terminal。这正体现了账本第 5 条"只声明已实现能力"的原则——terminal 认证何时声明以 acp-terminal-auth spec 为准。快照解析的回归测试位于 acpCapabilities.test.ts 与 acpProcessManagerCapabilities.test.ts。
第 2 域:认证(Authentication)
8 个任务覆盖三层入口与三种 auth method:
- 扩展共享 ACP debug action 类型,加入
authenticate与logout; - 添加类型化调试路由
authenticate({ agentId, methodId, workdir? })与logout({ agentId, workdir? }),后者受auth.logout能力门禁; - 将 auth-required 失败映射为 renderer 安全的 ACP 状态负载(不泄露凭证);
- 按 spec 的协议要求实现三种 method:
agent(缺省类型)直接调用connection.authenticate({ methodId });env_var不在 agent 设置中暴露缺失的环境变量并要求重启/重新初始化;terminal在声明clientCapabilities.auth.terminal=true之前必须先实现终端交互流程; - 补充成功、失败、method id 缺失、不支持 logout、进程清理五类认证测试。
spec 中有一条容易被忽略的关键约束:terminal 认证类型不得调用 authenticate,而是直接以交互方式运行已物化的 agent 命令,在退出码为 0 后重连并重新 initialize。这条路径在源码中由 acpAuthService.ts 与 acpTerminalAuthRunner.ts 承接,配套测试包括 acpAuthService.test.ts、acpTerminalAuthRunner.test.ts 与 acpTerminalAuthRunnerLifecycle.test.ts。注意 spec 明确:终端认证的实现完成,不等于 logout 或更大会话生命周期范围的完成——这正是 tasks.md 第 2 域仍保持未勾销的原因之一。
第 3 域:会话目录、导入与生命周期(Session Catalog, Import, and Lifecycle)
这是条目最多(16 项)的核心域,定义了远端 agent 会话与 DeepChat 本地会话之间的边界:
- 扩展共享 ACP debug action 类型:
sessionList、sessionImport、sessionResume、sessionDetach、sessionCloseRemote、sessionFork; - 增加
session/list类型化调试路径,支持工作区cwd过滤与游标分页; - 增加
AcpSessionLink持久化,键为agentId + canonicalWorkdir + remoteSessionId; - 外部会话目录同步只更新 link 元数据,不创建重复的 DeepChat 会话;
- 导入路径为远端会话创建或复用 DeepChat 会话;
session/load导入路径受顶层loadSession能力门禁; - 重放的远端更新先进入暂存(staging)再转换为 DeepChat 消息;引入消息/块指纹(fingerprinting),保证重复导入不产生重复消息;
session/resume路径受sessionCapabilities.resume门禁,仅用于已绑定会话;- 固定本地运行时恢复优先级:已链接的
resume> 已链接的loadSession导入/重放 >newSession; - 本地会话关闭/删除默认只 detach ACP 链接、不写远端;显式远端关闭受
sessionCapabilities.close门禁; - 用户停止生成走
session/cancel,显式远端关闭才用session/close; - 进程崩溃后持久化链接必须保留,可恢复 agent 稍后应能 resume;
session/fork仅作为 debug-only 路径,受能力门禁,暂不接入普通聊天流;- 增加 DimCode 形态的生命周期测试:list 空目录、目录同步、导入、重复导入不重复消息、resume、显式远端关闭。
plan 文档给出了 AcpSessionLink 的完整字段设计(conversationId、agentId、canonicalWorkdir、remoteSessionId、remoteTitle、remoteUpdatedAt、lastImportedRemoteUpdatedAt、lastImportFingerprint、importedMessageFingerprints、syncState: cataloged | imported | attached | stale | error)。数据所有权原则是:DeepChat 会话/消息记录是事实源,远端 session 只提供 catalog(session/list 返回的元数据)、replay(session/load 重放的历史)与 runtime context(resume/new 后的运行时上下文)三类信息。默认只有两种情况写远端:用户在已绑定会话中继续发送 prompt,或用户显式选择 Close Remote Session。链接持久化对应 acpSessionPersistence.ts,生命周期选择逻辑位于 acpSessionManager.ts,回归测试见 acpSessionPersistence.test.ts 与 acpSessionManager.test.ts。
第 4 域:session/update 路由(Session Update Routing)
该域解决一个具体的时序缺陷:session/new 返回前后,agent 可能已经发出 session/update,但 DeepChat 的 listener 尚未注册,导致 commands/modes/config 的早期状态丢失。6 个任务:
- 增加按
sessionId键控的 session update 缓冲区; - 缓冲 listener 注册前到达的更新;
registerSessionListener执行时按原始顺序 flush;- 施加 TTL 与最大条目数保护,避免内存无界增长;
- 将过期丢弃的缓冲更新记入 ACP 调试日志;
- 增加
session/new期间available_commands_update早到的回归测试。
从源码结构看,该域已有对应落地:acpProcessManager.ts 中定义了 SESSION_UPDATE_BUFFER_TTL_MS = 30_000(30 秒 TTL),bufferedSessionUpdates 以 sessionId 为键存更新,bufferSessionUpdate() 在 listener 缺失时写入缓冲,listener 注册后 flush 并记录 session/update.buffer.flush 调试事件,过期扫描任务定期清理 TTL 外的条目。这正是账本"缓冲 + TTL + 有序 flush + 可诊断丢弃"四条要求的组合。
第 5 域:Prompt Turn 与输入内容(Prompt Turn and Input Content)
目标是把历史式格式化替换为当前轮次 only 的格式化,7 个任务:
- 用 current-turn-only 格式化器替换基于历史的 ACP 格式化器;
- 移除 temperature/maxTokens 的 prompt 文本注入;
- DeepChat system prompt 仅在本地会话首次绑定 ACP 运行时发送一次;
- 增加 text、image、audio、resource、resource_link 五种输入内容映射;
- image/audio/resource 受
promptCapabilities门禁; - 为不支持的多模态内容提供降级行为;
- 覆盖 text-only、image 支持/不支持、audio 支持、嵌入上下文、system prompt 只发一次六类测试。
plan 给出的输入映射策略表值得保留:text → text;本地/远程 URL 附件 → resource_link;base64 图片且 agent 支持 → image,不支持则降级为 resource_link 或文本;audio 支持 → audio,不支持 → 文本降级;嵌入文件/上下文且支持 embeddedContext → resource 或文本上下文。实现入口是 acpMessageFormatter.ts,测试在 acpMessageFormatter.test.ts。
第 6 域:会话更新与输出内容(Session Updates and Output Content)
该域规范 agent 侧回流的更新如何进入 DeepChat,8 个任务:
agent_message_chunk保持映射到文本流 + 内容块;agent_thought_chunk映射到推理流 + 推理块;- image/audio/resource/resource_link 输出处理在元数据/调试中保留结构;
usage_update映射到 turn 元数据与 ACP 调试日志(不编造缺失值);session_info_update映射到AcpSessionLink元数据;- 会话标题更新不得覆盖用户手工编辑的 DeepChat 标题;
- 保持
plan更新的替换语义(每次替换当前 plan 条目,而不是向 transcript 追加重复 plan); - 增加 usage、session info、plan 替换、不支持输出降级四类测试。
映射逻辑收口在 acpContentMapper.ts,回归覆盖见 acpContentMapper.test.ts。
第 7 域:工具调用与权限(Tool Calls and Permission)
语义修正的核心是:普通 tool_call 进度不得当作权限 UI,只有 session/request_permission 进入 DeepChat 权限浮层。其余 5 项:
- 保留工具终端输出、diff 路径/内容、locations、原始输入/输出在块元数据/调试中;
- 权限 resolver 增加超时,默认结果为 cancelled;
- 会话中断后清理过期权限浮层,而不是对未知 request id 抛错;
- 覆盖 approve、deny、cancel、timeout、resolver 缺失与工具更新渲染的测试。
对应实现是 acpPermissionBridge.ts,测试为 acpPermissionBridge.test.ts。
第 8 域:文件系统(File System)
保持 fs/read_text_file 与 fs/write_text_file 在已声明的 client fs 能力之后,任务以测试加固为主:
- 已注册 workdir 要求;
- 1-based 行号处理;
- 跨工作区路径拒绝;
- 二进制读取拒绝与最大尺寸错误;
- 验证写入路径只创建允许的文件并返回协议形态的错误。
实现位于 acpFsHandler.ts,路径守卫在 acpPathGuard.ts,测试在 acpFsHandler.test.ts。spec 强调 clientCapabilities.fs 只有 handler 真正可用时才声明——handler 初始化失败时不声明,能力声明必须与控制流一致。
第 9 域:终端(Terminals)
8 个任务围绕协议正确性与输出安全:
terminal/create改为直接用command+argsspawn,移除默认 shell 字符串拼接(Windows 不默认包powershell.exe -Command;需要 shell 时由 agent 把 shell 本身作为 command);- cwd 解析受工作区规则或显式 fallback 警告保护;
- 输出缓冲截断改为保留最新尾部输出,且截断不得劈开 UTF-8 字符;
kill与release保持幂等;- 覆盖 args 引用、尾部截断、多字节截断、退出状态、kill、release 与缺失终端的测试。
从源码结构看,acpTerminalManager.ts 已体现这些约束:outputByteLimit(回退到默认上限)控制缓冲字节数,超出即置 truncated;killTerminal 在已 killed 或已有 exitStatus 时直接短路,releaseTerminal 对未知/已释放 terminal 返回空结果,两者均幂等。测试见 acpTerminalManager.test.ts。
第 10 域:模式、配置项与斜杠命令(Modes, Config Options, Slash Commands)
9 个任务维护三类 UI 状态与协议更新的同步:
- initialize、new、load、resume 四个入口都必须发布归一化后的配置状态(plan 中统一走
normalizeAcpConfigState); - 保留
session/set_mode兼容仍使用 session modes 的 agent;两者并存时 UI 优先展示 config options; current_mode_update与 ChatStatusBar 保持同步;config_option_update与配置状态保持同步;available_commands_update在更新缓冲修复后能正确填充斜杠建议(包括 listener 注册前收到的通知);- 选定的 workdir 不可用时跳过 ACP warmup,同时保留 session 启动的 fallback 行为;
- 覆盖 set mode、set model/config option、current mode update、config option update 与斜杠命令可用性的测试。
用户输入 /command arg 仍走普通 session/prompt,不新增 agent 专属 command RPC。状态归一化逻辑见 acpConfigState.ts。
第 11 域:诊断 UI(Diagnostics UI)
10 个任务要求在 agent 设置页加入紧凑的 ACP 诊断区,而不是独立大页面(plan 文档中给出了 ASCII 线框:协议版本、Auth 状态、FS/Terminal 开关、Sessions 能力、Prompt 内容能力,以及条件显示的 Authenticate / Sync Sessions / Run Diagnostics 按钮):
- 展示协议版本、就绪状态、认证状态、能力、启动来源与最近错误;
- Authenticate 按钮仅在存在 auth methods 时显示;Sync Sessions 仅在
sessionCapabilities.list存在时显示; - 已列出的远端会话提供 Import/Open 操作;已链接的本地会话提供 Detach 操作;
- Close Remote 仅在显式用户意图且
sessionCapabilities.close时可用; - Run Diagnostics 执行带超时的安全 initialize/list 能力探测;
- 所有新标签与错误文案走 i18n;
- renderer 测试覆盖 ready、auth required、无 session list、目录同步、已导入链接、重复导入防护与错误态。
第 12 域:Registry 与真实 Agent 矩阵(Registry and Real-Agent Matrix)
该域把互操作验证落到具体 agent 上:
- 在 Windows 上验证 registry 中
dimcode@0.0.75的启动规格; - 验证 DimCode 全生命周期:initialize、list、目录同步、导入、重复导入不重复、commands、resume、prompt、显式远端关闭;
- 验证 Claude Code ACP 的 initialize 与 auth-required 路径(含超时清理);
- 验证 Codex ACP 的 registry 启动与本地/全局版本漂移诊断;
- 在 ACP 调试日志或测试笔记中记录精确命令、版本、能力与结果;
- 在拿到可执行路径或精确包名之前,
acpx不进入矩阵。
registry 启动规格来自 registry.json;版本记录要求与 spec 的互操作矩阵一致——每次运行都要记录包与可执行文件版本,可选样本不可用不得暗示协议不支持,也不阻塞无关覆盖。
第 13 域:最终质量门(Final Quality Gates)
任务账本把收尾验证固化为 8 条命令与决策:
pnpm run format
pnpm run i18n
pnpm run lint
pnpm run typecheck
pnpm test -- test/main/agent/acp
pnpm test -- test/main/provider/acpProvider.test.ts
# 若 UI 有变更,再运行 renderer 诊断 UI 测试
最后一条是非命令项:实现合并后更新持久化文档,或归档本 SDD 目录。ACP 主进程测试集中在 test/main/agent/acp/(含 runtime、auth、catalog、instance、client、launch、compatibility 等子目录,共 27 个测试文件),provider 兼容路径测试为 acpProvider.test.ts,另有 providerInstanceManager.acpLifetime.test.ts 覆盖 ACP 实例生命周期。
如何阅读这份账本:与源码证据的对应关系
tasks.md 的价值不仅在于列出 106 个条目,更在于它把 spec 的验收合同转译成"文件级可定位"的工作项。从源码结构看,src/main/agent/acp/ 已经按域分层:runtime/(进程、会话、能力、内容映射、终端、FS、权限桥、调试日志)、auth/(认证服务与终端认证 runner)、instance/(runtime owner 与 agent 实例)、launch/(启动规格服务)、catalog/(registry 与设置存储)、client/(连接与 prompt 控制器)、compatibility/(provider 适配)。每一域的任务条目基本都能在对应模块与同名测试文件之间找到映射;而"完成"与否,仍需按账本开头的原则,以代码、测试与真实 agent 三者证据同时齐备为准——这正是 spec 在 Validation Contract 一节中强调的"终端认证实现单独完成不能关闭更广泛的验证要求"。