docs(notes): finalize Chinese pair for the sub-call rows note

This commit is contained in:
Tianyi Cui
2026-07-26 04:24:13 +08:00
parent 13f7c62318
commit 526651cb88
2 changed files with 10 additions and 4 deletions

View File

@@ -0,0 +1,6 @@
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write
2026-07-26-code-mode-chat-subcall-rows.md: 7d666f0a9e4b8bdb9bd6f5d0d0984fee0c4b21e2
2026-07-26-code-mode-chat-subcall-rows.zh.md: fb9b0c62bb702cfdb7ba3c8ccce73d8e43f29c1b

View File

@@ -14,10 +14,10 @@ Status: implemented
**子调用是 surface 流之外单独索引的 `ToolResultNode`,经由与原生行相同的 keyed slot 渲染,以始终可见的方式嵌套在父行之下。**
- **数据层**`Session.applyEventSideEffects` 把窗口内的每条 `tool/code-dispatch` 折入 `ConversationSnapshot.codeDispatches: ReadonlyMap<parentCallId, readonly CodeSubCall[]>`,其中 `CodeSubCall` 本身就是 `ToolResultNode`(子调用 id 充当 `callId`,已记录的参数经 JSON 字符串化写入 `call.argsRaw`,完整记录的 `content`/`isError` 原样携带。live mux 帧与历史回放构建出同一份索引(`rebuildDerivedFromWindow` 先清空再重新推导;父级写时复制copy-on-write数组保持快照引用 memo 稳定)。子调用永不进入 `nodes`——surface 流始终精确等于模型可见的轮次结构。该事件在协议(wire消费方边界作结构性收窄dsh-tools 的 host 类型进不了 client 程序——host/client 两侧的 `Context` 声明合并会冲突),姿态与所有跨协议载荷一致。
- **数据层**`Session.applyEventSideEffects` 把窗口内的每条 `tool/code-dispatch` 折入 `ConversationSnapshot.codeDispatches: ReadonlyMap<parentCallId, readonly CodeSubCall[]>`,其中 `CodeSubCall` 本身就是 `ToolResultNode`(子调用 id 充当 `callId`,已记录的参数经 JSON 字符串化写入 `call.argsRaw`,完整记录的 `content`/`isError` 原样携带。live mux 帧与历史回放构建出同一份索引(`rebuildDerivedFromWindow` 先清空再重新推导;父级写时复制copy-on-write数组保持快照引用 memo 稳定)。子调用永不进入 `nodes`——surface 流始终精确等于模型可见的轮次结构。该事件在 wire 消费方边界作结构性收窄dsh-tools 的 host 类型进不了 client 程序——host/client 两侧的 `Context` 声明合并会冲突),姿态与所有跨 wire 载荷一致。
- **渲染层**`ChatView``CallRow` 先渲染父行,随后对索引中出现的父级渲染一组 `[data-subcalls]` 嵌套的 `SubCallRow`,每一行都经由同一个 `'conversation.chat.toolview'` keyed 孔位、以 `entryKey = sub-tool name` 分发,并共用同一个 `GenericToolCard` fallback。与原生行的同一性由构造保证一个 keyed 注册(例如 bash 样例)接管子行与接管顶层行的方式完全相同,注册本身零改动。运行中的父调用(`runningCalls`也以同样的方式嵌套目前已产生的分发因此子行在运行期间实时流入PR1 在每次分发完成时即记录该分发)。
- **`run_code` 的呈现**:新增一种 `code` 行变体(分类器映射 `run_code → code`、标题 `Code`、图标 `IconCodeOutline16`:摘要使用模型撰写的 `description`,展开后显示程序本身(在 markdown 代码块填充上以等宽字体呈现),而不是参数的 JSON 信封。
- **details 面板**`materialFor` 按 nodes → runningCalls → 分发索引的顺序逐级回落,因此被选中的子调用 callId 会经由与原生已完结调用完全相同的渲染路径,解析出完整参数与完整输出。
- **`run_code` 的呈现**:新增一种 `code` 行变体(分类器映射 `run_code → code`、标题 `Code`、图标 `IconCodeOutline16`,以模型撰写的 `description` 作摘要,展开后显示程序本身(在 markdown 代码块填充底色上以等宽字体呈现),而参数的 JSON 信封。
- **details 面板**`materialFor` 按 nodes → runningCalls → 分发索引的顺序逐级回落,因此被选中的子调用 callId 会经由与已完结的原生调用完全相同的渲染路径,解析出完整参数与完整输出。
## 曾考虑的替代方案
@@ -29,4 +29,4 @@ Status: implemented
## 后果
自定义 toolview 注册免费适用于子调用——而且是刻意为之:除了组件自行读取上下文之外,不存在按注册粒度的 opt-out 手段,而当前没有任何消费方需要。选中高亮经由同一条 `selectedCallId` 通道到达嵌套行分组归属判断会同时检验两个层级。trajectory/waterfall 仍把 `run_code` 渲染为单独一行——它们的子调用 span 推迟到增加分发计时start/end 事件)的那个 PR缺少计时waterfall 上的 span 就是谎。fixture测试前置数据的轮次 64`?fixture`),加上 `code-mode-round` 浏览器 e2e录制的真实 round、无密钥回放共同锁定完整的产品表面jsdom 套件则锁定 slot 分发、错误状态、details 解析与索引引用稳定性。
自定义 toolview 注册免费适用于子调用——而且是刻意为之:不存在按注册粒度的 opt-out,唯一的出路是组件自行读取自身上下文,而当前没有任何消费方需要这么做。选中高亮经由同一条 `selectedCallId` 通道到达嵌套行分组归属判断会同时检验两个层级。trajectory/waterfall 仍把 `run_code` 渲染为单独一行——它们的子调用 span 推迟到增加分发计时start/end 事件)的那个 PR缺少计时waterfall 上的 span 就是在撒谎。fixture测试前置数据的轮次 64`?fixture`),加上 `code-mode-round` 浏览器 e2e录制的真实 round、无密钥回放共同锁定整个表面jsdom 套件则锁定 slot 分发、错误状态、details 解析与索引引用稳定性。