fix(subagent): keep Codex provider opt-in
This commit is contained in:
8 files changed
+4
-35
No files matched your search
+2
-2
@@ -2,5 +2,5 @@
|
||||
# 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 .agents/notes/proposed/feature/2026-08-04-claude-code-and-codex-subagent-backends.md
|
||||
2026-08-04-claude-code-and-codex-subagent-backends.md: 52181edba816f651877eac2c616cf67191f7e550
|
||||
2026-08-04-claude-code-and-codex-subagent-backends.zh.md: bde24eb8939b10c10916dab93effd3b94cbc7e1b
|
||||
2026-08-04-claude-code-and-codex-subagent-backends.md: 37f45f844c9411af0467397272649533ed4d44cc
|
||||
2026-08-04-claude-code-and-codex-subagent-backends.zh.md: dcd7b90231bdaed47435c27deef413d20f0b7f28
|
||||
+1
-3
@@ -16,7 +16,7 @@ The harness provides two sibling one-shot providers behind two fixed model-facin
|
||||
|
||||
The Codex provider is implemented against Codex 0.146.0. The Claude Code provider remains unimplemented. This Note remains proposed until both siblings and their combined evidence are present.
|
||||
|
||||
Both providers report `inheritsParentContext: false`, advertise no optional start capabilities, and pass the parent Session cwd without copying the parent conversation. Their fixed tools use `maxDepth: 'provider-managed'` because each out-of-process product owns any delegation budget inside its own harness; the parent sends no recursion cap that the provider cannot enforce. Every call creates a fresh product process and a non-resumable product conversation. The shared subagent service continues to own request resolution, lifecycle events, result settlement, and foreground collection; the shared subprocess service owns credential scrubbing, process-tree termination, and whole-tree exit observation.
|
||||
Both providers report `inheritsParentContext: false`, advertise no optional start capabilities, and pass the parent Session cwd without copying the parent conversation. Every call creates a fresh product process and a non-resumable product conversation. The shared subagent service continues to own request resolution, lifecycle events, result settlement, and foreground collection; the shared subprocess service owns credential scrubbing, process-tree termination, and whole-tree exit observation.
|
||||
|
||||
```text
|
||||
fixed tool → shared subagent service → product provider → official product process
|
||||
@@ -37,8 +37,6 @@ fixed tool → shared subagent service → product provider → official product
|
||||
|
||||
`@deepseek-ai/dsh-subagent-codex` registers the fixed `codex` provider and always starts `codex app-server --stdio` from `PATH`. Its public configuration contains only an explicit `env` overlay and a positive finite `disposeGraceMs`. Installation, login, `CODEX_HOME`, model selection, base URL, sandbox, approval policy, and product-session settings remain native Codex or deployment responsibilities.
|
||||
|
||||
The shipped `apps/cli/config/base.cordis.yml` loads this provider and a fixed `subagent_codex` tool by default, while `apps/cli/package.json` carries the provider package in the CLI dependency closure. Loading the base does not probe the Codex binary or authentication; missing native availability fails only when the tool is called.
|
||||
|
||||
Before publication, the provider validates a non-empty text-only task, starts the managed app-server in the parent workspace, completes `initialize` → `initialized`, and creates an `ephemeral: true` thread. The published run owns exactly one `turn/start`; its thread and turn ids remain private and are never persisted in the parent Session.
|
||||
|
||||
`turn/completed` is the authoritative remote terminal fact. The latest nonblank `agentMessage` with `phase: "final_answer"` wins. When the product emits no explicit final phase, the latest message with `phase: null` is the compatibility fallback; commentary never replaces either answer. A completed turn without an answer, a failed or interrupted remote turn, malformed wire data, protocol closure, early process exit, or unknown server request becomes `error`. Local cancellation wins its race and remains `aborted`.
|
||||
|
||||
+1
-3
@@ -16,7 +16,7 @@ harness 在两个固定的面向模型工具背后提供两个一次性兄弟提
|
||||
|
||||
Codex 提供方基于 Codex 0.146.0 实现。Claude Code 提供方仍未实现。在两个兄弟提供方及其组合证据全部具备之前,本 Agent Note 将保持提案状态。
|
||||
|
||||
这两个提供方都报告 `inheritsParentContext: false`,不声明任何可选的启动时功能,并传递父会话 cwd,但不会复制父级对话。固定工具使用 `maxDepth: 'provider-managed'`,因为每个进程外产品都负责其自身 harness 内部的委派预算;父级不会传入提供方无法执行的递归上限。每次调用都会创建一个全新的产品进程和一次不可续接的产品对话。共享 subagent 服务继续负责请求解析、生命周期事件、结果结算和前台收集;共享子进程服务负责凭证清洗、进程树终止以及整棵进程树的退出观测。
|
||||
这两个提供方都报告 `inheritsParentContext: false`,不声明任何可选的启动时功能,并传递父会话 cwd,但不会复制父级对话。每次调用都会创建一个全新的产品进程和一次不可续接的产品对话。共享 subagent 服务继续负责请求解析、生命周期事件、结果结算和前台收集;共享子进程服务负责凭证清洗、进程树终止以及整棵进程树的退出观测。
|
||||
|
||||
```text
|
||||
fixed tool → shared subagent service → product provider → official product process
|
||||
@@ -37,8 +37,6 @@ fixed tool → shared subagent service → product provider → official product
|
||||
|
||||
`@deepseek-ai/dsh-subagent-codex` 注册固定的 `codex` 提供方,并始终启动 `codex app-server --stdio`,该命令从 `PATH` 解析。其公开配置仅包含显式的 `env` 覆盖项和须为正有限值的 `disposeGraceMs`。安装、登录、`CODEX_HOME`、模型选择、基础 URL、沙箱、审批策略和产品会话设置仍由 Codex 原生机制或部署环境负责。
|
||||
|
||||
正式发布的 `apps/cli/config/base.cordis.yml` 默认加载这个提供方和固定的 `subagent_codex` 工具,而 `apps/cli/package.json` 将提供方包纳入 CLI 依赖闭包。加载基础配置时不会探测 Codex 二进制程序或身份验证;缺少原生可用条件只会在工具实际调用时失败。
|
||||
|
||||
发布前,提供方会验证非空的纯文本任务,在父级工作区中启动受管的 app-server,完成 `initialize` → `initialized` 握手,并创建一个 `ephemeral: true` 线程。已发布的运行只拥有一次 `turn/start`;其线程 ID 与轮次 ID 保持私有,绝不会持久化到父会话。
|
||||
|
||||
`turn/completed` 是权威的远端终止事实。以最后一条非空白的 `agentMessage` 为准,但它必须带有 `phase: "final_answer"`。若产品没有发出明确的最终阶段,则以最后一条 `phase: null` 的消息作为兼容性回退;过程说明绝不会取代上述任一答案。轮次完成却没有答案、远端轮次失败或中断、协议数据格式错误、协议关闭、进程提前退出或未知的服务器请求,都会产生 `error`。本地取消在竞态中胜出并保持为 `aborted`。
|
||||
|
||||
@@ -94,8 +94,6 @@ flowchart LR
|
||||
cfg --> plugin_dsh_base_subagent_spawn
|
||||
plugin_dsh_base_subagent_fork["subagent-fork<br/>@deepseek-ai/dsh-subagent-fork"]
|
||||
cfg --> plugin_dsh_base_subagent_fork
|
||||
plugin_dsh_base_subagent_codex["subagent-codex<br/>@deepseek-ai/dsh-subagent-codex"]
|
||||
cfg --> plugin_dsh_base_subagent_codex
|
||||
plugin_dsh_base_tool_subagent_control["tool-subagent-control<br/>@deepseek-ai/dsh-tool-subagent-control"]
|
||||
cfg --> plugin_dsh_base_tool_subagent_control
|
||||
plugin_dsh_base_tool_subagent_list_agents["tool-subagent-list-agents<br/>@deepseek-ai/dsh-tool-subagent-control/list-agents"]
|
||||
@@ -104,8 +102,6 @@ flowchart LR
|
||||
cfg --> plugin_dsh_base_tool_subagent
|
||||
plugin_dsh_base_tool_subagent_fork["tool-subagent-fork<br/>@deepseek-ai/dsh-tool-subagent"]
|
||||
cfg --> plugin_dsh_base_tool_subagent_fork
|
||||
plugin_dsh_base_tool_subagent_codex["tool-subagent-codex<br/>@deepseek-ai/dsh-tool-subagent"]
|
||||
cfg --> plugin_dsh_base_tool_subagent_codex
|
||||
plugin_dsh_base_tool_subagent_report["tool-subagent-report<br/>@deepseek-ai/dsh-tool-subagent-report"]
|
||||
cfg --> plugin_dsh_base_tool_subagent_report
|
||||
plugin_dsh_base_workflow_workerthread["workflow-workerthread<br/>@deepseek-ai/dsh-workflow-workerthread"]
|
||||
@@ -195,12 +191,10 @@ flowchart LR
|
||||
| `subagent` | `@deepseek-ai/dsh-subagent` |
|
||||
| `subagent-spawn` | `@deepseek-ai/dsh-subagent-spawn` |
|
||||
| `subagent-fork` | `@deepseek-ai/dsh-subagent-fork` |
|
||||
| `subagent-codex` | `@deepseek-ai/dsh-subagent-codex` |
|
||||
| `tool-subagent-control` | `@deepseek-ai/dsh-tool-subagent-control` |
|
||||
| `tool-subagent-list-agents` | `@deepseek-ai/dsh-tool-subagent-control/list-agents` |
|
||||
| `tool-subagent` | `@deepseek-ai/dsh-tool-subagent` |
|
||||
| `tool-subagent-fork` | `@deepseek-ai/dsh-tool-subagent` |
|
||||
| `tool-subagent-codex` | `@deepseek-ai/dsh-tool-subagent` |
|
||||
| `tool-subagent-report` | `@deepseek-ai/dsh-tool-subagent-report` |
|
||||
| `workflow-workerthread` | `@deepseek-ai/dsh-workflow-workerthread` |
|
||||
| `tool-workflow` | `@deepseek-ai/dsh-tool-workflow` |
|
||||
|
||||
@@ -254,9 +254,6 @@
|
||||
config:
|
||||
providerName: fork
|
||||
|
||||
- id: subagent-codex
|
||||
name: '@deepseek-ai/dsh-subagent-codex'
|
||||
|
||||
# Continuable background children are selected per delegation tool. The
|
||||
# separately loaded follow-up tool registers the one global `send_message`.
|
||||
- id: tool-subagent-control
|
||||
@@ -279,14 +276,6 @@
|
||||
toolName: subagent_fork
|
||||
backgroundMode: continuable
|
||||
|
||||
- id: tool-subagent-codex
|
||||
name: '@deepseek-ai/dsh-tool-subagent'
|
||||
config:
|
||||
provider: codex
|
||||
toolName: subagent_codex
|
||||
enableRunInBackground: false
|
||||
maxDepth: 'provider-managed'
|
||||
|
||||
# Optional direct-child return channel; absent from roots and one-shot agents.
|
||||
- id: tool-subagent-report
|
||||
name: '@deepseek-ai/dsh-tool-subagent-report'
|
||||
|
||||
@@ -98,7 +98,6 @@
|
||||
"@deepseek-ai/dsh-storage-domain": "workspace:^",
|
||||
"@deepseek-ai/dsh-storage-json": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent-codex": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent-fork": "workspace:^",
|
||||
"@deepseek-ai/dsh-subagent-spawn": "workspace:^",
|
||||
"@deepseek-ai/dsh-subprocess-local": "workspace:^",
|
||||
|
||||
@@ -85,7 +85,6 @@ function startRawLifecycle(fixture: RawLifecycleFixture) {
|
||||
env: {
|
||||
DSH_HOME: fixture.home,
|
||||
DSH_TELEMETRY_DISABLED: '1',
|
||||
PATH: fixture.home,
|
||||
RAW_READY_FILE: fixture.ready,
|
||||
RAW_SETTLED_FILE: fixture.settled,
|
||||
RAW_DISPOSED_FILE: fixture.disposed,
|
||||
@@ -164,11 +163,6 @@ describe.skipIf(!existsSync(dshBin))('dsh BUILT bin (node lib/bin.js, no tsx)',
|
||||
expect(stdout).toContain("name: '@deepseek-ai/dsh-agent-loop'")
|
||||
expect(stdout).toContain('agents: []')
|
||||
expect(stdout).toContain('# == base.cordis.yml')
|
||||
expect(stdout).toContain("name: '@deepseek-ai/dsh-subagent-codex'")
|
||||
expect(stdout).toContain('provider: codex')
|
||||
expect(stdout).toContain('toolName: subagent_codex')
|
||||
expect(stdout).toContain('enableRunInBackground: false')
|
||||
expect(stdout).toContain('maxDepth: provider-managed')
|
||||
}, 30_000)
|
||||
|
||||
it('composes the required raw overlay directly over the base', async () => {
|
||||
|
||||
Generated
-3
@@ -377,9 +377,6 @@ importers:
|
||||
'@deepseek-ai/dsh-subagent':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/subagent/subagent
|
||||
'@deepseek-ai/dsh-subagent-codex':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/subagent/subagent-codex
|
||||
'@deepseek-ai/dsh-subagent-fork':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/subagent/subagent-fork
|
||||
|
||||
Reference in New Issue
Block a user