让 DSH 在委托会话里一次性无人工地拉起官方 Codex 子代理:通过 app-server 协议把一条纯文本任务交给 Codex 跑并按严格成功条件回传最终答案。
$ dsh plugin --profile web add github:fufankeji/deepseek-harness-studio/packages/subagent/subagent-codexRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
subagent-codex 让 DSH 会话在需要的时候临时拉起一个独立的 Codex 子进程来跑一段纯文本任务:每次都开新的 app-server、不需要人按键审批、跑完把最终答案或失败诊断交给上游;它不改写你的 Codex 账户和设置,只是把官方 app-server 协议接到 DSH 的 subagent 服务上。
app-server --stdio 子进程,进程归 dsh-subprocess 的进程树统一管控(src/run.ts:236-249 / src/run.ts:185-217)phase: "final_answer" 的 agentMessage,没明确 final phase 时回退到最后一条 phase: null 的消息;空回答也会判为错误(README.md:11 / src/run.ts:162-177)thread/start 配置,三种 permissionMode 都不会触发 DSH 交互;未知 server request 直接失败关闭(src/wire.ts:25-36, 86-94 / README.md:13)SubagentResult.diagnostic(src/run.ts:84-114 / src/run.ts:358-365)inheritsParentContext: false,父会话的对话、角色、工具过滤、深度策略都不会下发到子 Codex(src/index.ts:62 / README.md:21)lib/index.js 与 lib/types/*.d.ts,见 package.json:13-27)。@openai/codex@0.147.0(官方 SDK,含六个平台子包携带 app-server 2.1.220 的 JavaScript wrapper 与原生 codex 二进制)、@deepseek-ai/dsh-subagent(共享任务接缝与结果结算)、@deepseek-ai/dsh-subprocess(负责真 CLI 进程的进程树托管)、@deepseek-ai/dsh-timeout(MAX_TIMER_DELAY_MS 上限校验)(package.json:49-53 / src/run.ts:9-29 / src/index.ts:11)。src/index.ts 命名导出 name/inject/Config/apply;apply(ctx, config) 把一个 CodexProvider 注册到 ctx.subagents,由 cordis.patch.yml 顺势注入 dsh-base 之上。运行时通过 createRequire 解析 @openai/codex/package.json 的 bin.codex,用当前 Node 可执行文件拉起 wrapper;JSON-RPC 帧层由 dsh-sdk-protocol 提供,wire.ts 只负责产品方法、当前 thread/turn 关联、无人值守审批应答和最终答案选择(src/index.ts:30-32, 113-135 / cordis.patch.yml:1-5 / src/run.ts:43-52, 132-134 / src/wire.ts:9-14)。src/index.ts(Cordis 注册入口)、src/run.ts(一次性任务生命周期与 run spec)、src/wire.ts(Codex app-server 0.147.0 协议适配器)。把"我不想动手、就让 Codex 自己去干"的一段独立任务交给子 Agent,常见做法是让 DSH 主对话里的模型在工具白名单里看到 subagent_codex 后按需触发,比如一次性生成长文档、批量改文件、或让 Codex 自己拉一份现状总结再带回主对话。本包不适合需要持续对话、要看中间步骤、或者要求 Codex 一路弹交互确认的场景——这些需求跟"一次性、无人工、只读最终答案"的定位天然冲突。
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH(launcher) | 0.1.0-rc.8 | 本包和同仓库其它包同版本(package.json:4),作为 Profile Bundle 注入 dsh-base 上层(cordis.patch.yml:1-5)。 |
| Node.js | ^22.19.0 || >=24.0.0 | 仓库根 engines.node 约束,subagent-codex 自身未声明独立范围(仓库根 package.json:8-10)。 |
| 平台 | 跨平台(macOS / Windows / Linux) | 实际可执行的 app-server 由 @openai/codex@0.147.0 的六个平台子包按系统/CPU 自带;省略 optional dependencies、不被支持的系统、载荷文件缺失都会让 provider 注册能成功但第一次委派在 app-server 启动边界失败(README.md:97-101)。 |
| Codex app-server | 0.147.0(随 @openai/codex 平台包) | 由 0.147.0 锁定,不依赖宿主 codex;本包也不查 PATH、不做平台选择、不回退到宿主二进制(README.md:42 / src/run.ts:43-52)。 |
| 原生模块 | codex / codex-code-mode-host / rg / zsh(darwin-arm64 平台包自带) | 安装后由 Codex 平台包携带,DSH 这边不再引入新的原生模块;其它平台载荷可能不同(README.md:97)。 |
disposeGraceMs 上限 | ≤ MAX_TIMER_DELAY_MS(2 147 483 647) | apply() 启动时校验,正有限值且不得超过仓库 dsh-timeout 共享上限(src/index.ts:120-129 / packages/util/timeout/src/index.ts:25)。 |
dsh plugin --profile web add github:fufankeji/deepseek-harness-studio/packages/subagent/subagent-codex
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
providerName | 字符串(非空) | 在 ctx.subagents 上的注册名,同时给 dsh-tool-subagent 工具行的 provider 字段引用;同一个 Profile 挂多份实例时需要互不重复(src/index.ts:38, 51 / README.md:27)。 | codex |
env | 对象(Record<string, string>) | 显式透传给 Codex app-server 子进程的环境变量,叠在父环境已被共享机制清掉凭证后的子集上;想让子进程拿到 OPENAI_API_KEY 时必须在这里显式声明(src/index.ts:43, 52 / src/run.ts:241 / README.md:42)。 | {} |
permissionMode | 枚举:never / approve-for-me / dangerously-bypass-approvals-and-sandbox | 选定这个 provider 实例的 Codex 原生非交互权限与沙箱模式;never 表示不发审批请求、approve-for-me 走 Codex 自动评审、dangerously-bypass-approvals-and-sandbox 会同时关掉审批和沙箱(src/run.ts:55-68 / README.md:32-36)。 | never |
disposeGraceMs | 数字(毫秒,正有限值) | 共享进程树主人在各终止 tier 之间的等待时长,随后要等到整棵进程树退出才算清场(src/index.ts:47, 55, 120-129 / src/run.ts:240)。 | 3000 |
Q: 跟直接接 Codex API 有什么区别?是不是更简单的接入?
A: 不一样。这个包是 dsh 的"subagent 供应商"角色,承接 dsh-tool-subagent 那边发来的一次性请求,每次启全新的 Codex app-server 进程跑完就结束;它不替 Codex 选模型、不持久化 Codex 会话、不复制 Codex settings。dsh-base 里默认的 deepseek 入口是主对话模型,跟这个 provider 在进程级别就是独立的两条线(README.md:42, 135)。
Q: env 是不是只放 OPENAI_API_KEY?别的变量怎么传?
A: 不是只能放 key,但请把 key 放在这里。父进程里任何被判定为凭证形态的环境变量在传给子进程前都会被 dsh-subprocess 剥掉。HOME、CODEX_HOME 这种非凭证变量会被自然继承,要在 env 里显式覆盖也可以。DSH 这边不会创建账户、不会登录 Codex、不会改 settings 文件;登录态和有效 key 都得由 Codex 那一侧自己保证存在(README.md:42 / src/run.ts:241)。
Q: 安装好之后,模型怎么才知道有 subagent_codex 这个工具?
A: 并不知道,要靠你的 Agent Preset。full Preset 默认把对应的 tool 行设成 disabled: true,需要先复制 Preset 再去掉这一字段;起一个基于复制品的新 Session 时,模型才会看到那个静态工具名。每个 dsh-tool-subagent 行需要一个独立 toolName 暴露给模型,因此同 Profile 下挂多份 provider 时也要给每个工具起不同的名字(README.md:52)。
Q: 子进程里跟 Codex 的设置文件是怎样生效的?
A: 走原生 Codex 配置的相对路径,本包既不指定 CODEX_HOME、也不去 copy / 过滤 settings 文件。所以在父会话的工作目录下会按 Codex 自家的 project / user 三层去找配置和登录态。也就是说你能在项目里放一份 .codex/settings.json 影响这个 provider,而卸载本包不会动到你这些文件(README.md:42)。
Q: 怎么从失败里看出到底是 Codex 报错还是子进程没起来?
A: 看 SubagentResult.diagnostic 里的 stage 段:initialize / thread-start 多半是启动期问题(比如平台包找不到、载荷缺失),turn-start / turn 是 Codex 协议层出错,process 是 CLI 已经退出但没正常出结果,teardown 是清理阶段 sub-process 退出失败。同时出现的 exit code / signal 行就是进程层的真实退出原因;HTTP 状态码只在 Codex 提供时才会出现在诊断里。原始的产品层或 Host 错误永远在 Error 的 cause 链里,不会直接进入这条 diagnostic(src/run.ts:84-114, 358-365 / src/wire.ts)。
Q: permissionMode 的三个值该怎么选?
A: 不想弹任何审批框就用默认的 never,Codex 对没预先授权的操作会直接拒绝;想让 Codex 改文件但仍然不让它问人就把 permissionMode 换成 approve-for-me,这时 Codex 会走自动评审而不是 DSH 弹窗;dangerously-bypass-approvals-and-sandbox 是把原生审批与沙箱同时关掉,让 Codex 像脱缰一样能在任何路径下做任何事,原则上只在受控 / 沙箱环境里用。DSH 这边三种模式都不会创建交互通道,所有审批都走 Codex 自身的设置(README.md:34-40 / src/wire.ts:25-36)。
Q: 我能让一个工具实例同时支持 foreground 和后台跑吗?
A: 可以,但需要分两个工具行。dsh-tool-subagent 的 backgroundMode 选 one-shot 时,省略 run_in_background 或传 false 走前台(同步阻塞);传 true 则立刻返回一个由父 Agent 拥有的 Job id,配合 dsh-tool-jobs 提供的 job_output / job_kill 后续拉。前提是你的 Profile 已经装好本地作业服务(@deepseek-ai/dsh-jobs-local / dsh-tool-jobs)(README.md:52)。
Q: 卸载这个包会不会带走什么副作用?
A: 没有持久副作用。卸载后下一次 Profile 启动就把这个 provider 注销,本包没有任何独立磁盘写入或独立账户创建;登录态、Codex settings 文件、缓存都还在 Codex 那一侧独立保留(README.md:44 / README.md:144)。
进阶 —— 需要先看懂 dsh 的 Profile Bundle 模型、cordis patch 注入顺序、dsh-tool-subagent 与 job 的接缝,并且要会自己配置 Codex 那边的 settings 和 key 才能让子进程跑通;如果只想"插上去就能用"会觉得整条链路偏长。
toolName(README.md:136)unknown 回退报出来(README.md:137)initialize 失败,不存在"宿主 CLI 回退"路径(README.md:138 / src/run.ts:243-248)permissionMode 都不会创建 DSH 交互通道或逐次调用 allow 策略(README.md:140 / src/wire.ts:38-51)