
DeepSeek Harness ACP 终端渲染基于_meta约定的富 bash 终端卡片实现【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness导读本篇技术指南深入解析 DeepSeek Harness 在 ACPAgent Client Protocol桥接层中的一项关键设计——如何在不把 shell 执行权让渡给编辑器的前提下通过 ACP 规范认可的_meta扩展点把bash工具调用渲染为带 cwd、命令标题、输出与退出状态的富终端卡片。你将掌握ACP 客户端侧终端子协议为何被否决、_meta.terminal_info / terminal_output / terminal_exit三项 Zed 约定的线缆形态、提供方无关的终端展示词汇在dsh-tools中的定义以及桥接层如何以能力声明为门控、以console文本块为保底回退实现能力诚实。本文依据仓库中的 Agent Note 与源码实现packages/acp/acp、packages/core/tools、packages/shell/tool-bash展开读者读完后既能理解该方案的完整架构也能看懂对应测试如何守护这些契约。背景ACP 桥接层中的工具调用渲染DeepSeek Harness 通过deepseek-ai/dsh-acp桥接层位于 packages/acp/acp实现 ACP 协议允许 Zed 等外部编辑器驱动编码 agent。协议的核心工具生命周期包括tool_call调用开始与tool_call_update调用结束两类会话更新。桥接层的一个重要设计原则是工具调用的展示由工具自身负责。工具通过ToolDefinition.presentCall与presentResult声明渲染意图桥接层对返回的联合类型做 switch 并映射到 ACP见 packages/core/tools/src/index.ts 对这两个可选方法的契约定义纯函数、无副作用可在实时流式与日志回放两种路径上安全调用。没有声明 presenter 的工具获得通用回退。在引入富终端渲染之前bash调用的纯文本呈现方式为tool_call标题 确切命令模型的description作为一个kind: execute内容文本块完成后的输出包裹在console围栏文本块中。这种呈现丢失了终端元数据的结构参考编辑器如 Zed能把终端元数据渲染为一张专用卡片——包含 cwd、命令、实时风格的输出和退出状态而纯文本把这些结构全部拍平。命令之所以作为标题是因为执行卡片隐藏原始输入而人类可读的description保留为卡片上方的独立块。关键发现agent 执行终端的两种路线ACP 客户端侧终端子协议terminal/create为什么不适合ACP 规范定义了一个客户端侧终端子协议agent 调用客户端的terminal/create传入{ command, args, cwd, env }由编辑器执行进程然后 agent 读取terminal/output/wait_for_exit。这个模型与 DeepSeek Harness 的执行架构根本冲突harness 通过dsh-bash自行执行bash承担沙箱化的环境清理、后台任务所有权、按会话的 cwd若把执行路由到编辑器将绕过上述所有机制并把执行分叉到两个后端。参考 agent 的_meta约定研究两个参考 agent2026-06-18发现二者都没有为自己的 shell 工具使用terminal/create——两者都保持 agent 侧执行并发出一套由 Zed 特殊处理的_meta约定参考 agent相关文件具体行为claude-agent-acptools.ts、acp-agent.ts以clientCapabilities._meta.terminal_output为门控tool_call携带content: [{ type: terminal, terminalId }]与_meta.terminal_info.{ terminal_id, cwd }输出与退出通过tool_call_update的_meta.terminal_output.{ terminal_id, data }与_meta.terminal_exit.{ terminal_id, exit_code, signal }到达codex-acpCodexToolCallMapper.ts、TerminalOutputMode.ts调用上同样携带terminal_info输出通过_meta.terminal_output完整或_meta.terminal_output_delta增量由同一个_meta.terminal_output能力选择Zed 侧crates/agent_servers/src/acp.rs已验证的行为是收到ToolCall且其_meta.terminal_info.terminal_id已设置时注册一个仅展示的终端header terminal_info.cwdlabel tool_call.title收到ToolCallUpdate时_meta.terminal_output.data写入该终端_meta.terminal_exit.{exit_code,signal}设置状态客户端通过clientCapabilities._meta.terminal_output true声明此能力。关键在于_meta本身是 ACP 规范认可的扩展点在ToolCall/ToolCallUpdate上类型为{[k]: unknown} | null而这里的具体键terminal_info/terminal_output/terminal_exit是 Zed 约定不属于 ACP 规范。但它们是 Zed 集成的事实契约也是在保持 agent 侧执行的前提下获得终端卡片的唯一方式。决策agent 侧执行 _meta终端卡片 文本保底最终决策明确为保持dsh-bash的 agent 侧执行通过_meta约定渲染终端卡片以能力声明为门控以console文本块作为保底回退。决策拆解为四点1. 能力声明initialize读取clientCapabilities._meta.terminal_output桥接层按连接记住它。只有客户端显式声明该能力桥接层才会发出终端元数据。这构成后续一切映射的前提。2. 提供方无关的展示词汇dsh-tools新增一种终端形态的展示结构工具可返回它——提供方无关只含cwd、输出data、exitCode/signal不含任何 ACP 类型。这保证了展示词汇不被某个具体协议绑架。在 packages/core/tools/src/presentation.ts 中可以看到完整的契约定义调用侧TerminalCallViewpresentation.tscard: terminaltitle即命令终端卡片的标题行description是一行人类可读摘要渲染在终端卡片上方卡片本身没有描述槽位cwd是工作目录绝对路径原样使用相对路径由 UI 桥接层按会话工作区解析——纯 presenter 看不到会话 cwd省略则由桥接层使用会话工作区结果侧TerminalResultViewpresentation.tsoutput为捕获的命令输出stdoutstderr 由工具自行决定如何合并exitCode/signal二选一让有能力的 UI 显示退出状态 pill无能力的 UI 获得由output派生出的console围栏保底由桥接层派生工具不双重编码。dsh-tool-bash为bash返回该结构cwd 来自解析后的工作目录输出与退出从运行结果解析。在 packages/shell/tool-bash/src/index.ts 中presentBashCall前台运行返回card: terminal命令为标题、description 为上方描述、workdir 透传为 cwd后台启动返回card: generickind: execute命令为rawInputdescription 作为内容块presentBashResult对非后台、非错误的结果先解析出退出标记再返回card: terminaloutputexitCode/signal后台确认与执行错误则返回 generic 围栏卡片。3. 桥接映射当客户端声明了_meta.terminal_output能力时桥接层将展示结构映射为ACP 消息映射内容tool_callcontent: […, { type: terminal, terminalId }]工具的任何content如描述渲染在终端块之前_meta.terminal_info.{ terminal_id, cwd }tool_call_update_meta.terminal_output.{ terminal_id, data }捕获的输出_meta.terminal_exit.{ terminal_id, exit_code \| signal }解析后的退出两个值得注意的细节update 的文本content被省略。因为 ACP 的tool_call_update.content会替换调用的 content 集合重新发送围栏块会覆盖终端内容块——这与纯文本路径的“追加输出”语义相反。terminalId由 harness 的callId派生稳定且每次调用唯一绝不跨调用复用。当能力未声明时桥接层行为不变在调用上发送描述内容块在 update 上发送既有的console文本内容——文本回退是对其他所有客户端的契约。4. 退出信息从渲染输出中解析这是一个非显而易见的约束纯presentResult(args, result)seam 只能看到内容块拿不到结构化的ShellRunResult。因此dsh-tool-bash通过解析renderResult追加的状态标记[exit code: N]/[killed by signal: …]来恢复结构化退出信息。解析与标记发射是精确的逆操作且二者在同一文件中共同演进标记发射方packages/shell/tool-bash/src/render.ts 的renderResult——输出体之后按顺序追加沙箱拒绝标记、超时标记[timed out after Nms]、信号标记[killed by signal: X]或非零退出标记[exit code: N]解析方packages/shell/shell/src/render.ts 的parseExitStatus——锚定行尾用正则在\n[killed by signal: …]$/\n[exit code: \d]$处切分无匹配则视为干净的 exit 0。要求前导换行与字符串结尾避免把普通输出中恰好以标记样文本结尾的内容误判为失败。一个往返测试见 packages/shell/tool-bash/tests/tools.spec.ts守护这对关系对每种renderResult输出把渲染文本喂回presentResult必须恢复出匹配的结构化退出同时断言被解析吞掉的标记已从输出体中移除保证带退出 pill 的卡片不会把同一状态显示两次。另外没有新增执行路径也没有实时流式传输输出在完成时附加来自 agent 自身的tool/result不逐 token 流式传输。资源释放不受影响桥接层从未创建客户端侧终端因此无需新增拆除逻辑。曾考虑的替代方案ACP 客户端侧终端子协议terminal/create明确否决。编辑器执行进程会绕过dsh-bash的环境清理、后台任务所有权和按会话的 cwd并把执行分叉到两个后端。两个参考 agent 以同样的方式否决了它agent 侧执行加_meta约定是在保持 harness 执行策略的同时获得终端卡片的唯一形态。通过事件 schema 传递结构化退出信息否决改用标记往返方案。纯presentResult(args, result)seam 只能看到内容块而解析是标记发出的精确逆操作二者在同一文件中共同演进由往返测试守护。后果与权衡Zed 约定的_meta键终端卡片依赖 Zed 特有的键terminal_info/terminal_output/terminal_exit位于 ACP 规范认可的_meta扩展点内而非 ACP 终端子协议。不识别这些键的客户端仍然获得文本回退能力门控确保仅在客户端通过_meta.terminal_output声明支持时才发出这些键因此非 Zed 客户端不会变差。如果 ACP 日后标准化了 agent 执行的终端则迁移到该标准并移除约定键。能力诚实仅在客户端声明了_meta.terminal_output时才发出终端元数据文本回退是对其他所有客户端的契约绝不可退化。这由一个无能力测试覆盖断言console路径对应测试见 packages/acp/acp/tests/bridge.spec.ts该处构造了clientCapabilities: { _meta: { terminal_output: true } }的初始化请求。terminalId 冲突从每次调用的callId派生保证在会话内唯一且在 call/result 对之间稳定绝不跨调用复用。退出信息从渲染文本解析退出信息通过解析renderResult的状态标记恢复exit_code/signal而非通过事件 schema 传递结构化退出。解析是标记发出的精确逆操作且位于同一文件往返测试固定了这对关系标记格式变更若破坏解析则测试套件失败。如果标记格式日后需要与退出信息分道扬镳则改为在 result 事件上暴露结构化退出。提供方无关词汇的蔓延终端展示结构扩大了dsh-tools的接口面。约束是保持其中立性不让 ACP 类型泄漏到dsh-tools且只提供第二个 UI 消费方同样需要的丰富度。超出范围 / 非目标文本块基线仍为无能力声明时的默认行为。以下两项后续工作有意不在该设计中构建各自需要单独的 Agent Note实时增量流式传输在分片到达时发出_meta.terminal_output_delta需要在dsh-bash上新增增量输出 seam当前设计刻意不做逐 token 流式命令分类将cat/sed解析为带文件位置的read卡片、将grep解析为search回退到终端卡片——仅展示绝不改变实际执行内容。在仓库中继续深入展示词汇契约packages/core/tools/src/presentation.tsTerminalCallView/TerminalResultView与 packages/core/tools/src/index.tspresentCall/presentResult的定义与“纯函数、可在回放时调用”的约束bash 工具的呈现实现packages/shell/tool-bash/src/index.tspresentBashCall/presentBashResult与 packages/shell/tool-bash/src/render.tsrenderResult标记发射退出解析逆操作packages/shell/shell/src/render.tsparseExitStatus往返与门控测试packages/shell/tool-bash/tests/tools.spec.tspresentCall/presentResult 全景断言与 packages/acp/acp/tests/bridge.spec.ts桥接层行为演进脉络本篇所记设计已被 ACP 作为仅面向自动化的协议 取代——桥接层不再把终端元数据投影为编辑器卡片但工具渲染意图对 UI 传输层如 Web 客户端仍然可用早期桥接层完整设计见 2026-06-14 ACP Agent Note。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考