| title | Sub-agent Surface (V1 / base / V2) |
|---|---|
| description | Control how Codex spawns and manages sub-agents across all models. |
A sub-agent is a separate Codex worker that the main agent can create for a focused task. It has its own context and tools, so several independent tasks can run in parallel. CodexCommander controls which Codex collaboration surface exposes those workers, which models Codex offers for them, and how a failed model can fall back. It does not decide when your main agent must delegate.
Choose the mode for new sessions. Existing sessions keep the surface they started with.
| Mode | What Codex gets | Who should pick it |
|---|---|---|
| V1 | Classic namespaced spawn_agent, send_input, resume_agent, and close_agent tools. A spawn can select another model directly. |
Beginners who need reliable delegation across different providers, especially native-to-routed children. |
| base (default; Codex native in the GUI) | Native entries preserve the installed source's collaboration field, including its absence. Routed compatibility entries may follow Codex's multi_agent_v2 feature flag. |
Most users. It follows Codex's intended surface for each model without forcing one globally. |
| V2 | Flat spawn_agent, send_message, followup_task, interrupt_agent, and agent-list tools, with concurrent sessions. |
Users who want the newer concurrent workflow. Mixed-provider parents must also choose the plaintext compatibility delivery policy described below. |
:::tip[Not sure?] Start with base. Choose V1 for the established cross-provider path. Force V2 only when you specifically want its newer session model; enable plaintext compatibility when that V2 parent must delegate to Kimi, Grok, DeepSeek, or another external provider. :::
The selected mode controls the multi_agent_version field in every catalog entry Codex reads:
- V1 stamps
multi_agent_version = "v1"on every model. - base restores authoritative native values, including an absent collaboration field. Routed compatibility entries may follow the native
multi_agent_v2feature flag. - V2 stamps
multi_agent_version = "v2"on every model.
CodexCommander applies this as the final pass to both the live /v1/models catalog and the catalog synced
to disk. That is why a mode change affects newly created App, CLI, and TUI sessions consistently.
Changing to V2 makes Luna eligible for the V2 collaboration surface because the generated
catalog stamps it as V2. It does not, by itself, make Luna (or any other model) available to a
currently running Codex worker. The five featured roster rows are suggestions shown first to
spawn_agent, not an exhaustive allowlist. A parent that already knows a compatible exact catalog
ID may pass it to native spawn_agent. For that spawn to succeed, all of these must hold:
- The exact ID is present in the worker-loaded catalog and is compatible with this collaboration surface and V2 task-delivery policy.
- The deterministic CodexCommander catalog containing it has been written to disk.
- The current Codex app-server has loaded that catalog (not an older in-memory copy).
- Its proxy route is enabled and can actually serve the request.
This separation is deliberate: protocol selection controls catalog semantics; catalog activation controls what an already-running Codex worker has loaded. In particular, opening a new task or forking a task does not reload an existing app-server's model catalog.
For a V2 roster, eligibility has three states: an entry stamped "v2", explicitly set to null, or
with no multi_agent_version field is eligible. A genuine "v1" pin is excluded because it states
that the model belongs to the other collaboration surface.
The dashboard can install an optional codexcommander-delegation user skill plus a bounded global
policy block. These artifacts supply a durable Balanced or Orchestrator mode hook for new
Codex tasks:
$HOME/.agents/skills/codexcommander-delegation/SKILL.md
$CODEX_HOME/AGENTS.md
The skill is advisory and deliberately contains no roster or model ids. Before a spawn it reads the
current collaboration tool contract and live injected guidance. Featured models are suggestions, not
an exhaustive allowlist; a known exact compatible catalog ID may be passed to native spawn_agent as
model when the live contract permits. Omitting model inherits the configured default or parent
choice. Add reasoning_effort only when the target advertises supported values and the brief
benefits from it. Match each spawn to task complexity, uncertainty, risk, and how tightly you can
check the result. Prefer the configured preferred worker when it fits; escalate capability only when
the brief needs it. Do not default to the cheapest model or spawn solely to delegate. Reassess model
choice on failed evidence, scope expansion, uncertainty, or capability mismatch—not on wait_agent
timeout alone.
A roster can change independently without making the installed skill stale.
For V2 coordination, a wait_agent timeout means only that no qualifying mailbox or final event
arrived during that wait. It does not mean a running child failed or stopped. The managed skill tells
the coordinator to reconcile once, continue useful local work or wait another 5–10 minutes, and never
interrupt solely because waits timed out—even when a checkpoint or conclude request is followed by
silence. Interruption instead needs explicit cancellation, a confirmed error or blocked state, a hard
deadline communicated to the child in advance, or deliberate replacement after preserving available
work. For a bounded high-stakes gate, the coordinator can request a checkpoint or durable partial
artifact prospectively; a conclude request is advisory and is delivered only at a model or tool
boundary.
The bounded AGENTS.md block is the durable mode hook. Codex loads it once for a run, so installing,
updating, changing mode, or removing it does not rewrite the instructions of a current task. Start a
new Codex task after any of those actions. User instructions and repository-scoped instructions
remain higher priority and can limit or forbid delegation even in Orchestrator mode. A nonempty
$CODEX_HOME/AGENTS.override.md shadows the global managed block; an empty override does not.
Remove setup deletes only the managed SKILL.md, removes its directory only when it is empty,
and removes only the AGENTS.md bytes bounded by the exact CodexCommander marker pair. Foreign skill
content, ambiguous markers, linked paths, and unexpected sibling files are never force-removed.
This advisory setup is separate from the collaboration surface and settings below. It does not call
/api/v2, change subagentDeveloperInstructions, mutate native [agents] defaults or Codex config,
inject a roster, rebuild or activate the catalog, restart a worker, or replace the proxy. Use the
corresponding Run Policy and catalog controls for those operations.
CodexCommander renders the canonical managed skill and bounded policy block into dashboard previews,
then publishes those exact artifacts through the atomic installer and packaging flow. Update through
the dashboard or project source; do not edit ~/.agents or packaged dist output manually.
The dashboard's Sub-agent delegation controls three related settings:
injectionModelis the preferred worker model named in CodexCommander guidance.injectionEffortis the optionalreasoning_effortto request for that model.injectionPromptreplaces the built-in V2 guidance text.
multiAgentGuidanceEnabled defaults to on and is the master switch for CodexCommander-authored guidance
on both surfaces. Turning it off suppresses both the V2 designation block and V1 proactive text.
These are instructions to the main agent, not a proxy-side spawn router. On V2, a full-history fork
inherits the parent model and rejects model or effort overrides. Guidance therefore tells Codex to
use fork_turns: "none" (or a positive partial turn count such as "3") when passing model or
reasoning_effort, and to make the task message self-contained.
For full-input conversations on native OpenAI Responses routes, CodexCommander places its delegation guidance in the initial instruction block, before conversation history. The same guidance stays at the same position as new tool results arrive, so the growing history remains available for prompt-cache reuse. The roster and provider selections are unchanged. Other provider routes retain their existing guidance placement. Cache reuse is still determined by the upstream service; a cold cache or a changed model, instruction set, or roster can increase uncached input.
When Commander restores a native previous_response_id from its local conversation state, it
checks for existing guidance after restoring that history. Matching guidance is reused, avoiding
another copy on each tool result. Existing stored guidance keeps its original position.
The featured roster is persisted as ordered objects with model and optional guidance fields.
Configuration reads also accept the older string[] form, but the canonical in-memory and newly
written form is objects. The first object write is a migration boundary: an older binary that only
understands string arrays fails when it reads that configuration. There are at most five entries.
Guidance is optional, sanitized operator text. Empty text is omitted; nonempty text is limited to 160
Unicode code points. Treat it as untrusted advisory context, not as an effort, quota, role, or
fallback control. On eligible V2 turns CodexCommander first applies live picker, surface, route, and
encrypted-task compatibility filters, then adds every surviving row annotation to the built-in
developer message without an aggregate character budget. Row guidance is not injected on V1 and is
never copied into the managed skill or global AGENTS.md policy.
Custom injectionPrompt text can use all four placeholders:
| Placeholder | Replaced with |
|---|---|
{{model}} |
The effective preferred model for this request. A bare native injectionModel is account-qualified only when the request itself targets an explicit account selector. An unresolved or ambiguous bare value becomes an empty string; an unresolved explicit account-qualified or routed id remains unchanged |
{{effort}} |
The configured injectionEffort, or an empty string |
{{roster}} |
The resolved picker-visible, surface-compatible roster |
{{fallback}} |
The configured global fallback guidance |
Built-in V2 guidance includes every accepted roster annotation that survives the compatibility
filters. Built-in guidance fires only when a preferred model, eligible roster, or fallback chain
resolves. A configured injectionModel is sufficient to render a custom prompt; if a bare value
cannot resolve uniquely, {{model}} expands to an empty string.
On V1, CodexCommander injects only the upstream-style proactive delegation guidance at max or ultra
effort. It does not add a preferred model, roster, fallback list, or custom prompt on V1.
The default-off syncCodexSubagentDefaults option is separate from guidance. When CodexCommander owns
active Codex routing, sync or restart can write only injectionModel and injectionEffort as
marker-owned [agents] default_subagent_model and default_subagent_reasoning_effort entries in
Codex TOML.
CodexCommander updates or removes only fields bearing its markers. If either target field is user-owned,
the pair is left unchanged rather than partially written; ambiguous TOML is rejected without a
write. External provider managers and user-owned root routing also remain authoritative.
For a spawned worker, CodexCommander builds this priority order:
- The requested primary model.
- The role's
model_fallbacklist from its$CODEX_HOME/agents/*.tomldefinition. - The global
subagentModelFallbacklist in CodexCommander config.
Duplicate model ids are removed while preserving the first occurrence. During selection, CodexCommander
skips candidates that are disabled, unroutable, backed by a disabled provider, marked unhealthy,
inside a cooldown, missing a usable pooled Codex account, or beyond the configured quota threshold.
Availability probes are cached for subagentModelFallbackPollMs (60 seconds by default).
Fallback does not make incompatible encrypted tasks readable. Under the default encrypted policy, selection is restricted to canonical native ChatGPT targets even if an external model appears earlier in the chain. A successfully negotiated plaintext-compatibility V2 session can use the normal heterogeneous fallback chain.
Codex may send a V2 native-to-routed child task only as backend-encrypted encrypted_content. That
payload can be read by the native ChatGPT backend, but not by an external provider. This is the
known #92 limitation.
CodexCommander fails safely instead of forwarding an empty or unreadable task:
- A direct non-native route returns HTTP 400 with
error.code = "unreadable_encrypted_agent_task"and does not echo the ciphertext. - A combo considers only canonical native ChatGPT targets for that task, including retries. If none is available, it returns the same 400 error.
- A readable plaintext task keeps the normal route and fallback behavior.
multiAgentV2MessageDelivery controls the V2 parent wire policy:
| Policy | Behavior |
|---|---|
"encrypted" (default) |
Preserves ChatGPT's reserved encrypted collaboration schema and the fail-closed behavior above. Use native ChatGPT workers or V1 for external workers. |
"plaintext" |
Experimental mixed-provider V2 compatibility. It changes only V2 task-message delivery so a routed provider can read the delegated task; it is not a general key or credential setting. For ChatGPT parents, CodexCommander presents a non-reserved plaintext collaboration namespace and restores the canonical namespace on the client-facing response. For routed parents, it marks only completed V2 message calls as plaintext. Both paths activate Codex's plaintext V2 handler, while its graph, mailbox, wait, follow-up, and completion lifecycle remain native. |
The plaintext decision is made when the parent tool schema is created, before the worker model is
known. Consequently every V2 spawn_agent, send_message, and followup_task message from that
parent is plaintext, including messages to native ChatGPT workers. CodexCommander suppresses those
arguments from usage-debug body samples, but the trusted local Codex runtime and proxy necessarily
handle the plaintext to deliver it.
Routed children can have send_message or followup_task without a spawn_agent tool. Their
completed collaboration message calls also carry the plaintext marker. When an older task replays
a delegated message that Codex stored as plain text in an encrypted-content slot, native plaintext
delivery repairs that message before forwarding it, so the task can continue.
For a canonical ChatGPT parent, plaintext compatibility activates only with the complete recognized
V2 schema. For a routed parent, CodexCommander marks only the exact collaboration message calls listed
above; lifecycle and unrelated tools remain untouched. A partial, changed, malformed, or colliding
native schema is not guessed: CodexCommander leaves it untouched and retains the encrypted fail-closed
guard. Delivery changes affect subsequent requests, so start a new session after saving instead of
switching an active conversation in place.
- Dashboard → first stat cell: choose V1, base, or V2.
- Models → Current behavior → Collaboration: choose Reliable V1, Codex native (base/default semantics), or Concurrent V2.
- Subagents → Agent Command Center:
- Configured Roster chooses and orders the five model overrides advertised first to
spawn_agent. Drag rows, use the arrow buttons, or press Alt + ↑/↓. The card shows your configured quick picks: a row's status line (for example V1 under Codex defaults or Routed · V2 compatible) indicates which collaboration surfaces can select it, while rows without a status line are available on both. - Agent Library searches the current model catalog and filters factual capabilities such as reasoning, long context, vision, and tool support. Entries remain addressable by exact id when their route is available, including models outside the five-slot roster.
- Run Policy stages the agent protocol, V2 message-delivery policy, preferred guidance model and effort, ordered global child fallback chain, health recheck interval, thread limit, sub-agent effort ceiling, roster guidance, and native Codex-default sync. Save policy changes separately from roster changes.
- Configured Roster chooses and orders the five model overrides advertised first to
Leaving Thread limit blank restores the Codex default. V2 counts total threads including the root; V1 counts child threads. A protocol or thread-limit change updates managed boot configuration: use the catalog status to choose the reload path. When the catalog and managed routing are current but the worker is stale, quit ChatGPT completely, reopen it, and start a new task for the session-bound tool shape. If the catalog is pending/unknown or routing is not injected, use Apply to Codex to reconcile them first; restarting ChatGPT alone is not that repair. Guidance and fallback apply to future spawned child turns. A V2 delivery-only change needs a new task but does not dirty the catalog or require Apply.
Use ccx v2 for the collaboration surface and native feature settings:
ccx v2 status
ccx v2 mode v1
ccx v2 mode default
ccx v2 mode v2
ccx v2 threads 8Use ccx agent for delegation, roster, effort-cap, and fallback settings:
ccx agent status
ccx agent injection set --model anthropic/claude-sonnet-5 --effort xhigh
ccx agent subagents set gpt-5.6-sol,anthropic/claude-sonnet-5
ccx agent fallback set gpt-5.4-mini,xai/grok-4.5 --poll-ms 60000
ccx agent effort set --subagent maxPass - to clear a nullable ccx agent injection value, or use the relevant clear action for a
roster or fallback list. See the CLI reference for all command families.
The management API exposes matching GET, PUT, and guidance-only PATCH endpoints:
| Endpoint | Manages |
|---|---|
/api/v2 |
Surface mode, V2 message delivery, native feature flag, and thread settings |
/api/injection-model |
Preferred model, effort, custom prompt, guidance, and native-default sync |
/api/effort-caps |
Main-agent and sub-agent effort ceilings |
/api/subagent-models |
Ordered roster of up to five { model, guidance? } objects; GET also keeps chosen: string[], while legacy { models } writes preserve matching guidance. PATCH changes one existing row's guidance atomically. Saving is non-disruptive and reports catalog activation state |
/api/subagent-model-fallback |
Global fallback order and poll interval |
/api/codex-catalog/status |
Read desired configuration, deterministic on-disk catalog evidence, current-worker activation evidence, and native model discovery status |
/api/codex-catalog/apply |
Guarded reconciliation for a pending catalog or uninjected managed route, followed when necessary by a confirmed force-restart of verified stale workers. For an already-converged stale worker this is an advanced fallback that may make ChatGPT show stopped unexpectedly; browser use requires a confirmed ccx gui or menu-app launch |
Sending multiAgentV2MessageDelivery: "encrypted" or null to PUT /api/v2 removes the explicit
override and restores the encrypted default.
For example:
curl -X PUT http://localhost:10100/api/v2 \
-H 'Content-Type: application/json' \
-d '{"multiAgentMode":"v2","multiAgentV2MessageDelivery":"plaintext"}'
curl -X PUT http://localhost:10100/api/injection-model \
-H 'Content-Type: application/json' \
-d '{"model":"anthropic/claude-sonnet-5","effort":"xhigh"}'No. Guidance can recommend a model, and native-default sync can provide a Codex default, but the main agent still decides whether to delegate.
A full-history V2 fork inherits the parent model. Use a spawn that sets fork_turns to "none" or
a positive partial count before passing a model or effort override.
The featured V2 roster only lists picker-visible, surface-compatible, in-window rows. A model can
still be spawnable by exact ID when it is in the worker-loaded catalog and compatible with this
surface, even if it is outside the five featured suggestions. It is missing from that featured list
when it is picker-hidden, outside the five-model display limit, missing from the catalog, or pinned
to V1. A "v2", null, or absent surface value is eligible; a real "v1" pin is not.
No. Forced V2 removes Luna's upstream V1 surface pin, so it can be eligible for the V2 roster. It still needs to be written into the catalog, loaded by the current Codex worker, and routable through the proxy. Being outside the five featured suggestions does not by itself block an exact-ID spawn. Use the dashboard's catalog status to see which condition is pending. If the catalog and routing are current and only the worker is stale, quit ChatGPT completely, reopen it, and start a new task. If the catalog is pending or routing is not injected, use Apply to Codex for reconciliation first.
No. Start a new Codex session after changing the mode. That controls the collaboration protocol but
does not reload an already-running App host's model catalog. Save writes desired configuration and
converges the on-disk catalog without interrupting work. When the catalog and managed routing are
current but the worker is stale, quit ChatGPT completely, reopen it, and then start the new task. The
guarded Force-restart workers action and ccx sync --restart-codex remain advanced fallbacks and may
make ChatGPT show stopped unexpectedly. A pending catalog or uninjected managed route still needs
Apply to Codex reconciliation first. There is intentionally no auto-apply, idle queue, or persisted
“pending” snapshot to manage.
Yes, with V2 message delivery → Plaintext compatibility and a fresh session. The policy keeps the V2 lifecycle but makes that parent's delegated messages plaintext. Leave delivery encrypted for the native-only confidentiality contract, or use Reliable V1 for the established cross-provider surface.
injectionEffort affects only delegated-worker guidance and, when explicitly enabled, native Codex
sub-agent defaults. It does not change the parent session's effort. ultra is a client-facing top
tier that Codex converts to max; CodexCommander then maps or clamps the value for the selected provider.
The model context cap is independent of sub-agent mode. Configure it under Models → Current behavior → Context. Uncapped means no routed provider has an artificial cap; Limited means all routed providers use the shared value; Mixed limits reports per-provider differences. Native OpenAI models retain their real context windows.