Integrate the observed master checkpoint 7ab215e23e5d977aae7eb5d4fb91782d39969dbb without rewriting the earlier published checkpoints. Master adds current-directory events, directory-aware consumers, and retained Git worktrees; its old subagent startup paths overlapped the unified activation implementation. Resolve directory selection within managed startup after acquiring parent ownership. Preserve the original Session origin while setting each new local child directory, retain persisted directory state on cold resume, and pass a required absolute cwd to external providers. Keep unified local/external ownership, full completion notices, parked-input host completion, SDK wait/error/shutdown behavior, and ACP cancellation semantics. Retain removal of the old in-process driver and continuation managers. Combine SDK wait with the new directory requests, preserve the new master directory/worktree fixtures, regenerate derived catalogs from the combined sources, and refresh only the four stale prompt/schema sidecars. Preserve every protected historical schema, archived note, catalog-v2 acknowledgement, and recorded predecessor input. Validation: full build; 59 CI static gates; 855 subagent tests with 100% coverage on changed core/external sources; affected consumer suites including 119 repaired-fixture tests; SDK 11 and headless 16 recorded scenarios; two local headless expected cases; six built nested SDK/ACP cases; lint, strict cast inventory, workspace constraints, and whitespace checks. Native Windows worker diagnostics remain additive and require the next CI run to classify the original crash.
description, kind
| description | kind |
|---|---|
| The one-shot Codex subagent provider for users and maintainers choosing a product backend, installing a Profile bundle, or configuring an unattended Codex delegation. | package-bundle |
@deepseek-ai/dsh-subagent-codex
English | 中文
Summary
Install @deepseek-ai/dsh-subagent-codex into a Profile when delegated work should run in a genuine, unattended Codex session in the parent Session's workspace. Each delegation uses a fresh isolated Codex thread for one self-contained text task and returns only its final answer or a safe failure diagnostic. Native Codex configuration and authentication remain authoritative, while permissionMode selects the non-interactive approval and sandbox behavior. The Bundle supplies a compatible native Codex payload, but it exposes no model capability until a delegation tool is configured.
Table of Contents
- Use this package
- Understand the implementation
- Further Exploration
- Model Experience
- Known Limitations and Deferred Work
- Dev Note
Use this package
Mount this provider when a delegation should run as a real Codex session in the parent's workspace. The common path is explicit: install the Bundle into a Profile, optionally configure the provider row, and expose it to the model through a delegation tool row.
Installing the Bundle
Install the package into the target Profile, then restart that Profile. The installation brings the official wrapper and one compatible native platform payload into the Profile; the declared patch layer registers only the dormant provider and starts no Codex process.
dsh plugin --profile <name> add @deepseek-ai/dsh-subagent-codex
dsh plugin --profile <name> remove @deepseek-ai/dsh-subagent-codex
dsh --profile <name>
Removing the package withdraws the provider and its private runtime closure on the next Profile start. Installation controls Host availability, not model permission: the model can only reach the provider through a delegation tool row you compose.
Configuration
| Field | Default | Meaning |
|---|---|---|
providerName |
codex |
Non-empty registry name on ctx.subagents; each mounted instance needs a unique value |
model |
native Codex settings | Optional non-empty model name fixed for every thread from this provider instance; omission sends no app-server override |
env |
{} |
Explicit child environment layered over the credential-scrubbed parent environment |
permissionMode |
never |
Native non-interactive approval and sandbox mode fixed for every thread from this provider instance |
disposeGraceMs |
3000 |
Grace between the shared managed-range owner's termination tiers |
permissionMode value |
thread/start fields |
Native behavior |
|---|---|---|
never |
approvalPolicy: never; sandbox omitted |
Never ask for approval; execution failures return to the model under the native sandbox |
approve-for-me |
approvalPolicy: on-request, approvalsReviewer: auto_review, sandbox: workspace-write |
Route permission requests through Codex automatic review without a human |
dangerously-bypass-approvals-and-sandbox |
approvalPolicy: never, sandbox: danger-full-access |
Skip approval and sandbox enforcement; this value must be selected explicitly |
The generated configuration catalog is the exhaustive source for every accepted field and its JSDoc. A configured model passes unchanged on each ephemeral thread/start; omission leaves native model selection in force. The provider does not discover models, rewrite aliases, select modelProvider or serviceTier, or set a fallback. Credential-shaped ambient variables are removed before the explicit env overlay, so an API key intended for the child must be supplied there.
Exposing the tool
Each delegation tool row names one provider and needs its own toolName, so the model sees static tools rather than a dynamic provider selector. Full Agent Presets carry a matching default tool row with disabled: true; copy a preset and remove that field to expose subagent_codex only to agents composed from the copy.
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex
toolName: subagent_codex
maxDepth: provider-managed
The tool returns a child id after accepting the task and sends its result to the parent Agent on completion. Each external activation executes once and accepts no follow-up input or resume.
What you get
The completion notice contains the final Codex answer, or the stop reason and optional safe diagnostic. The parent Session also retains the external task identity and complete terminal result independently of the notice; no local child Session is created. Product reasoning, tool activity, raw stderr, and workspace diffs do not enter the parent Session.
Failure and recovery
An install that omits optional dependencies, uses an unsupported platform, or loses the selected payload leaves the provider dormant and fails the first delegation at initialize with a safe unknown category and any observed process outcome; there is no host-CLI fallback. Raw wrapper text stays on Host stderr. A cancelled run settles as aborted.
Understand the implementation
Implementation internals — click to expand
This section explains how the provider drives a real Codex app-server and where the observable behavior comes from; the full contract lives in Use this package.
Design concept
- One fresh process, thread, and turn per run. Every run spawns a fresh app-server, creates one ephemeral thread, and executes exactly one turn; there is no continuation, resume, or pooling.
- Native configuration is authoritative. Codex configuration and authentication stay native through the parent cwd,
HOME, andCODEX_HOME; the provider overrides only the optional model and the thread's approval, reviewer, and sandbox fields. - Unattended by design. Approval, user-input, and MCP requests are answered or declined without a human; unknown server requests fail the run.
Source map
| File | Role |
|---|---|
src/index.ts |
Plugin entry: config schema, provider registration |
src/run.ts |
The run lifecycle, turn execution, result selection, and diagnostics |
src/wire.ts |
The minimal app-server JSON-RPC wire implementation |
cordis.patch.yml |
The Profile patch layer that registers the dormant provider |
Run flow
A start accepts only a non-empty sequence of text blocks and derives the child cwd from the parent session. It spawns the fixed command through the subprocess seam, performs the initialize → initialized handshake, maps the Profile-selected mode and optional model into official thread/start fields beside { cwd, ephemeral: true }, and publishes the run only after Codex returns a valid ephemeral thread. The published result starts exactly one turn, accepts only notifications for that run's thread and turn, and waits for the authoritative turn/completed terminal. The latest agentMessage with phase: "final_answer" wins; when Codex emits no explicit final phase, the latest message with phase: null is the compatibility fallback. A successful turn with no nonblank answer settles as an error. Failed turns use the coarse categories limit, access-policy, service, transport, product-error, invalid-result, or unknown; an early app-server exit uses process, and applicable connection and stream failures retain a numeric httpStatusCode.
Further Exploration
Read these pages when the package-level contract is not enough. They move from this provider to the seam it plugs into and the sibling product provider.
- Subagent subsystem — the service contract, provider contract, and terminal result semantics.
- dsh-subagent seam — the registry and start API this provider registers on.
- Claude Code subagent provider — the sibling product backend over the official Agent SDK.
- historical Claude Code and Codex backends — the design record for the product providers.
- Generated configuration catalog — every accepted config field and its source declaration.
Model Experience
Child request
What the model sees
The Codex child receives the standalone text blocks as one turn in a fresh ephemeral thread. Its workspace is the selected child working directory; the selected Provider instance fixes any configured model, environment, non-interactive approval policy, and sandbox mode, while an omitted model and every other product setting come from native Codex configuration. The executable version comes from the Bundle's pinned platform payload.
Token effect
The child pays for an independent Codex context and turn. Child tokens do not enter the parent's context.
KV Cache effect
Independent of the parent request cache. Reuse depends only on Codex's own provider, model, instructions, tools, and ephemeral-thread request.
Parent scheduling and results, indirectly
What the model sees
Through dsh-tool-subagent, the parent model first receives a child id, then the final Codex answer or a failure notice with its stop reason and safe diagnostic. Diagnostics contain only fixed stage, category, and observed protocol or process facts. Product reasoning, intermediate messages, tool activity, stderr, usage, product identifiers, commands, paths, and raw protocol payloads are not copied into the parent Session.
Token effect
Parent input grows by the start acknowledgement and completion notice, including the final answer or failure detail. Child tokens do not enter the parent context. This provider adds no parent tool schema by itself.
KV Cache effect
Start acknowledgements and completion notices append after the reusable parent request prefix. A notice may wake another turn without rewriting the existing prefix.
Known Limitations and Deferred Work
These limits define when this provider is a poor fit or needs special operational care. They are current package constraints, not a general Codex comparison or a task backlog.
- One fresh process, thread, and turn per run — there is no continuation, resume, pooling, progress stream, or product-session persistence.
- Static instance selection — Profile rows fix provider names, optional models, and tool bindings; calls cannot choose or change either a provider or model dynamically, and every exposed tool needs a unique
toolName. - Authentication and account state remain native — the Bundle supplies the CLI but does not create an account, log in, trust a project, or rewrite Codex settings; configuration and authentication failures surface with their lifecycle stage and the safe
unknownfallback rather than a separate public taxonomy. - The native platform payload is required at delegation time — installs that omit optional dependencies, unsupported platforms, and missing or damaged payloads fail at the first run; there is no host-CLI fallback.
- Compatibility is pinned by development evidence — upgrading from the verified 0.153.4 protocol baseline requires regenerating upstream schema evidence and rerunning handshake, answer-selection, approval, cancellation, keyless real-product, and credentialed DeepSeek nonce tests.
- No human approval path — known unattended approval requests are denied and unknown server requests fail closed; the three Profile modes never create a DSH interaction channel or per-call allow policy.
- Assistant payload is final text only — failed runs can also expose a separate safe diagnostic; reasoning, intermediate messages, tool traffic, usage, stderr, and workspace diffs remain outside the parent Session. Task identity and terminal results are retained in the parent log.
- No optional shared capabilities —
agentOptions, output schemas, child personas, tool filtering, and harness depth enforcement are rejected by the shared service for this provider. - No wall-clock timeout or side-effect rollback — the caller cancels long work, and files or external systems changed before cancellation are not restored.
Dev Note
Working context for maintainers — click to expand
This Dev Note is working context for maintainers: open questions and undecided directions. It is explicitly non-authoritative — shipped behavior and limits live in the sections above and in the package code.
- Payload size disclosure — the current darwin-arm64 platform payload packs to about 114 MB and unpacks to about 282 MB; these are disclosure numbers, not installation thresholds.
- Version-pinned protocol — the runtime dependency is pinned to
@openai/[email protected]; upgrading requires regenerating the upstream schema evidence and rerunning the credentialed nonce tests.