Plugin directory / Developer / dsh-better-codex-subagent
dsh-better-codex-subagent
Verified · install-tested on dsh ivwumupy
What it does
A plugin in the Developer category for DeepSeek Harness.
Works — verified, early-stage project
A plugin in the Developer category for DeepSeek Harness. It installs cleanly and boots without issues in our testing. It's early-stage but functional.
“Verified” means our automated CI actually ran dsh plugin add in a clean profile and it booted — nothing more. Feature descriptions and version compatibility are the author’s claims. This is not a security audit and not an endorsement of third-party code.
README
dsh-better-codex-subagent
English | 中文
A drop-in replacement for the fixed codex subagent provider
(@deepseek-ai/dsh-subagent-codex)
that additionally mirrors the Codex app-server stream into a harness child
session. Every Codex run therefore renders as an ordinary one-shot subagent in
the session tree and Web UI: a discoverable child node under the delegating
session, with the delegated task, the assistant answers, and the tool
executions (commands and file changes) as a normal conversation transcript.
The provider registers under the same codex name, so thetool-subagent-codex tool row (provider: codex) keeps working unchanged.
Loading this plugin together with @deepseek-ai/dsh-subagent-codex fails loud
on the duplicate provider name — compose one or the other.
Start and ownership
start(request) derives the child cwd from the parent Session, spawns the
fixed codex app-server --stdio command through dsh-subprocess, and performsinitialize → initialized → thread/start { cwd, ephemeral }. Only after
the app-server returns a thread matching the requested lifetime does the
provider create the projection child session, seed it (descriptor, turn start,
user task), and publish the run. A failure before publication closes the wire,
terminates the managed process tree, waits for it to exit, and rejectsstart() — no orphan child session is left behind.
The published run's result contract is identical to the base provider: one
turn, the authoritative turn/completed terminal notification, and the
latest agentMessage with phase: "final_answer" (or the phase: null
compatibility fallback) as the returned answer. Local cancellation maps toaborted, contextWindowExceeded to max-tokens, and any other remote
failure to error. dispose() is idempotent and reaches whole-tree
quiescence. The projection session stays in the store after the run settles
as a terminal, read-only one-shot child; the Web UI already renders one-shot
subagent conversations read-only.
Projection
The child session mirrors the app-server notification stream through a
stateful transcript:
| App-server notification | Projection-session events |
|---|---|
item/agentMessage/delta |
accumulated per item id |
item/completed (agentMessage, final_answer or null phase) |
assistant/message with the accumulated or completed text |
item/started / item/completed (commandExecution) |
tool/call (exec_command with command/cwd) + tool/result (aggregatedOutput, else exit code, else status) |
item/started / item/completed (fileChange) |
tool/call (fileChange with path/kind changes) + tool/result (path summary) |
| run settlement | turn/end (completed / aborted / max-tokens / error) |
The transcript is deliberately tolerant: unknown notification methods, item
kinds, and agent-message phases are ignored, so an app-server version that
introduces new item types cannot fail the run. Malformed payloads of known
kinds degrade to a skipped write. The base provider's fail-closed posture is
kept where it matters: unknown server requests (which demand an answer) and
mismatched thread/turn scoping in terminal notifications still fail the run.
Configuration
| Key | Default | Meaning |
|---|---|---|
env |
{} |
Explicit child environment layered over the subprocess seam's credential-scrubbed parent environment. |
disposeGraceMs |
3000 |
Positive finite grace in milliseconds, no greater than MAX_TIMER_DELAY_MS, between the shared process-tree owner's termination tiers. |
ephemeral |
true |
Thread lifetime passed to thread/start. false persists the Codex session under CODEX_HOME/sessions for a later codex resume; true keeps the base provider's ephemeral contract. |
- id: better-codex-subagent
name: 'dsh-better-codex-subagent'
config:
env:
OPENAI_API_KEY: !!js process.env.OPENAI_API_KEY
ephemeral: false
- id: tool-subagent-codex
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: codex
toolName: subagent_codex
maxDepth: provider-managed
Background execution
One-shot background execution works for the codex provider: the tool row
just needs enableRunInBackground unset or true (the default). The model
can then pass run_in_background: true, which starts the Codex run as a
background job that returns a job id immediately; job_output collects the
final answer and job_kill cancels. The projection session is the job's
child session, so the Web UI still renders the running and settled subagent
transcript. backgroundMode must stay one-shot (the default): the codex
provider has no prepareContinuable capability, and a continuable tool row
fails at mount.
Installation
The package is a dsh bundle: its manifest declaresdsh.bundle with a patch layer (cordis.patch.yml) that mounts the provider,
so dsh plugin installs it as a bundle into a profile. The package ships
prebuilt (lib/types/*.js ESM + declarations) plus the source and declares
its harness packages as peer dependencies, so it loads wherever the harness
packages are already present — a dsh profile, for example, resolves them from
the installed dsh runtime.
# From this package directory: build and produce the publishable tarball.
pnpm pack # → dsh-better-codex-subagent-0.1.0.tgz
Install into a profile (dsh plugin forwards to pnpm and appends the bundle
to the profile's dsh.profile.bundles because of the dsh.bundle manifest):
dsh plugin --profile web add ./dsh-better-codex-subagent-0.1.0.tgz
Other distribution forms work the same way: dsh plugin --profile web add dsh-better-codex-subagent after publishing to npm, ordsh plugin --profile web add github:you/deepseek-harness#<sha> from git — a
git install fetches sources only, so the package then needs a prepare
script (none is shipped yet) and an allowBuilds entry in the profile'spnpm-workspace.yaml.
If the profile already mounts the base@deepseek-ai/dsh-subagent-codex provider (for example a manually inserted- id: subagent-codex row in the profile's cordis.patch.yml), remove that
row and its dependency before restarting — both packages register the codex
provider name and the duplicate fails loud:
dsh plugin --profile web remove @deepseek-ai/dsh-subagent-codex
# and delete the `- id: subagent-codex` insert row from
# ~/.dsh/profiles/web/cordis.patch.yml
The tool-subagent-codex tool row (provider: codex) in the standard-codex
agent preset needs no change. Then restart dsh web.
Product compatibility and evidence
The wire implements the same 0.147.0 app-server surface as the base provider
(adapted from its wire.ts), with the ephemeral lifetime parameterized and a
validated notification sink added. Development evidence is pinned to@openai/codex@0.147.0; the npm package is a test-only dependency, and
deployments still supply codex on PATH. The keyless real-product test
boots the real app-server against a loopback Responses fixture and asserts
that the published run is discoverable through ctx.subagents.listChildren
and that its transcript carries the delegated task, the answer, and the
closing turn/end.
Known Limitations and Deferred Work
- Message granularity is per completed item, not per delta — the
item/agentMessage/deltastream is accumulated but written as oneassistant/messageonitem/completed; the Web UI does not stream the
answer live. Streamingassistant/chunkprojection is deferred. - Tool projection covers
commandExecutionandfileChangeitems only —mcpToolCall,webSearch,collabToolCall,plan, andreasoningitems
are ignored; the transcript is the extension point for them. - No continuation — the child is a terminal one-shot projection session;
follow-up messages, cold resume, andcodex resumethrough the harness are
out of scope (persisting the thread withephemeral: falsemakes the Codex
session resumable in the Codex CLI itself). - Host-managed product installation and account state — a missing or
incompatiblecodex, configuration error, or authentication failure is
surfaced as a startup or run error; the plugin provides no installer, login
flow, or runtime version gate. - No wall-clock timeout or side-effect rollback — the caller cancels long
work, and files or external systems changed before cancellation are not
restored.
Install
Install the catalog once, then DeepSeek Harness can find and install any plugin from this site automatically:
dsh plugin add dshbase-catalog Then say "install dsh-better-codex-subagent for me" — your agent finds it in the directory and installs it. Docs: dshbase-catalog · verified packs.
This plugin is GitHub source (not published to npm) — install it straight from the repo:
Web profile:
dsh plugin --profile web add github:ivwumupy/dsh-better-codex-subagent Headless (CLI) profile:
dsh plugin --profile headless add github:ivwumupy/dsh-better-codex-subagent Test report
Verified: L1 install + L2 load + L3 runtime from GitHub source on dsh 0.1.0-rc.6.