Repository navigation
feat: add hybrid code mode #11854
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add hybrid code mode #11854
Changes from all commits
6ab42db
fda09c0
9a0cd57
30b2a6c
6c919b7
02afce8
2ecf53e
4a38632
3239c68
f35beb1
28df8ee
a7315eb
3c69762
34711cf
ce7e57d
fa457bd
ae35809
4c53574
22a9a40
779d689
b1561b7
e6fbdcd
6edd151
f746b88
ed2e58c
4a72ef8
cad9407
1df2386
71ab2c9
68ceea7
f669bd7
f183ce0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,9 @@ | ||
| # CodeModeOnly MVP | ||
|
|
||
| > Current behavior: Only discovers schemas through top-level tool_search and invokes tools through exec. Full signatures are included when search is unavailable in the current scope; tools.eager can reduce the initial declaration. Hybrid keeps direct tools plus exec with its existing bridge and eager permission boundaries. The original MVP statements below about hiding tool_search or always including full schemas are superseded by the [lazy-loading design](lazy-code-mode.md). | ||
|
|
||
| [English](code-mode-only.md) | [简体中文](code-mode-only.zh-CN.md) | ||
|
|
||
| ## Status | ||
|
|
||
| Implemented for [#10377](https://github.com/QwenLM/qwen-code/issues/10377). | ||
|
|
@@ -12,20 +16,20 @@ describe this MVP; `tool_call` stays hidden. | |
|
|
||
| ## Goal | ||
|
|
||
| Add a `tools.codeModeOnly` setting that replaces the ordinary model-facing | ||
| tool surface with one `exec` JavaScript tool plus the small set of tools that | ||
| must remain direct control-plane calls. `exec` code can call ordinary tools | ||
| Add a `tools.mode: "code_mode_only"` setting that replaces the ordinary | ||
| model-facing tool surface with one `exec` JavaScript tool plus the small set of | ||
| tools that must remain direct control-plane calls. `exec` code can call ordinary tools | ||
| through `tools.<name>(args)` without bypassing Qwen Code's validation, | ||
| permissions, approvals, hooks, telemetry, cancellation, concurrency, or output | ||
| budgets. | ||
|
|
||
| Direct mode is a compatibility boundary: when the setting is false, tool | ||
| Direct mode is a compatibility boundary: when `tools.mode` is `direct`, tool | ||
| registration, deferred-tool behavior, provider requests, and execution remain | ||
| unchanged. | ||
|
|
||
| ## Non-goals | ||
|
|
||
| - Hybrid direct/code exposure. | ||
| - Defining hybrid direct/code exposure; see [Code Mode](code-mode.md). | ||
| - Persistent cells, globals, or values between `exec` calls. | ||
| - Background jobs, `wait`, `yield`, `store`, or `load`. | ||
| - Raw/freeform provider calls. | ||
|
|
@@ -37,27 +41,27 @@ unchanged. | |
| ```json | ||
| { | ||
| "tools": { | ||
| "codeModeOnly": true | ||
| "mode": "code_mode_only" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The setting resolves once to the effective `ToolMode` value `direct` or | ||
| `code_mode_only`. `ToolRegistry` and the execution surfaces consume that mode. | ||
| `exec` is only registered when the setting is enabled, so disabling the setting | ||
| also removes it from diagnostics and registry listings. | ||
| The setting resolves once to the effective `ToolMode` value. `ToolRegistry` | ||
| and the execution surfaces consume that mode. `exec` is only registered when a | ||
| code mode is enabled, so selecting `direct` also removes it from diagnostics | ||
| and registry listings. | ||
|
|
||
| ## Exposure policy | ||
|
|
||
| The registry remains the source of truth. Exposure is a view over registered | ||
| tools, never a second registry. | ||
|
|
||
| | Category | Model top level | `tools.*` inside `exec` | | ||
| | ------------------------------------------ | ----------------- | ----------------------- | | ||
| | `exec` | CodeModeOnly only | No | | ||
| | Direct control | Yes | No | | ||
| | Ordinary registered tool | No | Yes | | ||
| | Hidden bridge (`tool_search`, `tool_call`) | No | No | | ||
| | Category | Model top level | `tools.*` inside `exec` | | ||
| | ------------------------------------------ | ------------------------------------- | ----------------------- | | ||
| | `exec` | CodeMode and CodeModeOnly | No | | ||
| | Direct control | Yes | No | | ||
| | Ordinary registered tool | CodeMode only | Yes | | ||
| | Hidden bridge (`tool_search`, `tool_call`) | Existing behavior outside strict mode | No | | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-2: N06: The rewritten exposure row conditions the table's only statement about bridge exposure on "strict mode" — a term that exists nowhere in the mode vocabulary, the code, or any other English document — and it groups two tools the code exposes differently.
Witness: Suggested fix: Replace the cell with mode names and split the pair, e.g. two rows — The fix must not violate this existing fact: Acceptance criterion: N/A (documentation prose; no guard, branch or behaviour to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明改写后的 exposure 表格行把该表唯一一句关于 bridge 暴露的说明限定在 "strict mode" 下——而这个词在模式词表、代码和其余文档中都不存在(真实枚举是 — qwen3.8-max via Qwen Code /review (v0.25.0)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-2: The new Chinese translation states the opposite of the English original (docs/design/code-mode-only.md:144-148) on Code Mode shell concurrency: EN says "Code Mode Bash calls bypass the read-only command classifier, with the model responsible for keeping dependent calls sequential. Other tools retain their existing concurrency classification"; ZH says the batch is "由现有的只读并发分类器处理" and drops the Bash carve-out entirely. A reader working from the ZH design concludes that shell calls submitted together inside one Witness: Suggested fix: Translate the two missing EN sentences into the ZH paragraph, e.g. replace "… The fix must not violate this existing fact: Acceptance criterion: N/A (documentation text; no guard, branch, or behavior to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明新增中文翻译在 Code Mode shell 并发这一点上与英文原文相反:英文说 "Code Mode Bash calls bypass the read-only command classifier",中文写成"由现有的只读并发分类器处理",恰好把豁免说成了适用。同仓库的 code-mode-concurrency.zh-CN.md:21 与英文一致,可证这是翻译错误。实测 — qwen3.8-max via Qwen Code /review (v0.25.0)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-2: N06: The rewritten exposure row conditions the table's only statement about bridge exposure on "strict mode" — a term that exists nowhere in the mode vocabulary, the code, or any other English document — and it groups two tools the code exposes differently.
Witness: Suggested fix: Replace the cell with mode names and split the pair, e.g. two rows — The fix must not violate this existing fact: Acceptance criterion: N/A (documentation prose; no guard, branch or behaviour to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明改写后的 exposure 表格行把该表唯一一句关于 bridge 暴露的说明限定在 "strict mode" 下——而这个词在模式词表、代码和其余文档中都不存在(真实枚举是 — qwen3.8-max via Qwen Code /review (v0.25.0) |
||
|
|
||
| The direct-control allowlist is centralized and deliberately small. It covers | ||
| user interaction (`ask_user_question`), delegation (`agent`), terminal output | ||
|
|
@@ -80,17 +84,20 @@ Before each provider tool sync, the `exec` description is generated from the | |
| current registry. Tools are sorted by canonical name. A name is normalized to | ||
| a JavaScript property by replacing invalid identifier characters and prefixing | ||
| names that begin with a digit. If two canonical names normalize to the same | ||
| property, the lexicographically first name wins and one warning names the | ||
| property, an exact canonical match wins over rewritten names. If neither is an | ||
| exact match, the lexicographically first name wins. The description names the | ||
|
Comment on lines
+87
to
+88
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-3: N01: The sentence this diff rewrote (pre-diff: "one warning names the omitted collision") claims the A registry holding Witness: Suggested fix: Scope the claim to the configuration where it holds and name the other surface, e.g. "When search is unavailable in the current scope, the description names the omitted collision; when The fix must not violate this existing fact: Acceptance criterion: N/A (documentation prose). The behaviour the corrected sentence must match is already pinned from both sides: 中文说明本次改写后的句子声称 — qwen3.8-max via Qwen Code /review (v0.25.0)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-3: The new ZH version's 状态 section omits the English Status paragraph at docs/design/code-mode-only.md:12-16 ("Partly superseded by Lazy Code Mode: The ZH reader never learns that Witness: Suggested fix: Translate the EN Status paragraph into 状态 (adding the The fix must not violate this existing fact: docs/design/code-mode-only.md:12-16 is the source text the translation must carry, and docs/design/README.md ("Keep section order and heading levels aligned") requires it land in the existing 状态 section rather than as a new heading. Acceptance criterion: N/A (documentation text; no guard, branch, or behavior to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明新增中文版的「状态」小节漏掉了英文 Status 段落(docs/design/code-mode-only.md:12-16)中"Partly superseded by Lazy Code Mode"这一段,导致中英两版结构不同步,违反 AGENTS.md 对双语文档"完整且同步"的要求。 — qwen3.8-max via Qwen Code /review (v0.25.0)
Comment on lines
+87
to
+88
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-3: N01: The sentence this diff rewrote (pre-diff: "one warning names the omitted collision") claims the A registry holding Witness: Suggested fix: Scope the claim to the configuration where it holds and name the other surface, e.g. "When search is unavailable in the current scope, the description names the omitted collision; when The fix must not violate this existing fact: Acceptance criterion: N/A (documentation prose). The behaviour the corrected sentence must match is already pinned from both sides: 中文说明本次改写后的句子声称 — qwen3.8-max via Qwen Code /review (v0.25.0) |
||
| omitted collision. | ||
|
|
||
| The description defines: | ||
|
|
||
| - a fresh async JavaScript execution environment; | ||
| - `tools.<normalizedName>(args)` for nested calls; | ||
| - `ALL_TOOLS`, including canonical and JavaScript names; | ||
| - `text(value)`, `image(value)`, `audio(value)`, and `exit()`; | ||
| - `text(value)`, `image(value)`, `audio(value)`, `generatedImage(value)`, | ||
| `setTimeout(callback, delayMs)`, `clearTimeout(timeoutId)`, and `exit()`; | ||
| - TypeScript-like signatures generated deterministically from JSON Schema; | ||
| - the absence of Node.js, imports, network APIs, timers, and persistent state. | ||
| - the absence of Node.js, `process`, `require`, filesystem, network, imports, | ||
| `console`, `WebAssembly`, `Atomics`, and persistent state. Pending timers do not keep `exec` alive by themselves. | ||
|
|
||
| The nested call returns a JSON-safe object containing the real call id, tool | ||
| name, status, output, and structured content. Failed and cancelled calls reject | ||
|
|
@@ -105,8 +112,8 @@ configuration. The parent maps JavaScript names back to canonical registry | |
| names and dispatches each call. | ||
|
|
||
| The guest has no Node globals, `require`, `process`, filesystem, sockets, | ||
| module loader, `console`, timers, `Atomics`, `SharedArrayBuffer`, or | ||
| `WebAssembly`. Dynamic and static imports fail because no module loader is | ||
| module loader, `console`, `Atomics`, `SharedArrayBuffer`, or `WebAssembly`. | ||
| Dynamic and static imports fail because no module loader is | ||
| installed. Runtime memory and stack limits are fixed. QuickJS's interrupt hook | ||
| enforces a guest CPU budget. That budget and the parent's fallback watchdog | ||
| pause while the guest is suspended on registered host tools, whose own | ||
|
|
@@ -162,14 +169,13 @@ OpenAI-compatible, and Anthropic adapters all receive the structured `exec` | |
| declaration without provider-specific prompting. | ||
|
|
||
| Filtered subagent declarations apply the same policy. For a read-only teammate | ||
| or a fork with an execution allowlist, `exec` is the audited gateway while the | ||
| exact allowed nested names are carried in its invocation context. The same set | ||
| generates the description and is checked again before Core dispatch, so an | ||
| explicit allowlist can narrow code-mode-callable nested tools without becoming | ||
| prompt-only policy, exposing a hidden bridge, or making `exec` recursive. | ||
| For cache-compatible forks, an inherited `exec` declaration represents its | ||
| ordinary bindings: an omitted `fork_tools` inherits them, while an explicit | ||
| list replaces them with the requested subset. | ||
| or a fork with an execution allowlist, `exec` is the audited gateway and the | ||
| nested names carried in its invocation context are checked again before Core | ||
| dispatch. Explicit ordinary-tool entries narrow that nested set. An inherited | ||
| or explicitly allowed `exec` instead represents all surviving ordinary | ||
| code-mode-callable bindings, while the agent's own `tools` list still narrows | ||
| its direct surface. Hidden bridges remain unavailable and `exec` cannot call | ||
| itself. | ||
|
|
||
| ## Failure and rollback | ||
|
|
||
|
|
@@ -178,9 +184,9 @@ closed before scheduling. Invalid arguments continue to fail in the normal | |
| execution chain. A sandbox startup, protocol, timeout, memory, or teardown | ||
| failure becomes an `exec` tool error. | ||
|
|
||
| Rollback is setting `tools.codeModeOnly` to false. No session migration or | ||
| registry cleanup is required because code mode has no persistent state and the | ||
| ordinary registry was never replaced. | ||
| Rollback is setting `tools.mode` to `direct`. No session migration or registry | ||
| cleanup is required because code mode has no persistent state and the ordinary | ||
| registry was never replaced. | ||
|
|
||
| ## Verification | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| # CodeModeOnly MVP | ||
|
|
||
| > 当前行为:Only 模式通过顶层 tool_search 按需加载 schema,并通过 exec 调用。搜索在当前范围不可用时才提供完整签名;tools.eager 可缩小初始声明。Hybrid 继续使用直接工具加 exec,保留其 bridge 与 eager 权限边界。本文以下 MVP 中“隐藏 tool_search / 始终完整 schema”的旧约定已由 [延迟加载设计](lazy-code-mode.zh-CN.md) 取代。 | ||
|
|
||
| [English](code-mode-only.md) | [简体中文](code-mode-only.zh-CN.md) | ||
|
|
||
| ## 状态 | ||
|
|
||
| 已为 [#10377](https://github.com/QwenLM/qwen-code/issues/10377) 实现。 | ||
| 该功能为可选功能,默认关闭。 | ||
|
Comment on lines
+9
to
+10
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-3: The new ZH version's 状态 section omits the English Status paragraph at docs/design/code-mode-only.md:12-16 ("Partly superseded by Lazy Code Mode: The ZH reader never learns that Witness: Suggested fix: Translate the EN Status paragraph into 状态 (adding the The fix must not violate this existing fact: docs/design/code-mode-only.md:12-16 is the source text the translation must carry, and docs/design/README.md ("Keep section order and heading levels aligned") requires it land in the existing 状态 section rather than as a new heading. Acceptance criterion: N/A (documentation text; no guard, branch, or behavior to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明新增中文版的「状态」小节漏掉了英文 Status 段落(docs/design/code-mode-only.md:12-16)中"Partly superseded by Lazy Code Mode"这一段,导致中英两版结构不同步,违反 AGENTS.md 对双语文档"完整且同步"的要求。 — qwen3.8-max via Qwen Code /review (v0.25.0) |
||
|
|
||
| ## 目标 | ||
|
|
||
| 新增 `tools.mode: "code_mode_only"` 设置,用一个 `exec` JavaScript 工具和少量 | ||
| 必须保留为直接调用的控制面工具,取代面向模型的普通工具面。`exec` 中的代码可通过 | ||
| `tools.<name>(args)` 调用普通工具,同时不会绕过 Qwen Code 的校验、权限、审批、 | ||
| hook、遥测、取消、并发或输出预算。 | ||
|
|
||
| 直接模式是兼容性边界:当 `tools.mode` 为 `direct` 时,工具注册、延迟工具行为、 | ||
| provider 请求和执行均保持不变。 | ||
|
|
||
| ## 非目标 | ||
|
|
||
| - 定义混合的直接调用和代码调用;详见 [Code Mode](code-mode.zh-CN.md)。 | ||
| - 在多次 `exec` 调用间持久化 cell、全局变量或值。 | ||
| - 后台任务、`wait`、`yield`、`store` 或 `load`。 | ||
| - 原始/freeform provider 调用。 | ||
| - 在 code mode 中提供 `tool_search` 或 `tool_call` bridge。 | ||
| - 提供兼容 Node.js 的 sandbox。 | ||
|
|
||
| ## 配置 | ||
|
|
||
| ```json | ||
| { | ||
| "tools": { | ||
| "mode": "code_mode_only" | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| 该设置会解析一次,得到有效的 `ToolMode` 值;`ToolRegistry` 和各执行面使用这一 | ||
| 模式。只有启用某个 code mode 时才注册 `exec`,因此选择 `direct` 也会将它从 | ||
| 诊断信息和 registry 列表中移除。 | ||
|
|
||
| ## 暴露策略 | ||
|
|
||
| registry 仍是事实来源。暴露只是注册工具之上的视图,而不是第二套 registry。 | ||
|
|
||
| | 类别 | 模型顶层调用 | `exec` 内的 `tools.*` | | ||
| | ----------------------------------------- | ------------------------ | --------------------- | | ||
| | `exec` | CodeMode 和 CodeModeOnly | 否 | | ||
| | 直接控制工具 | 是 | 否 | | ||
| | 已注册的普通工具 | 仅 CodeMode | 是 | | ||
| | 隐藏 bridge(`tool_search`、`tool_call`) | 严格模式之外沿用既有行为 | 否 | | ||
|
|
||
| 直接控制 allowlist 集中维护且刻意保持精简。它覆盖用户交互 | ||
| (`ask_user_question`)、委派(`agent`)、终止输出约定、 | ||
| plan/goal/task/team/worktree/session 控制,以及生命周期无法安全隐藏在解释执行程序 | ||
| 后的 ACP host 控制。新工具默认可在 code mode 中调用;增加仅直接调用或隐藏工具时, | ||
| 必须显式修改策略。 | ||
|
|
||
| 延迟工具保持注册状态和延迟 registry 状态,并可从 `exec` 调用。生成的 `exec` | ||
| 描述仍会携带这些工具的完整 schema,以及它们在 `ALL_TOOLS` 中的名称和描述: | ||
| CodeModeOnly 会隐藏 `tool_search`,嵌套调用也不会以 `functionCall` 出现在历史记录 | ||
| 中,因此后续 reveal 无法补充描述里遗漏的 schema。CodeModeOnly 会跳过延迟预加载 | ||
| 和 ToolSearch 提醒,因为二者都不属于它面向模型的协议。 | ||
|
|
||
| ## 确定性的 JavaScript 接口 | ||
|
|
||
| 每次向 provider 同步工具前,都会从当前 registry 生成 `exec` 描述。工具按规范 | ||
| 名称排序。名称会通过替换无效标识符字符来规范化为 JavaScript 属性;如果名称以 | ||
| 数字开头,还会添加前缀。如果两个规范名称映射到同一个属性,优先保留与属性精确 | ||
| 一致的规范名称;若都不是精确匹配,则字典序靠前的名称胜出。描述会指出被省略的 | ||
| 冲突项。 | ||
|
|
||
| 描述会定义: | ||
|
|
||
| - 全新的异步 JavaScript 执行环境; | ||
| - 用于嵌套调用的 `tools.<normalizedName>(args)`; | ||
| - 包含规范名称和 JavaScript 名称的 `ALL_TOOLS`; | ||
| - `text(value)`、`image(value)`、`audio(value)`、`generatedImage(value)`、 | ||
| `setTimeout(callback, delayMs)`、`clearTimeout(timeoutId)` 和 `exit()`; | ||
| - 从 JSON Schema 确定性生成的类 TypeScript 签名; | ||
| - 不提供 Node.js、`process`、`require`、文件系统、网络、import、`console`、 | ||
| `WebAssembly`、`Atomics` 和持久状态。待处理的 timer | ||
| 本身不会让 `exec` 保持运行。 | ||
|
|
||
| 嵌套调用返回一个 JSON-safe 对象,其中包含真实 call id、工具名、状态、输出和 | ||
| structured content。调用失败或取消时,guest promise 会使用 scheduler/ACP 错误 | ||
| reject。 | ||
|
|
||
| ## Sandbox 与传输 | ||
|
|
||
| `exec` 在独立子进程中运行编译为 WebAssembly 的 QuickJS。每次调用都会创建全新 | ||
| 的 QuickJS runtime 和 context。子进程通过 stdio 接收精简的 framed JSON 协议; | ||
| 其中不包含工具实现或 Qwen 配置。父进程把 JavaScript 名称映射回规范 registry | ||
| 名称,并分派每次调用。 | ||
|
|
||
| guest 不提供 Node 全局变量、`require`、`process`、文件系统、socket、模块加载器、 | ||
| `console`、`Atomics`、`SharedArrayBuffer` 或 `WebAssembly`。由于没有安装 | ||
| 模块加载器,动态和静态 import 都会失败。runtime 的内存和 stack 限制固定。 | ||
| QuickJS 的 interrupt hook 会限制 guest CPU 预算。当 guest 挂起等待已注册的 host | ||
| 工具时,该预算和父进程的兜底 watchdog 会暂停;在 guest job 再次运行前恢复。 | ||
| 因此,长时间 build 可以继续使用工具声明的 timeout,同时 guest CPU 死循环无法 | ||
| 逃逸固定预算。源码、协议 frame、helper 输出和最终结果都有上限。 | ||
|
|
||
| 取消操作会中止所有嵌套调用并终止子进程。顶层 promise settled 后,也会在 teardown | ||
| 前取消未 await 的嵌套调用。子进程、timer、promise handle 或 guest 全局变量都不 | ||
| 会在调用结束后存活。 | ||
|
|
||
| 子进程只接收最小化且经过清理的环境,guest 无法检查该环境。独立进程为解释器故障 | ||
| 提供纵深防御;QuickJS/WASM 是 guest 的 capability 边界。 | ||
|
|
||
| ## 重入式分派 | ||
|
|
||
| `CoreToolScheduler.schedule()` 无法递归调用:子调用会排在仍在运行的父调用之后, | ||
| 从而形成死锁。因此,scheduler 会在 invocation 边界绑定 async-local | ||
| `ToolCallRuntime` context,`exec` 只与该 context 通信。 | ||
|
|
||
| scheduler runtime 会将同一 event-loop turn 中收到的嵌套调用合并为一批,并通过 | ||
| 使用相同 `Config` 和 observer 配置的 sibling scheduler 执行。这样无需直接调用 | ||
| `tool.execute()`,仍能沿用现有的构建/校验、权限、确认、hook、执行、截断、遥测和 | ||
| 并发链路。guest 的连续 await 会生成连续 batch;`Promise.all` 调用会进入同一个 | ||
| batch,由现有的只读并发分类器处理。嵌套 request id 包含父 id,并携带 | ||
|
Comment on lines
+123
to
+124
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Suggestion] R1-2: The new Chinese translation states the opposite of the English original (docs/design/code-mode-only.md:144-148) on Code Mode shell concurrency: EN says "Code Mode Bash calls bypass the read-only command classifier, with the model responsible for keeping dependent calls sequential. Other tools retain their existing concurrency classification"; ZH says the batch is "由现有的只读并发分类器处理" and drops the Bash carve-out entirely. A reader working from the ZH design concludes that shell calls submitted together inside one Witness: Suggested fix: Translate the two missing EN sentences into the ZH paragraph, e.g. replace "… The fix must not violate this existing fact: Acceptance criterion: N/A (documentation text; no guard, branch, or behavior to pin). Please prove it by removing the fix and confirming that test goes red. 中文说明新增中文翻译在 Code Mode shell 并发这一点上与英文原文相反:英文说 "Code Mode Bash calls bypass the read-only command classifier",中文写成"由现有的只读并发分类器处理",恰好把豁免说成了适用。同仓库的 code-mode-concurrency.zh-CN.md:21 与英文一致,可证这是翻译错误。实测 — qwen3.8-max via Qwen Code /review (v0.25.0) |
||
| `source: code_mode` 和 `parentCallId`。 | ||
|
|
||
| 嵌套 scheduler 更新会合并到所属 scheduler 的可见调用中,嵌套 id 的确认响应也会 | ||
| 委派给它。外层模型仍只接收完整的 `exec` 响应。 | ||
|
|
||
| ACP 沿用其独立审计过的执行链。它的 invocation 边界会绑定相同的 runtime 接口, | ||
| 嵌套分派通过 `Session.runTool` 重入。因此,ACP 顶层和嵌套调用使用相同的 ACP 权限、 | ||
| 审批、hook、遥测、持久化和取消机制,而不是借用 CLI scheduler 状态或直接执行工具。 | ||
| ACP 会串行执行普通嵌套调用,与现有直接工具顺序一致;Core scheduler 则保留现有的 | ||
| 安全只读并行 batch。 | ||
|
|
||
| ## Provider 行为 | ||
|
|
||
| 所有 provider 继续使用 `ToolRegistry` 提供的 `FunctionDeclaration[]`。在 Direct | ||
| 模式下,该数组与现有视图逐字节一致。在 CodeModeOnly 中,它是暴露策略生成的视图, | ||
| 因此 Gemini/Qwen、OpenAI-compatible 和 Anthropic adapter 都会收到结构化的 | ||
| `exec` declaration,不需要 provider 专用 prompt。 | ||
|
|
||
| 经过过滤的子智能体 declaration 使用相同策略。对于只读 teammate 或带执行 | ||
| allowlist 的 fork,`exec` 是经过审计的 gateway,其 invocation context 中携带的嵌套 | ||
| 名称会在 Core 分派前再次校验。显式列出的普通工具会收窄该嵌套集合;继承或显式允许 | ||
| 的 `exec` 则代表所有仍可用的普通 code-mode-callable binding,而智能体自身的 | ||
| `tools` 列表仍会收窄直接调用面。隐藏 bridge 始终不可用,`exec` 也不能调用自身。 | ||
|
|
||
| ## 失败与回滚 | ||
|
|
||
| 未知、冲突、隐藏、仅直接调用和递归请求的工具都会在调度前 fail closed。无效参数 | ||
| 继续在正常执行链中失败。sandbox 启动、协议、timeout、内存或 teardown 失败会转为 | ||
| `exec` 工具错误。 | ||
|
|
||
| 回滚方式是将 `tools.mode` 设为 `direct`。无需迁移 session 或清理 registry, | ||
| 因为 code mode 没有持久状态,且普通 registry 从未被替换。 | ||
|
|
||
| ## 验证 | ||
|
|
||
| 单元和集成测试必须覆盖: | ||
|
|
||
| - Direct 和 CodeModeOnly 暴露、延迟保留、冲突处理、确定性描述和显式子智能体过滤。 | ||
| - 有效/无效 JavaScript、异步顺序、`Promise.all`、helper 输出、throw error、CPU | ||
| 死循环、内存限制、import、不可用全局变量、隔离、输出限制、取消、未 await 工作和 | ||
| 递归调用。 | ||
| - 嵌套权限、确认、Pre/Post hook、失败、输出预算、真实名称遥测/UI 更新、MCP 工具 | ||
| 和 scheduler 死锁回归。 | ||
| - Gemini/Qwen、OpenAI-compatible、Anthropic、headless、interactive、subagent | ||
| 和 ACP 调用面。 | ||
|
|
||
| 只有通过相关 package 测试、build、typecheck、E2E probe 和两轮干净的完整 diff | ||
| 自审,才算实现完成。 | ||
Uh oh!
There was an error while loading. Please reload this page.