Files
deepseek-harness/.agents/notes/implemented/feature/2026-07-26-code-dispatch-ui-foundation.zh.md
Huanqi Cao e56b1ccab2 refactor(loader): tighten the disabled gate and rehome the note
Address review: the gate module docstring now states the actual evaluation
contexts (config after injections against the plugin context, disabled at
every mount decision against the loader context); metadataExpressionErrors
rejects expressions nested below disabled and syntax-checks the disabled
expression itself so an unparseable gate fails at the gate instead of the
boot. The tutorial's !!js claims follow, and the loader note moves to
implemented/architecture with its inbound links retargeted.
2026-08-11 18:52:52 +08:00

5.0 KiB
Raw Blame History

Agent Note: Code Mode 的 UI 基础——run_code 的 description 参数,以及与原生同等保真的分发日志

Status: implemented

English | 中文

范围:让 UI 能以与原生工具调用相同的保真度渲染 Code Mode 轮次的宿主侧约定变更,即其他 Code Mode UI Agent Note 赖以构建的基础。传输设计归 Code Mode 基础所有;模型可见的 description 参数、携带完整内容的 tool/code-dispatch 载荷,以及 dsh 配置树上临时的 DSH_TOOLS_MODE 启用开关,归本篇所有。

问题

run_code 轮次过去在每个产品界面上都不透明。调用卡片的标题就是原始程序文本,在行宽内无法阅读;而且不同于 bash(其必填的 description 用作卡片标签,命令本身放在展开后的输入里),run_code 完全没有模型撰写的标签。tool/code-dispatch 事件过去只携带每个子调用的 resultSummary(上限 200 字符、经 cwd 归一化),因此任何 UI 都无从展示子调用实际返回的内容Web 对话视图(chat 子调用行)会用渲染原生 tool/result 卡片的同一批组件来渲染子调用,而有界摘要无法支撑一张与原生同等保真的卡片。同时,dsh web 组合此前根本无法启用 Code Modetools 行钉死在 schema 默认值上,配置树里也完全没有该运行时。

决策

三项变更,每项对应一个障碍:

  1. run_code 新增必填的 description 参数(与 bash 完全相同的约定主动语态、5-10 个词、展示在 UI 中;仅含空白的取值在执行时被拒绝)。presentCall 现在以该 description 作为卡片标题,并把程序文本移入 rawInput。提示词侧的成本是每次调用多出几个 token换来的是每个表面——TUI 卡片、ACPAgent Client Protocol标题、Web 行——都无需解析 TypeScript 就能获得可供人阅读的标签。
  2. tool/code-dispatch 记录子调用面向模型的完整结果content: ContentBlock[]isError,即 tool/result 的词汇),取代 resultSummary,并把摘要与 cwd 归一化机制彻底删除。UI 渲染子调用走的代码路径与渲染原生结果完全相同,包括错误文本和非文本块。该事件保持仅日志(deriveMessages() 忽略它):模型上下文没有任何变化。
  3. dsh 配置树上的 DSH_TOOLS_MODE 环境变量native|code|both;未设置时保持 schema 默认值):tools 行通过 !!js 读取它worker 代码运行时则无条件挂载(本项交付时 loader 元数据仍是静态的,因此不存在条件行;后来的 disabled 插值决策 让条件行成为可能但此处不变——native 启动只是注册该服务worker 要到每次运行时才 spawn。这是一个明确标注为临时的配置钩子设计目标是让 Web UI 拥有按会话的工具模式选择,该目标落地后,这个环境变量随即退役。

曾考虑的替代方案

保留有界摘要(提高上限,或上限加 truncated 标志)。 否决:本堆叠 PRPull Request链已敲定的要求是子调用的行与详情必须与原生调用渲染得完全一致;任何上限都会强制引入第二条降级的渲染路径,外加截断 UI。转而接受的代价是读取大文件的程序会把渲染后的内容原样记录在分发事件上不设上限、位于 spill 策略之外,并以同样的字节数增大会话日志。持久化副本的 spill 集成已作为 code-dispatch 日志 spill 交付。

一个 --tools-mode CLI命令行界面标志或 profile 配置键。 推迟而非否决标志语法暗示永久性profile JSON 又是用户配置;两者都会固化这个 seam而按会话选择的设计本就打算移除它。环境变量则如实呈现了它权宜之计的本质。

记录规范 value,而非渲染后的 content 否决:tool/result 持久化的是内容而非值(见规范输出约定),与原生同等保真意味着与之精确对齐;值始终仅存在于执行期本地。

后果

会话格式保持 SESSION_FORMAT_VERSION 为 0预发布阶段的变动不递增版本号携带 resultSummary 的旧日志只是多出一个不被读取的字段并缺少 contentv0 不作任何兼容性承诺)。既有的 Code Mode 快照 fixture测试前置数据已重新录制。模型可见表面扩大了run_code 的 schema新增一个必填参数以及每一份 Code Mode 系统提示词/工具 schema 快照都发生了变化。Web UI 工作直接构建在新的事件载荷之上;每个子调用的实时运行状态已把本事件重塑为一对分发 start/end 事件(实时并行分发)。