mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
docs(i18n): re-translate RFC batch with the prompt-v4 pipeline
146 篇 RFC 译文按 v4 基线(#348)重出:v4 模板+术语表、金标 few-shot、三段协议、切换行后处理;全量机械核对零异常(一处 task id 术语违规已修)。三篇超长 RFC(code-mode 已入,web-seam/ agent-scope/sandbox/cds-core 仍在长文档通道产出)随后补。
This commit is contained in:
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-assembled-assistant-messages-only.md: 7605f286cf5914a127f5f8e2b77490648b42cc30
|
||||
2026-06-20-assembled-assistant-messages-only.zh.md: e282c5bd74fd3b854c85112d64de44a5470007bc
|
||||
2026-06-20-assembled-assistant-messages-only.zh.md: 05f15ffadba4607bc64fdf2f7eefdbcc41cf03a3
|
||||
|
||||
@@ -1,36 +1,36 @@
|
||||
# RFC:只持久化已组装的 assistant 消息,不持久化流式分片
|
||||
|
||||
Status: rejected — high-fidelity chunk replay, partial failed streams, and snapshot replay currently depend on persisted `assistant/chunk` events. Dropping chunks is only viable with a no-information-loss replay/artifact replacement.
|
||||
# RFC:仅持久化组装后的 assistant 消息,不存储流式分片
|
||||
|
||||
[English](2026-06-20-assembled-assistant-messages-only.md) | 中文
|
||||
|
||||
Status: rejected — high-fidelity chunk replay, partial failed streams, and snapshot replay currently depend on persisted `assistant/chunk` events. Dropping chunks is only viable with a no-information-loss replay/artifact replacement.
|
||||
|
||||
## 问题
|
||||
|
||||
当前的规范会话日志会逐条持久化模型流出的每个 `assistant/chunk`。[会话持久化 RFC](../../implemented/architecture/2026-06-14-session-persistence.md) 选择这一方案是为了 token 级别的回放保真度和连续的 `seq`,但代价日益增长:JSONL fixture(测试前置数据)被大量微小的 delta 记录占据;快照场景通过分组 chunk 事件来回放模型;ACP 加载时需要从 chunk 重建先前的 assistant 输出;任何未来的日志读取方都必须区分持久的消息历史与 token 级别的追踪。
|
||||
当前的规范会话日志会持久化模型流式输出的每一个 `assistant/chunk`。[会话持久化 RFC](../../implemented/architecture/2026-06-14-session-persistence.md) 选择这一方案是为了 token 级别的回放保真度和连续的 `seq`,但其代价日益增长:JSONL fixture(测试前置数据)被大量微小的 delta 记录占据,快照场景通过分组 chunk 事件来回放模型,ACP(Agent Client Protocol)加载时从 chunk 重建先前的 assistant 输出,而任何未来的日志读取方都必须区分持久的消息历史与 token 级别的追踪。
|
||||
|
||||
对于成功完成并组装出完整内容的步骤,agent loop(智能体循环)已经追加了一条 `assistant/message`。这正是 `deriveMessages()` 用来构造下一次模型请求的事件。换言之,正常的可恢复对话状态已经存在,无需 chunk;chunk 是实时渲染和确定性测试的产物,不是必需的对话历史。失败或中止的流则不同:部分 assistant 输出可能仅以 chunk 形式存在,而空的 max-token 步骤可能根本不产生 `assistant/message`。
|
||||
对于成功组装出完整内容的步骤,agent loop(智能体循环)已经追加了一条 `assistant/message`。这正是 `deriveMessages()` 用来构造下一次模型请求的事件。换言之,正常的可恢复会话状态无需 chunk 即已具备;chunk 是实时渲染和确定性测试的产物,不是必需的会话历史。失败或中止的流则不同:部分 assistant 输出可能仅以 chunk 形式存在,而空的 max-token 步骤可能根本不产生 `assistant/message`。
|
||||
|
||||
## 提案
|
||||
|
||||
停止在规范会话日志中存储 `assistant/chunk`。持久日志只保留 `assistant/message`、`tool/call`、`tool/result`、保留的 `usage`,以及轮次边界。实时 UI 仍可通过一个刻意设计为瞬态的流事件接收 token 增量。快照回放应将其模型脚本移入显式的 fixture 伴随文件,或从已记录的适配器产物派生,而不是把规范的用户会话当作 token 磁带。需要部分失败流输出的场景必须在回放 fixture 中记录该输出。
|
||||
停止在规范会话日志中存储 `assistant/chunk`。持久日志保留 `assistant/message`、`tool/call`、`tool/result`、`usage`(如保留)以及轮次边界。实时 UI 仍可通过一个刻意设计为瞬态的流事件接收 token 增量。快照回放应将其模型脚本移入显式的 fixture 伴随文件,或从记录的适配器产物中派生,而非将规范的用户会话当作 token 磁带。需要部分失败流输出的场景必须在回放 fixture 中记录该输出。
|
||||
|
||||
ACP 的 `session/load` 可以将先前的 assistant 消息作为完整内容块回放,而不是模拟原始的 token 流。加载的 transcript(文本记录)不必重现每一个历史 delta;它必须展示相同的已完成 assistant 内容,并以有效的提供方历史恢复对话。
|
||||
ACP `session/load` 可以将先前的 assistant 消息作为完整内容块回放,而非模拟原始的 token 流。加载后的 transcript(文本记录)无需重现每一个历史 delta;它必须展示相同的已完成 assistant 内容,并以有效的 provider 历史恢复运行。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `SessionEventMap` 移除 `assistant/chunk`,或在需要过渡性实时事件时将其标记为不持久化。
|
||||
- [会话持久化文档](../../../../packages/session-persistence/session-persistence/README.md)不再要求逐条存储每个流式分片。
|
||||
- `llm-replay` 与 ACP 快照使用显式的回放 fixture 格式或伴随文件来承载模型 chunk。
|
||||
- `SessionEventMap` 移除 `assistant/chunk`,或在需要过渡性实时事件时将其标记为非持久化。
|
||||
- [会话持久化文档](../../../../packages/session-persistence/session-persistence/README.md)不再要求逐字存储每个流式分片。
|
||||
- `llm-replay` 和 ACP 快照使用显式的回放 fixture 格式或伴随文件来存储模型 chunk。
|
||||
- `session/load` 从 `assistant/message` 渲染已完成的 assistant 消息。
|
||||
- 存储的日志大幅缩小,且在没有 chunk 空洞的情况下保持 `seq` 连续。
|
||||
- 会话格式版本与已记录的 fixture 一并刷新;按预发布格式策略拒绝非当前版本的存储日志。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
规范的用户会话不再能重建旧轮次的精确 token 流。它还会丢失失败或中止流的部分 assistant 输出,除非有其他事件或 fixture 记录了它。对于当前的恢复、加载和快照契约而言,这是过大的信息损失。需要精确确定性流的测试应当自行拥有该 fixture,前提是生产会话日志为用户可见的恢复保留了足够的保真度。
|
||||
规范的用户会话不再能重建旧轮次的精确 token 流。它也会丢失失败或中止流的部分 assistant 输出,除非另有事件或 fixture 记录。对于当前的恢复、加载和快照契约而言,这是过大的信息损失。需要精确确定性流的测试应当直接拥有该 fixture,前提是生产会话日志为用户可见的恢复保留了足够的保真度。
|
||||
|
||||
## 相关
|
||||
|
||||
本 RFC 取代[会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md)中关于 chunk 持久化的决策,并影响 [ACP 快照测试](../../implemented/testing/2026-06-19-acp-snapshot-tests.md)——其当前的回放插件从 `assistant/chunk` 事件派生脚本。
|
||||
本 RFC 取代 [会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md) 中关于 chunk 持久化的决策,并影响 [ACP 快照测试](../../implemented/testing/2026-06-19-acp-snapshot-tests.md)——其当前的回放插件从 `assistant/chunk` 事件派生脚本。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-drop-acp-session-load.md: 39f24d313db6083db45ff6fbc4a84f504e7714cb
|
||||
2026-06-20-drop-acp-session-load.zh.md: 003c66636a75e21199f3c3ac600867cf9b73b87c
|
||||
2026-06-20-drop-acp-session-load.zh.md: b7339f492d5f6b7e2daab5820dada0fa2b5fe823
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
# RFC:移除 ACP session/load,待恢复功能具备产品形态后再引入
|
||||
|
||||
Status: rejected — Zed is the current target ACP client, advertises and exercises load-capable sessions, and keeps pending-load state for concurrent `session/load`. The bridge should keep `session/load` and make the resume contract solid.
|
||||
# RFC:移除 ACP session/load,直到 resume 具备产品形态
|
||||
|
||||
[English](2026-06-20-drop-acp-session-load.md) | 中文
|
||||
|
||||
Status: rejected — Zed 是当前目标 ACP 客户端,它声明并使用支持 load 的会话,且为并发 `session/load` 维护 pending-load 状态。bridge 应保留 `session/load` 并使 resume 契约更加稳固。
|
||||
|
||||
## 问题
|
||||
|
||||
ACP(Agent Client Protocol)当前通告 `loadSession: true` 并实现了 `session/load`:向 bridge 注入持久化能力、校验 cwd 与存储元数据的一致性、从持久化日志重建 agent、并向客户端回放先前的 transcript(文本记录)更新。这条路径有自己的竞态处理、loading-id 守卫、回放展示逻辑和测试。它还依赖规范日志保留足够的 UI 数据来重建旧的分片和工具展示。
|
||||
ACP(Agent Client Protocol)声明 `loadSession: true` 并实现 `session/load`:向 bridge 注入持久化能力、校验 cwd 与存储元数据的一致性、从持久化日志重建 agent(智能体),并向客户端回放先前的 transcript(文本记录)更新。该路径有自己的竞态处理、loading-id 守卫、回放展示逻辑和测试。它还依赖规范日志保留足够的 UI 数据,以重建旧的分片和工具展示。
|
||||
|
||||
持久化本身仍是基础能力,但编辑器可见的恢复功能尚未经过产品流程设计。目前没有会话选择器、没有标题/预览元数据,对加载失败或部分加载也没有清晰的用户体验。bridge 正在为一个仅由测试、文档和当前目标客户端的会话模型所使用的功能承担复杂度。
|
||||
持久化仍然是基础能力,但编辑器可见的 resume 尚未经过产品流程设计。目前没有会话选择器、没有标题/预览元数据,也没有明确的加载失败或部分加载的用户体验。bridge 正在为一个仅被测试、文档和当前目标客户端的会话模型所使用的功能付出复杂度代价。
|
||||
|
||||
## 提案
|
||||
|
||||
暂时只支持新建会话。`initialize` 通告 `loadSession: false` 或省略该能力,`session/load` 不予支持。持久化仍可供 agent loop(智能体循环)和测试使用;如果其他消费方需要,恢复功能仍可作为底层工厂存在。编辑器 bridge 应在具备真正的会话选择 UX 和稳定的加载 transcript 契约后,再重新引入 `session/load`。
|
||||
当前阶段,ACP 仅启动全新会话。`initialize` 声明 `loadSession: false` 或省略该能力,`session/load` 不予支持。持久化仍可供 agent loop(智能体循环)和测试使用;如果其他消费方需要,resume 仍可作为底层工厂存在。编辑器 bridge 应在具备真正的会话选择 UX 和稳定的 load transcript 契约后,再重新引入 `session/load`。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- ACP 不再仅为 `session/load` 注入 `sessionPersistence`。
|
||||
- `initialize` 不通告加载支持。
|
||||
- `session/load` 处理器、loading-id 追踪、已加载会话的 cwd 预检以及加载回放测试全部移除。
|
||||
- 快照 fixture(测试前置数据)不再依赖加载回放的展示逻辑。
|
||||
- [ACP 文档](../../../../packages/ui/acp/README.md)仅描述新建会话的支持。
|
||||
- `initialize` 不再声明 load 支持。
|
||||
- `session/load` handler、loading-id 追踪、已加载会话的 cwd 预检以及 load 回放测试均被移除。
|
||||
- 快照 fixture(测试前置数据)不再依赖 load 回放展示。
|
||||
- [ACP 文档](../../../../packages/ui/acp/README.md)仅描述全新会话的支持。
|
||||
|
||||
## 放弃了什么
|
||||
## 放弃的能力
|
||||
|
||||
编辑器无法通过 ACP 重新打开先前持久化的会话。这确实是一个有价值的产品功能,但当前实现超前于 UX 设计,且将 bridge 绑定在 token 级别的日志回放上。保留持久化但移除编辑器加载,将 bridge 收窄到它当前能干净呈现的工作流。
|
||||
编辑器无法通过 ACP 重新打开先前持久化的会话。这确实是一项产品功能,但当前实现超前于 UX 设计,且将 bridge 绑定到 token 级别的日志回放。保留持久化但移除编辑器 load,可将 bridge 收窄到它当前能干净呈现的工作流。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-drop-acp-terminal-meta.md: 4ae3b31824ece850da0ddbc004e97b21e3cb9aad
|
||||
2026-06-20-drop-acp-terminal-meta.zh.md: 62341ccae728d981400fdc22b8ec7380bbb3faf2
|
||||
2026-06-20-drop-acp-terminal-meta.zh.md: f5b3e0a4e1f37445a0b0dcbf7426806a1de89763
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
# RFC:移除 ACP 终端 `_meta` 渲染
|
||||
|
||||
Status: rejected — Zed is the current target client, and the terminal `_meta` convention is intentional Zed UX with a plain ACP fallback for other clients.
|
||||
|
||||
[English](2026-06-20-drop-acp-terminal-meta.md) | 中文
|
||||
|
||||
Status: rejected — Zed 是当前目标客户端,终端 `_meta` 约定是有意为之的 Zed UX 设计,同时为其他客户端提供纯 ACP(Agent Client Protocol)回退路径。
|
||||
|
||||
## 问题
|
||||
|
||||
ACP(Agent Client Protocol)桥接层通过 `_meta.terminal_info`、`_meta.terminal_output` 和 `_meta.terminal_exit` 实现了一套 Zed 专属的终端卡片约定。已实现的[富 ACP bash 渲染 RFC](../../implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md) 有意避开了 ACP 客户端侧的 `terminal/create`(因为 bash 执行属于 harness 的职责),但仍采用了参考 agent 的纯展示用 `_meta` 约定。这为 Zed 带来了更好的卡片效果,代价是桥接层状态、能力协商、终端 id、特殊的 update 映射、文本回退测试,以及 `dsh-tool-bash` 中的 exit-pill 解析。
|
||||
ACP 桥接层通过 `_meta.terminal_info`、`_meta.terminal_output` 和 `_meta.terminal_exit` 实现了一套 Zed 特有的终端卡片约定。已实现的[富 ACP bash 渲染 RFC](../../implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md) 刻意回避了 ACP 客户端侧的 `terminal/create`(因为 bash 执行属于 harness 职责),但仍采用了参考 agent(智能体)的纯展示 `_meta` 约定。这在 Zed 中带来了更好的卡片效果,代价是桥接状态、能力协商、终端 id、特殊的 update 映射、文本回退测试,以及 `dsh-tool-bash` 中的 exit-pill 解析。
|
||||
|
||||
回退路径已经存在:将工具调用和完成输出渲染为普通的 ACP 内容块。非 Zed 客户端本来就依赖这条路径,但 Zed 终端卡片是当前目标客户端的功能,而非投机性的装饰。
|
||||
回退路径已经存在:将工具调用和完成输出渲染为普通 ACP 内容块。非 Zed 客户端本来就依赖这条路径,但 Zed 终端卡片是当前目标客户端的功能特性,而非推测性装饰。
|
||||
|
||||
## 提案
|
||||
|
||||
忽略 `clientCapabilities._meta.terminal_output`,通过普通 ACP 内容路径渲染 bash 结果。执行仍留在 agent 侧,通过 `dsh-bash` 完成;只移除与展示相关的终端元数据。如果 ACP 日后标准化了 agent 执行的终端,或产品决定 Zed 专属展示值得维护成本,终端卡片可以回归。
|
||||
忽略 `clientCapabilities._meta.terminal_output`,通过纯 ACP 内容路径渲染 bash 结果。执行仍由 agent 侧的 `dsh-bash` 完成;仅移除展示相关的终端元数据。如果 ACP 日后标准化了 agent 执行的终端,或产品决定 Zed 特有展示值得其维护成本,终端卡片可以再回来。
|
||||
|
||||
本提案比[收拢工具自有 UI 展示](2026-06-20-generic-tool-rendering.md)更窄:如果通用的 `presentCall`/`presentResult` 保留,本提案不动它们,只移除终端子形态和 `_meta` 映射。
|
||||
本提案比[收拢工具自有 UI 展示](2026-06-20-generic-tool-rendering.md)更窄:如果通用的 `presentCall`/`presentResult` 保留,本提案不影响它们,只移除终端子形态与 `_meta` 映射。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- ACP 不再读取或存储 `_meta.terminal_output` 能力状态。
|
||||
- `TerminalRendering`、终端 id、终端 cwd 解析以及 `_meta.terminal_*` update 映射从 `@deepseek-ai/dsh-acp` 中消失。
|
||||
- `ToolTerminal` 从 `@deepseek-ai/dsh-tools` 中消失,或在展示清理中因无使用而删除。
|
||||
- `TerminalRendering`、终端 id、终端 cwd 解析与 `_meta.terminal_*` update 映射从 `@deepseek-ai/dsh-acp` 中消失。
|
||||
- `ToolTerminal` 从 `@deepseek-ai/dsh-tools` 中消失,或在展示清理中因未使用而删除。
|
||||
- Bash 结果展示不再为终端 pill 解析退出状态。
|
||||
- 已实现的[富 ACP bash 渲染 RFC](../../implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md) 保留在 `implemented/` 中作为已交付的历史记录,如被本提案取代则互相交叉引用。
|
||||
- 已实现的[富 ACP bash 渲染 RFC](../../implemented/feature/2026-06-18-acp-terminal-and-tool-rendering.md) 作为已交付历史保留在 `implemented/` 中;如被本提案取代,则加上交叉链接。
|
||||
|
||||
## 放弃的内容
|
||||
|
||||
Zed 用户将失去专属终端卡片:没有 cwd 头部、终端展示或 exit pill。他们仍能以普通内容形式看到命令和输出。在 ACP 桥接层尚未发布、`_meta` 键仍是约定而非标准的阶段,这是合理的简化。
|
||||
Zed 用户将失去专用终端卡片:没有 cwd 头部、终端展示或 exit pill。他们仍能以纯内容形式看到命令和输出。在 ACP 桥接层尚未发布、`_meta` 键只是约定而非标准的阶段,这是合理的简化。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-drop-bash-output-spill-files.md: bbc26c645cefb1659012ca0debda78fc6850d276
|
||||
2026-06-20-drop-bash-output-spill-files.zh.md: 1439616bf55ad388e69ba693cbc7c130f4e2fc8c
|
||||
2026-06-20-drop-bash-output-spill-files.zh.md: 43b6029a68542d03027b61424a2a3024ace200d5
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
# RFC:移除 bash 完整输出溢出文件
|
||||
|
||||
Status: rejected — full-output recovery is a real bash behavior. A future artifact/blob service may generalize it, but dropping spill files before that replacement would lose useful command output.
|
||||
|
||||
[English](2026-06-20-drop-bash-output-spill-files.md) | 中文
|
||||
|
||||
Status: rejected — full-output recovery is a real bash behavior. A future artifact/blob service may generalize it, but dropping spill files before that replacement would lose useful command output.
|
||||
|
||||
## 问题
|
||||
|
||||
`dsh-bash-local` 在内存中保留有界的输出,并将大体积的 stdout/stderr 流溢出到私有临时文件。这要求维护一个私有目录、创建仅所有者可读的随机文件、处理关闭失败、按字节偏移增量读取、报告有损读取、在面向模型的文本中渲染路径,以及清理纪律。当输出被截断时,工具会告诉模型去读取一个本地溢出路径。
|
||||
`dsh-bash-local` 在内存中保留有界的输出,并将大体量的 stdout/stderr 流溢出到私有临时文件。这要求一个私有目录、仅所有者可写的随机文件创建、关闭失败处理、基于字节偏移的增量读取、有损读取报告、在面向模型的文本中渲染路径,以及清理纪律。当输出被截断时,该工具会告知模型去读取一个本地溢出路径。
|
||||
|
||||
这解决了一个真实问题,但方式狭窄且有泄漏。溢出路径是一个暴露在模型输出中的进程本地文件系统产物,而非具备作用域访问、保留策略或 UI 能力的持久化 harness 产物。它还使后台任务的读取变得复杂,因为有损增量读取必须指向一到两个溢出文件。
|
||||
这解决了一个真实问题,但方式狭隘且有泄漏。溢出路径是一个暴露在模型输出中的进程级文件系统产物,而非具有作用域访问控制、保留策略或 UI 支持的持久化 harness 产物。它还使后台任务的读取变得复杂,因为有损增量读取必须指向一个或两个溢出文件。
|
||||
|
||||
## 提案
|
||||
|
||||
保留尾部截断,移除完整输出溢出文件。bash 结果包含有界的尾部内容加一个明确的截断标记;不输出路径。如果用户需要恢复完整输出,则添加一个通用的产物/blob 服务(具备显式的所有权、清理和 UI 渲染),再让 bash 将大体积输出附加到该服务。
|
||||
保留尾部截断,移除完整输出溢出文件。bash 结果包含有界的尾部内容加一个明确的截断标记;不输出路径。如果用户需要恢复完整输出,则添加一个通用的产物/blob 服务(具有明确的所有权、清理和 UI 渲染),然后让 bash 将大体量输出附加到该服务。
|
||||
|
||||
本提案可以独立于[通用长时运行工具运行时](../../proposed/architecture/2026-06-20-generic-long-running-tool-runtime.md)落地。如果后台任务保留,`bash_output` 仍应报告输出已被丢弃,但不再公布溢出路径。
|
||||
本提案可以独立于[通用长时间运行工具运行时](../../proposed/architecture/2026-06-20-generic-long-running-tool-runtime.md)落地。如果后台任务保留,`bash_output` 仍应报告输出已被丢弃,但不再提供溢出路径。
|
||||
|
||||
## 验收标准
|
||||
|
||||
@@ -24,8 +24,8 @@ Status: rejected — full-output recovery is a real bash behavior. A future arti
|
||||
- 测试覆盖尾部截断,不再断言完整输出文件的内容。
|
||||
- [docs/defensive-patterns.md](../../../defensive-patterns.md) 中的安全指导不再将私有溢出文件视为面向模型的接口。
|
||||
|
||||
## 放弃了什么
|
||||
## 放弃的能力
|
||||
|
||||
模型或用户无法再从临时文件恢复大体积命令输出中被省略的前缀。在真正的产物服务出现之前,这是可接受的。当前的溢出路径为一个生命周期和权限都未经设计的功能引入了过多的定制机制。
|
||||
模型或用户无法再从临时文件恢复大体量命令输出中被省略的前缀。在真正的产物服务出现之前,这是可以接受的。当前的溢出路径为一个生命周期和权限均未经设计的功能引入了过多的定制机制。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-drop-durable-step-boundaries.md: fba8ad4211db69d3a04d253fd9544caca0f538c6
|
||||
2026-06-20-drop-durable-step-boundaries.zh.md: 9ffa12cfba697f1e3bc9059529d0fdf97f595705
|
||||
2026-06-20-drop-durable-step-boundaries.zh.md: e389c5506b03a472c74853f3b73c21681f96287f
|
||||
|
||||
@@ -1,32 +1,32 @@
|
||||
# RFC:移除持久化的步骤边界事件
|
||||
|
||||
Status: rejected — `step/end` is the durable indication that a model step finished, and keeping the symmetric `step/start` / `step/end` pair makes crash repair, invariants, and transcript inspection clearer than inferring completion from adjacent step-scoped events.
|
||||
|
||||
[English](2026-06-20-drop-durable-step-boundaries.md) | 中文
|
||||
|
||||
Status: rejected — `step/end` 是模型步骤已完成的持久化标识,保留对称的 `step/start` / `step/end` 对,在崩溃恢复、不变式检查和 transcript(文本记录)审查方面,都比从相邻的步骤级事件推断完成状态更清晰。
|
||||
|
||||
## 问题
|
||||
|
||||
会话日志存储了 `step/start` 和 `step/end` 事件,尽管每个步骤级事件本身已携带 `{ turn, step }`:assistant 分片、assistant 消息、工具调用、工具结果、token 用量和错误。`deriveMessages()` 忽略步骤边界,ACP(Agent Client Protocol)在 UI 层也忽略它们,主要消费方是不变式检查、测试、快照 golden 文件和崩溃恢复。
|
||||
会话日志存储了 `step/start` 和 `step/end` 事件,尽管每个步骤作用域的事件本身已经携带 `{ turn, step }`:assistant 分片、assistant 消息、工具调用、工具结果、用量和错误。`deriveMessages()` 忽略步骤边界,ACP(Agent Client Protocol)在 UI 层面也忽略它们,主要消费方是不变式检查、测试、快照 golden 文件和崩溃恢复。
|
||||
|
||||
被否决的论点是:边界事件让日志更像仪式而非信息。实际上,`step/end` 是具体信息:读者无需从下一个事件推导,就能判断一次模型请求是已完成、已崩溃还是正在被修复。同样,一条孤立的 `step/start` 对于「模型请求已发起但在产出任何分片之前就失败了」的场景也有用。
|
||||
被否决的论点是:边界事件使日志更像仪式而非信息。实际上,`step/end` 是具体信息:读者无需从下一个事件推导状态,就能判断一次模型请求是已完成、已崩溃还是正在修复。同样,一个孤立的 `step/start` 对于「模型请求已发起但在产生任何分片之前就失败了」的场景也有价值。
|
||||
|
||||
## 提案
|
||||
|
||||
以轮次作为唯一的持久化边界。从 `SessionEventMap` 中移除 `step/start` 和 `step/end`;保留步骤级事件上用于分组的数值 `step` 字段。agent loop(智能体循环)递增步骤计数器,并以该编号记录步骤级事件,但不再追加开/关边界事件。消费方通过共享 `(turn, step)` 的连续事件推断步骤分组。
|
||||
将轮次作为唯一的持久化边界。从 `SessionEventMap` 中移除 `step/start` 和 `step/end`;在需要分组的事件上保留数值型 `step` 字段。agent loop(智能体循环)递增步骤计数器并以该编号记录步骤作用域的事件,但不再追加开/关边界事件。消费方通过共享 `(turn, step)` 的连续事件推断步骤分组。
|
||||
|
||||
不变式插件应强制步骤级事件在一个已打开的轮次内具有有效的正整数步骤编号,而非要求它们被独立的边界记录包围。崩溃恢复不应合成 `step/end`;如果一个被中断的轮次被保留,恢复路径仍可关闭该轮次而无需捏造步骤边界记录。
|
||||
不变式插件应当强制步骤作用域的事件在一个已打开的轮次内具有有效的正整数步骤编号,而非要求独立的边界记录包围它们。崩溃恢复不应合成 `step/end`;如果一个被中断的轮次被保留,修复路径仍然可以关闭该轮次而无需捏造步骤边界记录。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `SessionEventMap` 不再包含 `step/start` 或 `step/end`。
|
||||
- agent loop 不再有 `closeStep()` 终结路径。
|
||||
- agent loop 中不再有 `closeStep()` 终结路径。
|
||||
- ACP 快照和持久化契约 fixture(测试前置数据)不再期望步骤边界行。
|
||||
- `deriveMessages()` 和回放从步骤级事件推导出相同的消息历史。
|
||||
- [事件分类体系文档](../../../architecture.md)将轮次描述为持久化边界,将步骤描述为步骤级记录上的一个字段。
|
||||
- `deriveMessages()` 和回放从步骤作用域的事件推导出相同的消息历史。
|
||||
- [事件分类体系文档](../../../architecture.md)将轮次描述为持久化边界,将步骤描述为步骤作用域记录上的一个字段。
|
||||
- 会话格式版本和已记录的 fixture 被刷新;按预发布格式策略,非当前版本的已存储日志被拒绝。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
日志不再将「一次模型请求已发起但进程在产出任何事件之前就终止了」记录为持久化事实,也不再有显式的「此步骤已完成」标记。在会话日志仍是持久化回放与审计表面的当下,这一损失不可接受。
|
||||
日志不再将「一次模型请求已发起但进程死亡前未产生任何事件」记录为持久化事实,也不再有显式的「此步骤已完成」标记。在会话日志仍是持久化回放与审计表面的当下,这一损失不可接受。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-drop-unused-session-lineage.md: 4200532726a27e257e09f927240846f20a0b30ad
|
||||
2026-06-20-drop-unused-session-lineage.zh.md: c20f964317a1924c3cbc36b7f7838f3a207a65c1
|
||||
2026-06-20-drop-unused-session-lineage.zh.md: 1524987111f12a9c6e2014723bb1cb4c87bcf940
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# RFC:移除未使用的会话血缘元数据
|
||||
|
||||
Status: rejected — `parentSession` is part of the documented fork/sub-agent seam and is already preserved by the agent/session resume path. The field is future-facing, but it is not accidental dead state.
|
||||
|
||||
[English](2026-06-20-drop-unused-session-lineage.md) | 中文
|
||||
|
||||
Status: rejected — `parentSession` 是已文档化的 fork/subagent seam 的一部分,且已被 agent(智能体)/session 恢复路径保留。该字段面向未来,但并非意外的死状态。
|
||||
|
||||
## 问题
|
||||
|
||||
`SessionHeader.parentSession` 记录新会话从哪个会话 fork 而来。它在 `dsh-session` 中定义,被持久化后端保存,在 resume 路径中被复制,作为血缘元数据被文档记录,并有往返测试覆盖。然而仓库中没有任何已上线的 fork UI 或 subagent 流程读取它。计划中的 subagent/fork seam 仍是一个 TODO,因此该字段目前只是被存储的未来形状。
|
||||
`SessionHeader.parentSession` 记录新会话从哪个会话 fork 而来。它在 `dsh-session` 中定义,被持久化后端保留,在恢复流程中复制,作为血缘元数据被文档记录,并有往返测试覆盖。然而仓库中没有任何生产环境的 fork UI 或 subagent 流程读取它。计划中的 subagent/fork seam 仍是 TODO,因此该字段目前只是预存的未来形状。
|
||||
|
||||
单文件的代价虽小,但在整个格式中分布广泛:每个后端 schema 和元数据序列化器都在保存一个尚无已完成功能读取的值。由于 header 是一份磁盘契约,即便是占位字段也会成为未来重构必须维护、迁移或有意打破的东西。
|
||||
单个文件的成本虽小,但在格式层面影响面广:每个后端 schema 和元数据序列化器都在保留一个尚无已完成功能读取的值。由于 header 是磁盘契约,即使是占位字段也会成为未来重构必须维护、迁移或有意打破的东西。
|
||||
|
||||
## 提案
|
||||
|
||||
从 `SessionHeader` 中移除 `parentSession`,直到真正的 fork/resume 功能需要血缘信息时再引入。如果存在相应 API,fork 仍然可以用先前事件来初始化新会话,但持久化的父指针应当与读取它的功能和解释它的 UX 一同引入。
|
||||
从 `SessionHeader` 中移除 `parentSession`,直到真正的 fork/恢复功能需要血缘信息时再引入。如果存在相应 API,fork 仍然可以用先前事件来初始化新会话,但持久化的父指针应当与读取它的功能和解释它的 UX 一同引入。
|
||||
|
||||
如果血缘信息回归,届时再决定它应放在不可变 header 中、会话图索引中,还是作为一等事件。当前字段不应预先锁定那个设计。
|
||||
|
||||
@@ -20,12 +20,12 @@ Status: rejected — `parentSession` is part of the documented fork/sub-agent se
|
||||
|
||||
- `SessionHeader` 仅包含 version、id、createdAt 和可选的 cwd。
|
||||
- JSONL 与 SQLite 元数据 schema 不再存储 parent-session id。
|
||||
- resume 和 list API 不再往返传递 `parentSession`。
|
||||
- 恢复与列表 API 不再往返传递 `parentSession`。
|
||||
- 文档和测试移除没有生产消费方支撑的 fork 血缘声明。
|
||||
- 会话格式版本、后端 schema 版本和录制的 fixture(测试前置数据)按需刷新;按预发布格式策略,非当前版本的已存储数据将被拒绝,不提供迁移路径。
|
||||
- 会话格式版本、后端 schema 版本与记录的 fixture(测试前置数据)按需刷新;按预发布格式策略,非当前版本的存储数据将被拒绝,不提供迁移路径。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
代码库失去一个为未来 fork/subagent UX 准备好的血缘钩子。这是有意为之。该字段在功能存在时很容易重新引入,而未发布的立场允许格式变更无需迁移。
|
||||
代码库失去了一个为未来 fork/subagent UX 预备的现成血缘钩子。这是有意为之。该字段在功能存在时很容易重新引入,而未发布的立场允许格式变更无需迁移。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-fold-session-persistence-interface.md: 695cd679c67f3e0a9f901c671c33e9507ecbe279
|
||||
2026-06-20-fold-session-persistence-interface.zh.md: 1ef93fb64cc27eeeb465136dc7dac6e751a7ccfc
|
||||
2026-06-20-fold-session-persistence-interface.zh.md: 38f79f833fb5d95e4d9f392de627ee16b17cb997
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# RFC:将持久化接口合入 dsh-session
|
||||
# RFC:将持久化接口合并进 dsh-session
|
||||
|
||||
Status: rejected — the separate persistence interface package is the intended modular capability seam for durable backends. Folding it into `dsh-session` would reduce package count at the cost of a cleaner backend boundary.
|
||||
|
||||
@@ -6,26 +6,26 @@ Status: rejected — the separate persistence interface package is the intended
|
||||
|
||||
## 问题
|
||||
|
||||
`dsh-session-persistence` 是一个接口包(package),其核心概念已由 `dsh-session` 拥有:`SessionHeader`、`SessionEvent`、`SessionId`、`session/event` 和 `session/flush`。该包额外引入了抽象的 `SessionPersistence` 服务、共享写协调器和契约辅助工具。后端包依赖它,`agent-loop` 则需要可选地发现一个兄弟服务来实现恢复。
|
||||
`dsh-session-persistence` 是一个接口包(package),其核心概念已经由 `dsh-session` 拥有:`SessionHeader`、`SessionEvent`、`SessionId`、`session/event` 与 `session/flush`。该包额外添加了抽象的 `SessionPersistence` 服务、共享写入协调器和契约辅助工具。后端包依赖它,`agent-loop`(智能体循环)也需要可选地查找一个同级服务来实现恢复。
|
||||
|
||||
当持久化还是一个全新的可替换后端设计时,能力 seam 的拆分是合理的。但在可变摘要被移除之后,这个接口包基本上只是包装了会话日志自身的存储关注点。保持独立可能带来的仪式感多于清晰度。
|
||||
当持久化还是一个全新的可替换后端设计时,能力 seam 的拆分是合理的。但在可变摘要被移除之后,这个接口包基本上只是包装了会话日志自身的存储关切。继续保持独立可能带来的仪式感多于清晰度。
|
||||
|
||||
## 提案
|
||||
|
||||
将抽象的 `SessionPersistence` 服务、协调器和持久化契约辅助工具移入 `dsh-session`。JSONL 和 SQLite 仍作为独立的后端包,注册由 session 包拥有的服务。这样既保留了后端可替换性,又删除了一个支撑包和一条跨包 seam。
|
||||
|
||||
实施 PR(Pull Request)应更新[能力 seam](../../implemented/architecture/2026-06-13-capability-seams.md) 指南,补充此例外:持久化不同于 bash 或 LLM(大语言模型),因为它的词汇和生命周期事件本身就是 session 包的核心领域。
|
||||
实施 PR(Pull Request)应更新[能力 seam](../../implemented/architecture/2026-06-13-capability-seams.md) 指南,补充此例外:持久化不同于 bash 或 LLM(大语言模型),因为它的词汇和生命周期事件本就属于 session 包的核心领域。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `@deepseek-ai/dsh-session-persistence` 作为包被移除。
|
||||
- `dsh-session` 导出持久化服务类型、协调器和契约辅助工具。
|
||||
- JSONL 和 SQLite 后端包直接依赖 `dsh-session`。
|
||||
- `agent-loop` 的恢复功能使用由 session 包拥有的服务键。
|
||||
- [会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md)、[共享持久化写协调器](../../implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md)与[包文档](../../../../packages/session-persistence/session-persistence/README.md)说明后端实现为何仍保持独立。
|
||||
- `agent-loop` 的恢复功能使用 session 包拥有的服务键。
|
||||
- [会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md)、[共享持久化写入协调器](../../implemented/architecture/2026-06-18-shared-persistence-write-coordinator.md)与[包文档](../../../../packages/session-persistence/session-persistence/README.md)说明后端实现为何仍保持独立。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
`dsh-session` 变得更重:它同时拥有内存日志和持久化接口。这就是取舍。如果第三方持久化后端已经形成公开生态,独立的接口包会是更清晰的 SDK 边界;但在预发布阶段,多出的包看起来像是在有外部消费方之前的过度抽象。
|
||||
`dsh-session` 变得更重:它同时拥有内存日志和持久化接口。这就是代价。如果第三方持久化后端已经形成公开生态,独立的接口包会是更清晰的 SDK 边界;但在预发布阶段,在尚无外部消费方时,多出的包看起来更像是过早的抽象。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-generic-tool-rendering.md: 07102ed3b12d7f587b1d12f0e240c1202a2e1cdd
|
||||
2026-06-20-generic-tool-rendering.zh.md: 86ea52545a79ff975fc6b9c5d080e111a2750290
|
||||
2026-06-20-generic-tool-rendering.zh.md: d2c8c745f0ac04a01eb72b50fd1b63cb655afe36
|
||||
|
||||
@@ -6,30 +6,30 @@ Status: rejected — tool-owned presentation should wait for more real tools bef
|
||||
|
||||
## 问题
|
||||
|
||||
工具可以定义 `presentCall()` 和 `presentResult()` 回调,返回 `ToolCallPresentation`、`ToolResultPresentation` 以及可选的 `ToolTerminal` 字段。代码本身已标记出设计的混乱:title、kind、raw input、content、terminal cwd、terminal output、exit code 和 signal 逐步堆积成一堆可选字段。ACP(Agent Client Protocol)随后维护 pending call 状态以将 result 与原始 args 配对,在 `session/load` 时创建仅用于回放的 presenter,并将 terminal 子字段映射为 Zed 特有的 `_meta`。`dsh-tool-bash` 甚至从已渲染的文本中反向解析退出状态,因为纯回放安全的 presenter 已经拿不到结构化的 `BashRunResult`。
|
||||
工具可以定义 `presentCall()` 和 `presentResult()` 回调,返回 `ToolCallPresentation`、`ToolResultPresentation` 以及可选的 `ToolTerminal` 字段。代码本身就标记了这个设计的混乱:title、kind、raw input、content、terminal cwd、terminal output、exit code 和 signal 逐步增长为一堆可选字段。ACP(Agent Client Protocol)随后维护 pending call 状态以将 result 与原始 args 配对,在 `session/load` 时创建仅用于回放的 presenter,并将 terminal 子字段映射为 Zed 特有的 `_meta`。`dsh-tool-bash` 甚至从渲染后的文本中反向解析退出状态,因为纯回放安全的 presenter 已经拿不到结构化的 `BashRunResult`。
|
||||
|
||||
真正的一方使用场景是 ACP 的 bash 展示。这不足以作为冻结一个跨包 UI 展示 API 的依据。
|
||||
真正的第一方用途是为 ACP 提供 bash 展示。这不足以作为冻结一个跨包 UI 展示 API 的依据。
|
||||
|
||||
## 提案
|
||||
|
||||
暂时移除工具自有的 UI 展示回调。规范的工具事件已经携带工具名称、原始参数字符串、结果内容与错误状态。UI 从这些字段渲染一个通用的工具卡片。工具特有的富展示可以在至少有两个真实工具和两个真实消费方来验证词汇后,以 tagged render-intent union 的形式回归。
|
||||
暂时移除工具自有的 UI 展示回调。规范的工具事件已经携带工具名、原始参数字符串、结果内容和错误状态。UI 从这些字段渲染一个通用的工具卡片。工具特有的富展示可以在至少有两个真实工具和两个真实消费方来验证词汇之后,以带标签的 render-intent union 形式回归。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
一个更小的替代方案是在单个 PR(Pull Request)中将当前的可选字段包替换为一个显式 union;但如果目标是简化,更彻底的做法是删除回调、保留通用路径。
|
||||
作为更小的替代方案,可以在一个 PR(Pull Request)中将当前的可选字段集合替换为一个显式 union;但如果目标是简化,更彻底的做法是删除回调、保留通用路径。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `ToolDefinition` 移除 `presentCall` 和 `presentResult`。
|
||||
- `ToolCallPresentation`、`ToolResultPresentation`、`ToolTerminal` 和 `ToolCallKind` 消失,除非一个最小的通用 UI 类型仍需要其中之一。
|
||||
- ACP 不再维护 presenter pending 状态,也不在实时流式输出/加载回放期间调用工具回调。
|
||||
- `dsh-tool-bash` 不再解析已渲染文本来恢复退出状态以生成 UI pill。
|
||||
- 快照 golden 展示通用工具卡片和文本结果。
|
||||
- ACP 不再维护 presenter pending 状态,也不再在实时流式输出/加载回放期间调用工具回调。
|
||||
- `dsh-tool-bash` 不再解析渲染文本来恢复退出状态以供 UI pill 使用。
|
||||
- 快照 golden 文件展示通用工具卡片和文本结果。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
Bash 失去其自定义的终端风格卡片和模型撰写的描述位置。回退方案仍然合理:命令作为工具输入展示,输出作为文本展示。富展示应在产品拥有足够的 UI/工具多样性、足以支撑一份稳定的展示契约时再行设计。
|
||||
Bash 失去其自定义的终端风格卡片和模型生成描述的放置位置。回退方案仍然合理:命令作为工具输入展示,输出作为文本展示。富展示应当在产品拥有足够的 UI/工具多样性、足以支撑一份稳定的展示契约时再行设计。
|
||||
|
||||
## 相关
|
||||
|
||||
本 RFC 是[移除 ACP terminal 元数据](2026-06-20-drop-acp-terminal-meta.md)的宽泛版本。如果本 RFC 被接受,那个更窄的 RFC 就不再需要。
|
||||
这是[移除 ACP terminal 元数据](2026-06-20-drop-acp-terminal-meta.md)的宽泛版本。如果本 RFC 被接受,那个更窄的 RFC 就不再必要。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-retire-mid-turn-steering.md: bf78125ec175aa9152789bdccd1f8e8a16863a5b
|
||||
2026-06-20-retire-mid-turn-steering.zh.md: 03af2b24916a5d1a479dc06a30d54003dfa7f156
|
||||
2026-06-20-retire-mid-turn-steering.zh.md: a56e112df37bdeb75ca808f76beabe1fec8b1b7b
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
# RFC:废除中途 steering(中途引导)
|
||||
|
||||
Status: rejected — mid-turn steering is an intentional agent capability for between-step user/plugin input and future goal/loop workflows. It is complexity with a product direction, not an accidental duplicate of `send()`.
|
||||
# RFC:移除轮次中途引导
|
||||
|
||||
[English](2026-06-20-retire-mid-turn-steering.md) | 中文
|
||||
|
||||
Status: rejected — mid-turn steering is an intentional agent capability for between-step user/plugin input and future goal/loop workflows. It is complexity with a product direction, not an accidental duplicate of `send()`.
|
||||
|
||||
## 问题
|
||||
|
||||
agent(智能体)暴露了两条用户消息路径,看起来相近但生命周期语义不同:`send()` 将一条普通用户轮次排入队列,而 `steer()` 在当前运行轮次的步骤之间注入一条消息,空闲时则回退为 `send()`。这一区别渗透到整个栈:`Agent.steer()` 是公开 API,会话日志有持久化的 `steering/message` 事件,agent 事件分类体系有 `agent/steering`,循环在排队消息 FIFO 之外还维护一个 steering FIFO,取消操作需要清空两个队列,`deriveMessages()` 必须将 steering 渲染为带标签的合成用户消息而非普通提示词。
|
||||
agent(智能体)暴露了两条用户消息路径,外观相近但生命周期语义不同:`send()` 将一条普通用户轮次排入队列,而 `steer()` 在当前运行轮次的步骤之间注入一条消息,空闲时则回退为 `send()`。这一区分贯穿整个栈:`Agent.steer()` 是公开 API;会话日志有持久化的 `steering/message` 事件;agent 事件分类体系有 `agent/steering`;agent loop(智能体循环)在排队消息 FIFO 之外还维护一个 steering FIFO;取消操作需要清空两个队列;`deriveMessages()` 必须将 steering 渲染为带标签的合成用户消息,而非普通提示词。
|
||||
|
||||
continuation seam 放大了这一成本。`agent/turn-continuation` 默认为 `hadToolCalls || steeringInjected`,因此同一轮次内的 steering 消息即使模型没有请求工具调用也能强制循环再次调用模型。注释中提到了未来的 `/goal`、`/loop` 和预算守卫用途,但当前仓库没有生产级监听器;只有测试注册了该 waterfall(瀑布式事件)。另外,唯一调用 `steer()` 的生产 UI 是 stdio 演示。ACP 在轮次运行期间已经通过普通队列发送提示词。
|
||||
续行 seam 进一步放大了成本。`agent/turn-continuation` 默认条件为 `hadToolCalls || steeringInjected`,因此同一轮次内的 steering(中途引导)消息即使模型未请求工具调用,也会强制循环再次调用模型。注释中提到了未来 `/goal`、`/loop` 和预算守卫的用途,但当前仓库没有生产级监听器;只有测试注册了该 waterfall(瀑布式事件)。另外,唯一调用 `steer()` 的生产 UI 是 stdio 演示。ACP(Agent Client Protocol)在轮次运行期间已经通过普通队列发送提示词。
|
||||
|
||||
## 提案
|
||||
|
||||
暂时删除中途用户 steering。`Agent.send()` 成为提交用户内容的唯一公开方式;当 agent 正在运行时,内容等待下一轮次。循环仅因工具调用而在轮次内继续,而非因为用户在某步骤运行期间输入了内容。想要中断当前轮次的调用方使用 `cancel()` 再 `send()`。
|
||||
暂时删除轮次中途的用户 steering。`Agent.send()` 成为提交用户内容的唯一公开方式;当 agent 正在运行时,内容等待下一个轮次。循环仅因工具调用而在轮次内继续,不因用户在某个步骤运行期间输入内容而继续。调用方若要中断当前轮次,使用 `cancel()` 后再 `send()`。
|
||||
|
||||
移除 `Agent.steer()`、steering FIFO、`steering/message`、`agent/steering`、由 steering 驱动的 continuation,以及区分排队消息与 steering 消息的取消逻辑。在同一变更中移除 `agent/turn-continuation`,除非实现 PR 发现了生产级监听器;没有 steering 之后,当前仓库不再有具体的 continuation 消费方。如果将来真正的预算或 goal 插件需要强制 continuation,应以该插件为具体消费方重新引入一个更窄的 seam。
|
||||
移除 `Agent.steer()`、steering FIFO、`steering/message`、`agent/steering`、由 steering 驱动的续行逻辑,以及取消操作中区分排队消息与 steering 消息的逻辑。除非实现 PR 发现了生产级监听器,否则在同一变更中一并移除 `agent/turn-continuation`;没有 steering 后,当前仓库不再有具体的续行消费方。如果将来真正的预算或目标插件需要强制续行,应以该插件为具体消费方重新引入一个更窄的 seam。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `Agent` 暴露唯一的用户消息入口 `send()`。
|
||||
- 持久化会话事件词汇不再包含 `steering/message`。
|
||||
- `deriveMessages()` 渲染普通用户消息和上下文注入,不再有 steering 标签路径。
|
||||
- 循环只有一个排队消息 FIFO,没有同轮次用户消息 continuation 路径。
|
||||
- `agent/turn-continuation` 被移除或收窄到一个具名的生产级消费方。
|
||||
- stdio UI 和文档将运行期间的输入描述为排入下一轮次的输入。
|
||||
- 会话格式版本和录制的 fixture(测试前置数据)已刷新;按预发布格式策略拒绝非当前版本的存储日志。
|
||||
- `deriveMessages()` 渲染普通用户消息和上下文注入,不存在 steering 标签路径。
|
||||
- 循环只有一个排队消息 FIFO,没有同轮次用户消息续行路径。
|
||||
- `agent/turn-continuation` 被移除,或收窄到有具名的生产级消费方。
|
||||
- stdio UI 和文档将运行期间的输入描述为「排入下一轮次的输入」。
|
||||
- 会话格式版本和已录制的 fixture(测试前置数据)已刷新;非当前版本的存储日志按预发布格式策略被拒绝。
|
||||
|
||||
## 放弃了什么
|
||||
|
||||
用户无法在模型处于工具步骤之间时添加同轮次 steering 内容。这种行为在理论上对「你已经在工作了,顺便也考虑一下 X」有用,但它不是 ACP 今天暴露的行为,而且它使轮次边界变得更难推理。更简单的行为是合理的:用户输入成为下一条提示词,取消仍是替换进行中工作的显式手段。
|
||||
用户无法在模型处于工具步骤之间时添加同轮次 steering 内容。这种行为在理论上对「你已经在工作了,也考虑一下 X」的场景有用,但它不是 ACP 当前暴露的行为,且使轮次边界更难推理。更简单的行为是合理的:用户输入成为下一条提示词,取消操作仍是替换进行中工作的显式手段。
|
||||
|
||||
## 相关
|
||||
|
||||
本提案与[删除持久化步骤边界](2026-06-20-drop-durable-step-boundaries.md)天然配对,因为移除同轮次 steering 和 `agent/turn-continuation` 之后,工具调用成为一个轮次包含多个模型步骤的唯一原因。
|
||||
本提案与[移除持久化步骤边界](2026-06-20-drop-durable-step-boundaries.md)天然配对,因为移除同轮次 steering 和 `agent/turn-continuation` 后,工具调用成为一个轮次包含多个模型步骤的唯一原因。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-single-session-acp-bridge.md: b7b52ca4df2d118358303745f4484e3e40a242b3
|
||||
2026-06-20-single-session-acp-bridge.zh.md: 2f00067fffcbd7a74f403c6247b290ac09a846b8
|
||||
2026-06-20-single-session-acp-bridge.zh.md: bd287f79475433e4d5e502ef30abd5d14410e633
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# RFC:将 ACP 桥接恢复为每连接单会话
|
||||
# RFC:将 ACP 桥接恢复为每连接一个活跃会话
|
||||
|
||||
[English](2026-06-20-single-session-acp-bridge.md) | 中文
|
||||
|
||||
@@ -6,21 +6,21 @@ Status: rejected — Zed 是当前目标 ACP 客户端,其 ACP 实现明确支
|
||||
|
||||
## 问题
|
||||
|
||||
ACP 桥接现已支持在一条 JSON-RPC 连接上承载多个活跃会话。这一能力带来了多条目会话映射、反向的会话/agent 查找、逐会话的提示词状态、加载中 id、每个事件的解复用、跨会话的销毁,以及未来权限提示与后台任务的隔离问题。早先的[多会话 ACP 提案](../../implemented/feature/2026-06-14-acp-multi-session.md)仍在跟踪未完成的权限归属部分;本 RFC 是与之竞争的简化路径。
|
||||
ACP(Agent Client Protocol)桥接现在支持在一条 JSON-RPC 连接上承载多个活跃会话。这一能力带来了多条目会话映射、反向会话/agent(智能体)查找、逐会话的 prompt 状态、加载中 id、每条事件的解复用、跨会话拆除,以及未来权限提示与后台任务的隔离问题。较早的[多会话 ACP 提案](../../implemented/feature/2026-06-14-acp-multi-session.md)仍在追踪未完成的权限归属部分;本 RFC 是与之竞争的简化路径。
|
||||
|
||||
产品目标已证明它需要在一个 harness 进程上承载并发的编辑器对话:Zed 的 ACP 连接拥有多个会话和加载状态。快照回放层仍然避免并发模型流,因为其回放条目是位置敏感的;这是测试 fixture 的局限,不是移除桥接多路复用的理由。
|
||||
产品目标已经证明它需要在一个 harness 进程上承载并发的编辑器对话:Zed 的 ACP 连接拥有多个会话和加载状态。快照回放层仍然避免并发模型流,因为其回放条目是位置相关的;这是测试 fixture(测试前置数据)的局限,而非移除桥接多路复用的理由。
|
||||
|
||||
## 提案
|
||||
|
||||
将 ACP 的作用域收回到每连接一个活跃会话。`session/new` 或 `session/load` 创建唯一的会话记录;在现有会话被 dispose 或连接关闭之前,第二个活跃会话请求将被拒绝。如果编辑器需要多个聊天标签页,可以启动多个 agent 子进程,直到桥接具备具体的多会话 UX 和权限模型。
|
||||
将 ACP 的范围收回到每连接一个活跃会话。`session/new` 或 `session/load` 创建唯一的会话记录;在现有会话被 dispose(资源释放)或连接关闭之前,第二个活跃会话请求将被拒绝。如果编辑器需要多个聊天标签页,可以启动多个 agent 子进程,直到桥接具备具体的多会话 UX 和权限模型。
|
||||
|
||||
在单个 `SessionRecord | undefined` 即可满足需求的地方,移除多会话映射和解复用逻辑。桥接仍可保留使销毁行为正确的 agent/会话生命周期 seam;简化仅针对在同一传输层上多路复用多个活跃会话这一点。
|
||||
移除多会话映射和解复用逻辑,改用单一的 `SessionRecord | undefined` 即可。桥接仍可保留使 dispose 正确的 agent/会话生命周期 seam;简化仅针对在同一传输层上多路复用多个活跃会话这一点。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- ACP 每连接仅有一条活跃会话记录。
|
||||
- ACP 每连接只有一条活跃会话记录。
|
||||
- 当该记录存在时,`session/new` 和 `session/load` 拒绝请求。
|
||||
- 事件处理器不再跨 `Map<sessionId, record>` 解复用。
|
||||
- 事件处理器不再在 `Map<sessionId, record>` 上做解复用。
|
||||
- 多会话测试被移除,或移至继续支持多路复用的提案下。
|
||||
- 既有的[多会话 ACP 提案](../../implemented/feature/2026-06-14-acp-multi-session.md)更新为链接本 RFC,并继续作为当前方向。
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-06-20-truncate-interrupted-turns.md: e17cb20f0185fe5d47d0a5ca18b7a389951fbadd
|
||||
2026-06-20-truncate-interrupted-turns.zh.md: 9ded51b29323be452bd67901dea2ba7b309a9903
|
||||
2026-06-20-truncate-interrupted-turns.zh.md: 48aeae650f867fb4629db33a448dd6cbaea60ae0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# RFC:加载时截断被中断的末尾轮次
|
||||
# RFC:加载时截断被中断的最终轮次
|
||||
|
||||
Status: rejected — a single turn can contain substantial real work, including many steps and large tool output. Preserving interrupted turns is preferable to silently dropping that tail on load.
|
||||
|
||||
@@ -6,31 +6,31 @@ Status: rejected — a single turn can contain substantial real work, including
|
||||
|
||||
## 问题
|
||||
|
||||
当前的持久化契约会保留最后一个已持久写入但从未关闭的轮次。加载时,`interruptedTurnClosers()` 扫描尾部,为未应答的工具调用合成错误的 `tool/result` 事件,在步骤未关闭时追加 `step/end`,追加 `turn/end { kind: 'interrupted' }`,并要求后端持久提交这段修复。协调器、JSONL 后端、SQLite 后端、会话事件词汇、不变式、文档和测试都对这条合成关闭路径建了模。
|
||||
当前的持久化契约会保留已持久写入但从未关闭的最终轮次。加载时,`interruptedTurnClosers()` 扫描尾部,为未应答的工具调用合成 error `tool/result` 事件,在 step 处于打开状态时追加 `step/end`,追加 `turn/end { kind: 'interrupted' }`,并要求后端持久提交这次修复。协调器、JSONL 后端、SQLite 后端、会话事件词汇、不变式、文档和测试都对这条合成关闭路径进行了建模。
|
||||
|
||||
这是为了保留上一次崩溃轮次的部分工作而引入的大量机制。它还会生造从未发生过的事件。合成的工具结果有用处(它使提供方历史保持合法),但也意味着恢复后的日志中包含了没有任何工具产出过的、模型可见的文本。当前设计在尚无已发布产品、也没有真实的恢复 UX 来证明部分轮次恢复确有价值的情况下,就优化了最大化的尾部保留。
|
||||
这是一套庞大的机制,只为保留上次崩溃轮次中的部分工作。它还会凭空创造从未发生过的事件。合成的工具结果虽然有用(因为它使 provider 历史保持合法),但也意味着恢复后的日志中包含了模型可见、却并非任何工具产出的文本。当前设计在尚无已发布产品、也没有真实恢复 UX 来证明部分轮次恢复确有价值的情况下,就优化了最大化尾部保留。
|
||||
|
||||
## 提案
|
||||
|
||||
加载时只保留到最后一个已完成的轮次。后端仍然容忍并截断撕裂的末尾记录,但如果解析出的持久前缀在一个已打开的 `turn/start` 之后结束,规范的修复方式是丢弃上一个 `turn/end` 之后的所有事件。不合成 `tool/result`,不合成 `step/end`,不追加 `turn/end { interrupted }`,也不需要 `interrupted` 轮次结束原因。
|
||||
加载时只保留最后一个已完成的轮次。后端仍然容忍并截断撕裂的最终记录,但如果解析出的持久前缀止于一个打开的 `turn/start` 之后,规范的修复方式是丢弃上一个 `turn/end` 之后的所有事件。不合成 `tool/result`,不合成 `step/end`,不追加 `turn/end { interrupted }`,也不引入 `interrupted` 轮次结束原因。
|
||||
|
||||
这使持久化的轮次边界变得简单:一个已完成的 `turn/end` 就是检查点。最后一个检查点之后的内容都是崩溃尾部。下一次提示词从最后一个已知合法的提供方 transcript 恢复,而非从部分重建的末尾轮次恢复。
|
||||
这使持久化的轮次边界变得简单:一个已完成的 `turn/end` 就是检查点。最后一个检查点之后的内容都是崩溃尾部。下一次 prompt 从最后一个已知合法的 provider transcript(文本记录)恢复,而不是从部分重建的最终轮次恢复。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- `TurnEndReasonMap` 移除 `interrupted` 变体。
|
||||
- `interruptedTurnClosers()` 及其测试消失。
|
||||
- 持久化协调器的修复钩子截断后端特定的撕裂/未关闭尾部状态,不追加关闭事件。
|
||||
- [会话持久化文档](../../../../packages/session-persistence/session-persistence/README.md)说明加载返回到最后一个已完成轮次,不包含部分末尾轮次。
|
||||
- 快照测试与契约测试随其所固定的行为一起更新。
|
||||
- 会话格式版本与已记录的 fixture(测试前置数据)一并刷新;按预发布格式策略,非当前版本的存储日志被拒绝,不提供迁移路径。
|
||||
- `interruptedTurnClosers()` 及其测试删除。
|
||||
- 持久化协调器的修复钩子截断后端特有的撕裂/打开尾部状态,不追加关闭事件。
|
||||
- [会话持久化文档](../../../../packages/session-persistence/session-persistence/README.md)说明加载返回最后一个已完成的轮次,不包含部分最终轮次。
|
||||
- 快照与契约测试随其所固定的行为一同更新。
|
||||
- 会话格式版本与记录的 fixture(测试前置数据)刷新;按预发布格式策略,非当前版本的存储日志被拒绝,不提供迁移路径。
|
||||
|
||||
## 放弃了什么
|
||||
## 放弃的内容
|
||||
|
||||
一次崩溃可能丢失末尾轮次中的真实工作:上一个 `turn/end` 之后追加的助手文本、工具调用和工具输出。这是有意为之的简化。产品尚未发布,末尾轮次恢复的语义未经用户验证,而一个干净的「已完成轮次即检查点」模型在解释、测试和实现上都容易得多。未来如果需要「恢复部分崩溃工作」功能,应当设计为一个面向用户的显式恢复视图,而非静默插入规范 transcript 的合成事件。
|
||||
崩溃可能丢失最终轮次中的真实工作:上一个 `turn/end` 之后追加的助手文本、工具调用和工具输出。这是有意为之的简化。产品尚未发布,最终轮次恢复的语义未经用户验证,而一个干净的「已完成轮次即检查点」模型在解释、测试和实现上都容易得多。未来若需「恢复部分崩溃工作」功能,应设计为面向用户的显式恢复视图,而非静默插入规范 transcript 的合成事件。
|
||||
|
||||
## 相关
|
||||
|
||||
本 RFC 是对[会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md)和[轮次封闭不变式](../../implemented/architecture/2026-06-15-turn-enclosure-invariant.md)的直接简化。它还移除了持久化步骤边界事件的大部分动机,使 [drop durable step boundary events](2026-06-20-drop-durable-step-boundaries.md) 的变更范围更小。
|
||||
本提案是对[会话持久化](../../implemented/architecture/2026-06-14-session-persistence.md)与[轮次封闭不变式](../../implemented/architecture/2026-06-15-turn-enclosure-invariant.md)的直接简化。它还移除了持久化 step 边界事件的大部分动机,使[移除持久化 step 边界事件](2026-06-20-drop-durable-step-boundaries.md)的改动更小。
|
||||
|
||||
<!-- rfc-format: alternatives-not-recorded (pre-format RFC) -->
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-04-prune-unimplemented-subagent-vocabulary.md: 3c86f11564d85b423fe59d784c6bf69959fb3907
|
||||
2026-07-04-prune-unimplemented-subagent-vocabulary.zh.md: ad8c8541ca682be6e71b6fe4ae166c3b65d14cdf
|
||||
2026-07-04-prune-unimplemented-subagent-vocabulary.zh.md: 84ff6f15ff2c9b3a13240997ab3c7b5cf2ab7263
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
# RFC:裁剪 subagent seam 中未实现的词汇
|
||||
|
||||
Status: rejected — the deferred capability vocabulary (`outputSchema`/`structured`, `toolFilter`, `sendMessage`/`resume`) is intentionally reserved surface: the seam advertises the full intended contract ahead of its implementations by design, so providers and consumers grow into a stable shape rather than re-negotiating it per capability. The consumer-evidence analysis below stands as the record of what is currently unimplemented.
|
||||
# RFC:裁剪未实现的 subagent seam 词汇
|
||||
|
||||
[English](2026-07-04-prune-unimplemented-subagent-vocabulary.md) | 中文
|
||||
|
||||
Status: rejected — the deferred capability vocabulary (`outputSchema`/`structured`, `toolFilter`, `sendMessage`/`resume`) is intentionally reserved surface: the seam advertises the full intended contract ahead of its implementations by design, so providers and consumers grow into a stable shape rather than re-negotiating it per capability. The consumer-evidence analysis below stands as the record of what is currently unimplemented.
|
||||
|
||||
## 问题
|
||||
|
||||
[subagent seam](../../implemented/feature/2026-06-21-subagent-capability-seam.md) 交付了一套两层能力设计:由服务在启动时检查的能力 flag,以及 `SubagentRun` 上的可选运行时方法。三项启动时特性和两个可选运行时方法均无实现、无调用方:
|
||||
[subagent seam](../../implemented/feature/2026-06-21-subagent-capability-seam.md) 交付了一套两层能力设计:启动时由服务检查的能力 flag,以及 `SubagentRun` 上的可选运行时方法。三个启动时特性和两个可选运行时方法的实现数与调用数均为零:
|
||||
|
||||
- **`outputSchema`/`structured` 与 `toolFilter`**(`SubagentCapabilities`、`SubagentStartRequest`、`SubagentResult`,位于 `packages/subagent/subagent/src/types.ts`):每个真实提供方都声明 `outputSchema: false, toolFilter: false`(`packages/subagent/subagent-spawn/src/index.ts`、`packages/subagent/subagent-fork/src/index.ts`、`packages/subagent/subagent-acp/src/index.ts`);唯一的生产环境 `ctx.subagents.start` 调用方(`packages/subagent/tool-subagent/src/index.ts`)构建 `{ prompt, parent, signal?, agentOptions? }`,结构上无法设置这两项;`structured` 仅由测试 mock(`packages/support/subagent-mock`)为其自身 spec 产出。服务的能力检查包含两行 assert,唯一的执行者是拒绝测试。
|
||||
- **`SubagentRun.sendMessage` / `SubagentRun.resume`**(同一文件):没有任何提供方实现——连 mock 也没有;spawn spec 断言的是它们的*缺席*。
|
||||
- **`outputSchema`/`structured` 与 `toolFilter`**(`SubagentCapabilities`、`SubagentStartRequest`、`SubagentResult`,位于 `packages/subagent/subagent/src/types.ts`):每个真实提供方都声明 `outputSchema: false, toolFilter: false`(`packages/subagent/subagent-spawn/src/index.ts`、`packages/subagent/subagent-fork/src/index.ts`、`packages/subagent/subagent-acp/src/index.ts`);唯一的生产环境 `ctx.subagents.start` 调用方(`packages/subagent/tool-subagent/src/index.ts`)构造 `{ prompt, parent, signal?, agentOptions? }`,结构上无法设置这两个字段;`structured` 仅由测试 mock(`packages/support/subagent-mock`)为其自身 spec 产出。服务的能力检查包含两行 assert,其唯一执行者是拒绝测试。
|
||||
- **`SubagentRun.sendMessage` / `SubagentRun.resume`**(同一文件):没有任何提供方实现——包括 mock 也没有;spawn spec 断言的正是它们的*缺失*。
|
||||
|
||||
`dsh-subagent` 依赖 `dsh-tools` 的唯一原因是 `outputSchema` 的 `SchemaSpec` 类型。三个后续 subagent 工作流(per-session 快照回放、fork seed 边界、ACP 后端)都围绕这块表面落地,却没有增长出哪怕一个消费方。
|
||||
`dsh-subagent` 依赖 `dsh-tools` 的唯一原因是 `outputSchema` 的 `SchemaSpec` 类型。三个后续 subagent 工作流(per-session 快照回放、fork seed 边界、ACP(Agent Client Protocol) 后端)都围绕这块接口面落地,却没有增长出哪怕一个消费方。
|
||||
|
||||
## 提案
|
||||
|
||||
从 seam 中移除 `outputSchema`/`structured`、`toolFilter`、`sendMessage` 和 `resume`;将 `SubagentCapabilities` 缩减为 `{ depthLimit }`;删除两行能力 assert、三个提供方上的 all-false flag、mock 的 structured 分支及其 `capabilities`/`structured` 配置旋钮,以及为固定被移除表面而存在的测试(两行拒绝测试、spawn 缺席测试、mock structured spec)。从 `packages/subagent/subagent/package.json` 中删除 `dsh-tools` 的 peer/dev 依赖。更新 [subagent.md](../../../core-data-structures/subagent.md) 中的粘贴内容与 type-equiv manifest,以及 `packages/subagent/subagent`、`packages/subagent/subagent-spawn`、`packages/subagent/subagent-fork` 和 `packages/support/subagent-mock` 的 README 相关行。实现 PR 按 [implemented/AGENTS.md](../../implemented/AGENTS.md) 修订 seam RFC 的能力目录。
|
||||
从 seam 中移除 `outputSchema`/`structured`、`toolFilter`、`sendMessage` 与 `resume`;将 `SubagentCapabilities` 缩减为 `{ depthLimit }`;删除两行能力 assert、三个提供方上的 all-false flag、mock 的 structured 分支及其 `capabilities`/`structured` 配置项,以及为固定被移除接口面而存在的测试(两行拒绝测试、spawn 缺失测试、mock structured spec)。从 `packages/subagent/subagent/package.json` 中删除 `dsh-tools` 的 peer/dev 依赖。更新 [subagent.md](../../../core-data-structures/subagent.md) 中的粘贴内容与 type-equiv manifest(元数据清单),以及 `packages/subagent/subagent`、`packages/subagent/subagent-spawn`、`packages/subagent/subagent-fork` 和 `packages/support/subagent-mock` 的 README 相关行。实现 PR(Pull Request)按照 [implemented/AGENTS.md](../../implemented/AGENTS.md) 修订 seam RFC 的能力目录。
|
||||
|
||||
**保留** `depthLimit`/`maxDepth` 与能力检查。进程内后端强制执行该限制,尽管当前发布的工具尚未设置它。递归是已知的 seam 风险,因此恰当的后续工作是补上工具默认值,而非删除正在工作的强制逻辑。
|
||||
**保留** `depthLimit`/`maxDepth` 与能力检查。进程内后端已强制执行该限制,尽管当前发布的 tool 尚未设置它。递归是已知的 seam 风险,因此恰当的后续工作是提供一个 tool 默认值,而非删除正在工作的强制逻辑。
|
||||
|
||||
审视过但有意不动的相邻表面:`SubagentService.getProvider()`/`list()` 只有测试 harness 消费方,但 [prune-dead-seam-methods 实现说明](../../implemented/simplification/2026-06-20-prune-dead-seam-methods.md) 记录了完全相同的形态曾从 bash executor 中移除后又被回退——测试 harness 对于一个在已跟踪 map 上的单行访问器而言就是消费方。`SubagentRunEndInfo.lastAssistantMessage` 是一个已记录的保留项([subagent-observe-enrich RFC](../../implemented/feature/2026-06-30-subagent-observe-enrich.md) 的评审删除了 `agentType` 但有意保留了它,因为它是进程外子 agent 唯一的最终消息通道);它当前未接通的桥接转发是一个待弥合的缺口或待记录的消费方,不是本 RFC 要裁剪的表面。
|
||||
审视过但有意不动的相邻接口面:`SubagentService.getProvider()`/`list()` 仅有测试 harness 消费方,但 [prune-dead-seam-methods 实现说明](../../implemented/simplification/2026-06-20-prune-dead-seam-methods.md) 恰好记录了这种形态从 bash executor 中被移除后又被回退的经过——对于一个基于已跟踪 map 的单行访问器而言,测试 harness 就是消费方。`SubagentRunEndInfo.lastAssistantMessage` 是一个已记录的保留项([subagent-observe-enrich RFC](../../implemented/feature/2026-06-30-subagent-observe-enrich.md) 的评审删除了 `agentType` 但有意保留了它,因为它是进程外子 agent(智能体)唯一的最终消息通道);它当前未接通的桥接转发是一个待补的缺口或待记录的消费方,不是本 RFC 要裁剪的接口面。
|
||||
|
||||
这是 [从持久化 seam 裁剪死方法](../../implemented/simplification/2026-06-20-prune-dead-seam-methods.md) 在 seam 词汇层面的回声:每个实现都必须为无人声明的成员——甚至更弱,因为这里连一个实现都不存在。
|
||||
这是[从持久化 seam 裁剪死方法](../../implemented/simplification/2026-06-20-prune-dead-seam-methods.md)在 seam 词汇层面的回响:每个实现都必须为无人声明的成员,甚至更弱,因为这里连一个实现都没有。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
### 为什么不保留?
|
||||
|
||||
两类能力的设计是 seam RFC 的核心亮点,日后重新添加 `outputSchema` 会涉及多个文件。但该设计以 `depthLimit` 作为活跃示例、以 RFC 作为记录仍然成立;而且 seam RFC 本身承认已交付的 `toolFilter` 形态是错的(真正的强制需要在子 agent 的上下文中设置 `tools/pre-execute` deny,而非 schema 过滤)——该 deny 原语已存在于拦截 seam 上,因此面向真实实现提供方重新添加时,将固定一份比当前推测性契约更好的契约。
|
||||
两类能力的设计是 seam RFC 的核心亮点,日后重新添加 `outputSchema` 会涉及多个文件。但该设计以 `depthLimit` 作为活跃示例、以 RFC 作为记录仍然成立;而且 seam RFC 本身承认已交付的 `toolFilter` 形态是错误的(真正的强制需要在子 agent 上下文中实施 `tools/pre-execute` deny,而非 schema 过滤)——该 deny 原语已存在于拦截 seam 上,因此基于真实实现提供方重新添加时,将固定出一份比当前推测性契约更好的契约。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 被移除的拼写仅出现在本 RFC 和修订后的 seam RFC 中;`SubagentCapabilities` 为 `{ depthLimit: boolean }`;`dsh-tools` 依赖边已消除(`hygiene` 绿)。
|
||||
- 深度强制测试不变且绿。
|
||||
- 被移除的拼写仅出现在本 RFC 和修订后的 seam RFC 中;`SubagentCapabilities` 为 `{ depthLimit: boolean }`;`dsh-tools` 依赖边已消除(`hygiene` 绿色)。
|
||||
- 深度强制测试不变且绿色。
|
||||
|
||||
## 风险
|
||||
|
||||
subagent 生命周期事件在结束载荷上携带 `lastAssistantMessage`——该增强位于服务模块中,不在本 RFC 缩减的 seam 词汇范围内;observe-enrich RFC 记录了因缺乏消费方而删除 `agentType` 兄弟字段的判断:本 RFC 延续的正是这一判断。CC hooks 桥接是这些生命周期事件的第一个外部消费方,它只读取事件载荷,不触及本文移除的任何表面;observe-enrich RFC 中延期的控制流重设计将实现 `resume` 列为自身的未来工作——恰好是本 RFC 模式所预期的重新添加触发点。
|
||||
subagent 生命周期事件在结束载荷上携带 `lastAssistantMessage`——该增强位于服务模块中,不在本 RFC 缩减的 seam 词汇范围内;observe-enrich RFC 记录了因缺少消费方而删除 `agentType` 兄弟字段的判断,本 RFC 延续了这一判断。CC hooks 桥接是这些生命周期事件的第一个外部消费方,它只读取事件载荷,不涉及本文移除的任何接口面;observe-enrich RFC 推迟的控制流重设计将实现 `resume` 列为自身的未来工作——恰好是本 RFC 模式所预期的重新添加触发点。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-12-collapse-workflow-to-foreground-core.md: 78b67c10ac39fddaf4ea76ca90d5cbf760fe5866
|
||||
2026-07-12-collapse-workflow-to-foreground-core.zh.md: 567da63e86b24dbedfd6fb50da0984c9866bd9cb
|
||||
2026-07-12-collapse-workflow-to-foreground-core.zh.md: 28b0af0a70110d39572fafac521a555c62ebb3f5
|
||||
|
||||
@@ -1,39 +1,39 @@
|
||||
# RFC:将工作流收缩至实际使用的前台核心
|
||||
|
||||
Status: rejected — Workflow progress is an intentional observation surface; make it useful through a consumer instead of deleting it.
|
||||
# RFC:将工作流收缩至已使用的前台核心
|
||||
|
||||
[English](2026-07-12-collapse-workflow-to-foreground-core.md) | 中文
|
||||
|
||||
Status: rejected — Workflow progress is an intentional observation surface; make it useful through a consumer instead of deleting it.
|
||||
|
||||
## 问题
|
||||
|
||||
工作流能力执行前台 JavaScript 来编排 subagent,但它同时携带了一套无人消费的进度观测系统。没有任何生产环境的监听器订阅六个 `workflow/*` 事件中的任何一个;监听器仅存在于工作流测试中。尽管如此,seam 仍定义了 run/phase/agent outcome 载荷,worker 仍发送 phase/log/agent 生命周期协议消息,host 通过一个 `liveAgents` 配对账本转发它们,引擎维护 run id 的唯一目的就是关联这些通知。
|
||||
工作流能力执行前台 JavaScript 来编排 subagent,但它同时携带了一套无人消费的进度观测系统。没有任何生产环境的监听器订阅六个 `workflow/*` 事件中的任何一个;监听器仅存在于工作流测试中。尽管如此,seam 定义了 run/phase/agent outcome 载荷,worker 发送 phase/log/agent 生命周期协议消息,host 通过一个 `liveAgents` 配对账本转发它们,引擎维护 run id 仅仅是为了关联这些通知。
|
||||
|
||||
这套进度词汇不仅未被使用,而且在不重新设计的情况下无法服务于它唯一的具名未来消费方。`WorkflowRunInfo` 包含 `{id, meta}` 但没有父 agent、会话或工具调用标识,而面向模型的工具从不暴露 run id。一个全局 ACP 监听器无法将事件路由到正确的客户端会话。`meta.phases` 从未被查询,`phase(title)` 不会对其做校验,phase 的 `detail`/`model` 和 agent 的 `label`/`phase` 只喂给事件,`whenToUse` 被校验和复制但从未被渲染或用于选择。`phase()` 和 `log()` 仍然跨越 worker 边界,尽管没有接收方。
|
||||
这套进度词汇不仅仅是未被使用;它在不经重新设计的情况下也无法服务于其唯一已命名的未来消费方。`WorkflowRunInfo` 包含 `{id, meta}` 但没有父 agent(智能体)、会话或工具调用标识,而面向模型的工具也从不暴露 run id。一个全局 ACP(Agent Client Protocol)监听器无法将事件路由到正确的客户端会话。`meta.phases` 从未被查询,`phase(title)` 不对其做校验,phase 的 `detail`/`model` 和 agent 的 `label`/`phase` 仅供事件消费,`whenToUse` 被校验和复制但从未被渲染或用于选择。`phase()` 和 `log()` 仍然跨越 worker 边界,尽管没有接收方。
|
||||
|
||||
live handle 在观察者消失后仍重复事件时代的数据。`WorkflowRun.id` 没有非事件消费方,而工具读取 `run.meta.name` 只是为了渲染一个它已经以 `args.meta.name` 形式持有的值;两者都不属于执行/取消 handle。
|
||||
live handle 在观测者消失后仍重复事件时代的数据。`WorkflowRun.id` 没有非事件消费方,而工具读取 `run.meta.name` 只是为了渲染一个它已经以 `args.meta.name` 形式持有的值;两者都不属于执行/取消 handle。
|
||||
|
||||
取消也为一个同步启动提供了两条公开通道。`WorkflowStartRequest.signal` 被传给 worker host,而唯一的生产调用方另外将同一个 signal 桥接到 `WorkflowRun.cancel()`。因为 `start()` 在控制权让出之前就返回了 run,不存在需要请求时取消的就绪窗口;重复的 signal 增加了 host 的 listener/disarm 状态却没有消除任何竞态。
|
||||
取消机制也为一个同步启动提供了两条公开通道。`WorkflowStartRequest.signal` 被传递给 worker host,而唯一的生产调用方另外将同一个 signal 桥接到 `WorkflowRun.cancel()`。因为 `start()` 在控制权让出之前就返回了 run,不存在需要请求时取消的就绪窗口;重复的 signal 增加了 host 的 listener/disarm 状态却没有封堵任何竞态。
|
||||
|
||||
`WorkflowError.fatal` 是同类投机分支的微缩版:每个生产环境的构造都是 fatal 的,`fatal: false` 仅存在于测试中,组合子已经通过 `instanceof` 区分工作流失败。
|
||||
`WorkflowError.fatal` 是同一种推测性分支的微缩版:所有生产环境的构造都是 fatal 的,`fatal: false` 仅存在于测试中,组合子已经通过 `instanceof` 区分工作流失败。
|
||||
|
||||
## 提案
|
||||
|
||||
保留实际使用的核心:`agent(prompt, { schema, model })`、`parallel`、`pipeline`、`args`、并发/agent 上限、取消、有界 dispose、结构化结果、worker 隔离,以及前台工具收集。移除所有 `workflow/*` 事件及其仅服务于事件的 info/outcome 类型;移除 `phase()`、`log()`、agent 的 `label`/`phase`、phase 声明、`whenToUse` 及其 worker 消息/host 观察者;将工作流元数据收缩为工具实际使用的 name;移除仅服务于事件的 run id/meta 快照以及合成的 agent-end 账本。将 `WorkflowRun` 收缩为 `result`、`cancel()` 和 `dispose()`;工具渲染请求方持有的 name。移除 `WorkflowStartRequest.signal` 及 worker host 的 input-signal listener/disarm 状态,保留调用方从自身 abort signal 到 `run.cancel()` 的桥接。将 `WorkflowError` 变为单一的 fatal 错误类,不再有布尔模式或 `isFatalWorkflowError()` 辅助函数。
|
||||
保留已使用的核心:`agent(prompt, { schema, model })`、`parallel`、`pipeline`、`args`、并发/agent 上限、取消、有界 dispose(资源释放)、结构化结果、worker 隔离与前台工具收集。移除所有 `workflow/*` 事件及其仅供事件使用的 info/outcome 类型;移除 `phase()`、`log()`、agent 的 `label`/`phase`、phase 声明、`whenToUse` 及其 worker 消息/host 观测者;将工作流元数据收缩为工具实际使用的 name;移除仅供事件使用的 run id/meta 快照与合成的 agent-end 账本。将 `WorkflowRun` 收缩为 `result`、`cancel()` 和 `dispose()`;工具渲染请求方持有的 name。移除 `WorkflowStartRequest.signal` 及 worker host 的 input-signal listener/disarm 状态,保留调用方从其 abort signal 到 `run.cancel()` 的桥接。将 `WorkflowError` 变为单一的 fatal 错误类,不再有布尔模式或 `isFatalWorkflowError()` 辅助函数。
|
||||
|
||||
修订已实施的动态工作流 RFC,并更新 seam/tool/worker README、工具 schema、生成的 catalog 与包依赖图、worker type-equiv 记录、单元测试,以及工作流快照/header fixture。如果未来委托进度 UI 工作,应从一份命名了父 agent/会话/工具调用的关联契约出发,而非原样复活此协议。
|
||||
修订已实施的 dynamic-workflow RFC,并更新 seam/tool/worker README、工具 schema、生成的 catalog 与 package 依赖图、worker type-equiv 记录、单元测试以及工作流快照/header fixture(测试前置数据)。如果进度 UI 工作被立项,应从一份命名了父 agent/会话/工具调用的关联契约出发,而非原样复活这套协议。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
**为未来 UI 保留预建的观测词汇。** 当前形状类似 Claude Code 的动态工作流元数据,host 有意地将每个转发的 agent start 与 worker 的 end 或合成的终端 end 配对。移除它意味着放弃形状兼容性,使进度 UI 成为一项全新的设计任务;但现有载荷仍然缺少可路由的归属信息,因此仅靠平衡的生命周期也无法在不重新设计的情况下让具名的 ACP 消费方可行。
|
||||
**为未来 UI 保留预建的观测词汇。** 当前形态类似 Claude Code 的 dynamic-workflow 元数据,host 有意地将每个转发的 agent start 与 worker 的 end 或一个合成的终止 end 配对。移除它意味着放弃形态兼容性,使进度 UI 成为一项全新的设计任务;但现有载荷仍缺少可路由的归属信息,因此仅靠平衡的生命周期也无法在不重新设计的情况下让已命名的 ACP 消费方可行。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 工作流公开 seam 仅包含有生产消费方的执行、取消、结果与 dispose 契约。
|
||||
- 不再保留任何工作流事件、phase/log 协议消息、run-id 生成器、仅服务于进度的元数据、host 配对账本或 fatal 模式分支。
|
||||
- 不再保留任何工作流事件、phase/log 协议消息、run-id 生成器、仅供进度使用的元数据、host 配对账本或 fatal 模式分支。
|
||||
- run handle 不再有 id/meta 回显,取消在同步 `start()` 返回后只有一条持有者拥有的通道。
|
||||
- parallel/pipeline 行为、上限、取消静默、worker 隔离、结构化输出以及面向模型的工作流场景保持覆盖率。
|
||||
- parallel/pipeline 行为、上限、取消静默、worker 隔离、结构化输出与面向模型的工作流场景保持测试覆盖。
|
||||
- 类型检查、覆盖率、快照、doc-sync、module-graph 校验、构建与 hygiene 全部通过。
|
||||
|
||||
## 风险
|
||||
|
||||
这是对工作流 DSL、事件分类体系、handle 与 start request 的编译可见收缩。现有提供描述性元数据的工作流调用,以及使用 `phase`、`log` 或 label 的脚本,必须相应精简;程序化调用方需自行将 abort 源桥接到返回的 handle;未来的观察者必须添加一个关联性更好的 seam。使工作流真正有用的执行语义不变。
|
||||
这是对工作流 DSL、事件分类体系、handle 与 start request 的编译可见收缩。现有提供描述性元数据的工作流调用,以及使用 `phase`、`log` 或 label 的脚本,都必须相应精简;程序化调用方需自行将 abort source 桥接到返回的 handle;未来的观测者必须添加一个关联性更好的 seam。使工作流有用的执行语义不变。
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write
|
||||
2026-07-12-prune-unused-skill-registry-surface.md: 3e8c009871c3d609612b4a01edc2048ddedfad0d
|
||||
2026-07-12-prune-unused-skill-registry-surface.zh.md: 1412e3cfac1adbb8b563ad50edb08c53a719feb8
|
||||
2026-07-12-prune-unused-skill-registry-surface.zh.md: deaea2ca53d4ed2ac5141013f969f621d3202875
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
# RFC:裁剪未使用的 skill 注册表接口
|
||||
|
||||
Status: rejected — Direct runtime skill registration is an intentional extension path for third-party plugins.
|
||||
# RFC:裁剪 skill 注册表中未使用的接口
|
||||
|
||||
[English](2026-07-12-prune-unused-skill-registry-surface.md) | 中文
|
||||
|
||||
Status: rejected — Direct runtime skill registration is an intentional extension path for third-party plugins.
|
||||
|
||||
## 问题
|
||||
|
||||
skill 服务的嵌入式运行时子系统没有任何生产调用方调用 `ctx.skills.register()`。它引入了一个保留的 `runtime` 提供方名称、一套运行时 map/rank/source、重复策略、缓存键中的第二个 revision、规范化逻辑、dispose 函数和测试,而这些都与每个已交付 skill 实际使用的提供方 seam 并行存在。`SkillSummary.whenToUse` 以及 candidate/definition 上的 `path` 被解析和复制,但没有任何生产消费方读取它们:模型目录只渲染 name/description,资源加载使用 `resourceBase`,提供方自行管理其定位符。刻意开放的 `metadata` 扩展点保留不动。
|
||||
skill(技能)服务的嵌入式运行时子系统中,`ctx.skills.register()` 没有任何生产调用方。它引入了一个保留的 `runtime` 提供方名称、一套运行时 map/rank/source、重复策略、缓存键中的第二个 revision、规范化逻辑、dispose(资源释放)器以及相应测试——而所有已交付的 skill 都只使用提供方 seam。`SkillSummary.whenToUse` 和 candidate/definition 的 `path` 被解析和复制,但没有任何生产消费方读取它们:模型目录只渲染 name/description,资源加载使用 `resourceBase`,提供方自行管理其定位器。有意开放的 `metadata` 扩展点保留不动。
|
||||
|
||||
## 提案
|
||||
|
||||
移除 `SkillService.register()`、`SkillRegistration`、运行时伪提供方及保留名称规则、运行时 revision/缓存分支,以及仅用于运行时的 source/rank 规范化逻辑。需要嵌入式 skill 的测试改为注册一个小型真实提供方。保留 `providerRevision` 作为进行中的发现纪元,但已完成的目录仅以 cwd 为键:每次提供方变更都同步清除缓存,await 之后的 revision 比较已能阻止插入陈旧结果。从 skill 契约和本地提供方副本中移除 `whenToUse`、`SkillCandidate.path` 和 `SkillDefinition.path`,同时保留提供方的 locator/root 路径;保留 `metadata`、`disableModelInvocation`、`source`、`provider`、`locator` 和 `resourceBase`,它们要么是刻意的扩展词汇,要么是生产中被消费的字段。
|
||||
移除 `SkillService.register()`、`SkillRegistration`、运行时伪提供方及保留名称规则、运行时 revision/缓存分支,以及仅用于运行时的 source/rank 规范化逻辑。需要嵌入式 skill 的测试改为注册一个小型真实提供方。保留 `providerRevision` 作为进行中的发现 epoch,但已完成的目录缓存仅以 cwd 为键:每次提供方变更同步清除缓存,await 之后的 revision 比较已能阻止插入陈旧结果。从 skill 契约和 local-provider 副本中移除 `whenToUse`、`SkillCandidate.path` 与 `SkillDefinition.path`,同时保留提供方的 locator/root 路径;保留 `metadata`、`disableModelInvocation`、`source`、`provider`、`locator` 和 `resourceBase`,因为它们要么是有意开放的扩展词汇,要么是生产消费的字段。
|
||||
|
||||
同步修订 skill 系统 RFC、README、JSDoc、目录文件和测试。agent 作用域的系统提示词段落、工具提供方和变量明确不在本提案范围内:[agent 作用域贡献者契约](../../implemented/architecture/2026-07-08-agent-scope-contexts.md)有意允许在 `setup(agentCtx)` 期间通过 agent 拥有的上下文注册这三者,因此仓库内没有固定的作用域注册并不能证明无人消费。
|
||||
同步修订 skill 系统 RFC、README、JSDoc、目录文件与测试。agent(智能体)作用域的系统提示词段、工具提供方和变量明确不在本提案范围内:[agent 作用域贡献者契约](../../implemented/architecture/2026-07-08-agent-scope-contexts.md)有意允许在 `setup(agentCtx)` 期间通过 agent 拥有的上下文注册这三者,因此仓库内没有固定的作用域注册并不能证明它们未被使用。
|
||||
|
||||
## 曾考虑的替代方案
|
||||
|
||||
**为嵌入方保留运行时 skill 注册。** 这是已实现的 skill RFC 中一个刻意设计的同步直接定义便利接口。一个小型提供方包装层可以在 effect 拥有的生命周期下暴露相同的嵌入数据,但它必须实现异步 `list()`/`get()`、携带提供方身份、并接受提供方的重复语义。本提案选择保留一条统一的提供方路径,而非维护第二套排序、校验、缓存失效和查找路径。
|
||||
**保留面向嵌入方的运行时 skill 注册。** 这是已实现的 skill RFC 中有意提供的同步直接定义便利接口。一个小型提供方包装层可以在 effect 拥有的生命周期下暴露相同的嵌入数据,但它必须实现异步 `list()`/`get()`、携带提供方身份,并接受提供方的重复语义。本提案选择只保留一条统一的提供方路径,而非维护第二套排序、校验、缓存失效与查找路径。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- skill 收集只有一条提供方驱动的路径;已完成缓存的键仅为 cwd;revision 纪元仅用于进行中的失效;保留的 skill 字段要么有生产读取方,要么有记录在案的刻意扩展契约。
|
||||
- agent 作用域的 prompt 段落、变量、工具提供方、工具守卫,以及原生模式和 Code Mode 下的结构化输出提交行为保持不变。
|
||||
- 类型检查、覆盖率、快照、doc-sync、module-graph 校验、构建和 hygiene 全部通过。
|
||||
- skill 收集只有一条提供方驱动的路径,已完成缓存仅以 cwd 为键,revision epoch 仅用于进行中的失效检测;保留的 skill 字段要么有生产读取方,要么有记录在案的有意扩展契约。
|
||||
- agent 作用域的提示词段、变量、工具提供方、工具守卫,以及原生模式和 Code Mode 下的 structured-output 提交行为保持不变。
|
||||
- 类型检查、覆盖率、快照、doc-sync(文档同步门禁)、module-graph 校验、构建与 hygiene 全部通过。
|
||||
|
||||
## 风险
|
||||
|
||||
这是对预发布 skill 注册表的一次编译可见的收缩。外部编程式 `list()`/`get()` 消费方将失去 `whenToUse` 路由提示和 candidate/definition 上的 `path`;已交付的模型目录从未渲染它们,资源解析保留了显式的 `resourceBase` 加上提供方自有的不透明 locator,但这些字段在可观测性上并不等价。skill 本地的 frontmatter 解析必须继续保留并校验所支持的 metadata schema,外部提供方仍可提供嵌入式、文件系统、远程或其他 skill 来源。
|
||||
这是对预发布 skill 注册表的编译可见收缩。外部编程式 `list()`/`get()` 消费方将失去 `whenToUse` 路由提示和 candidate/definition 的 `path`;已交付的模型目录从未渲染它们,资源解析保留了显式的 `resourceBase` 加上提供方自有的不透明 locator,但这些字段并非观测等价。skill 本地 frontmatter 解析必须继续保留并校验所支持的 metadata schema,外部提供方仍可提供嵌入式、文件系统、远程或其他 skill 来源。
|
||||
|
||||
Reference in New Issue
Block a user