Sub-agent Surface (v1 / base / v2)
opencodex lets you choose the multi-agent collaboration surface for every model in the catalog. The Sub-agent toggle in the dashboard and Models page controls this globally.
| Mode | Surface | Behavior |
|---|---|---|
| v1 | multi_agent_v1 |
Classic namespaced agent tools with send_input / close_agent / resume_agent. A spawn_agent model override can start a sub-agent on a different model. |
| base (default) | Upstream pins | Restores upstream model pins: gpt-5.6-sol and gpt-5.6-terra use v2, gpt-5.6-luna uses v1, and unpinned models follow the Codex multi_agent_v2 feature flag. Spawn behavior follows the surface that resolves for that model. |
| v2 | multi_agent_v2 |
Flat spawn_agent tools with concurrent sessions and send_message / followup_task / wait_agent / interrupt_agent. Children inherit the parent model on full-history forks; fork_turns: "none" (or a partial fork) accepts model / reasoning_effort overrides. |
How it works
Section titled “How it works”The mode sets the multi_agent_version field on every catalog entry that Codex reads:
- v1 mode: forces
multi_agent_version = "v1"on all entries, overriding upstream pins. - base mode: restores upstream defaults. Pinned models get their snapshot value; unpinned models omit the field so the Codex feature flag decides.
- v2 mode: forces
multi_agent_version = "v2"on all entries, overriding upstream pins.
The override is the final pass in both the live /v1/models catalog response and the on-disk catalog sync. Mode changes therefore apply consistently to newly created sessions, regardless of how an entry was built.
Delegation model and effort
Section titled “Delegation model and effort”The dashboard’s Sub-agent delegation picker stores an injectionModel and, optionally, an injectionEffort. These are delegation guidance settings, not a proxy-side spawn router. An optional injectionPrompt replaces the built-in guidance text entirely.
multiAgentGuidanceText identifies the surface from the request’s tools — including the Codex Desktop WebSocket path (responses_lite), where tools arrive inside an additional_tools input item instead of the request’s tools array.
On a v2 turn (Sol/Terra in base mode, every model in v2 mode), the proxy injects a compact guidance block — budgeted to 700 characters — whenever an injection model is set or the configured sub-agent roster resolves in the catalog. The block teaches spawn_agent’s hidden model / reasoning_effort arguments, mandates fork_turns: "none" (or a partial fork) for overrides, names the preferred model and effort, and lists the subagentModels roster with the effort ladder each advertises in the injected catalog — the same list Codex validates spawn efforts against.
On a v1 turn the proxy only mirrors upstream’s Proactive delegation text at the top effort tier (max / ultra). No model designation, roster, or custom prompt is added there — v1 stays lean by design.
To replace the built-in v2 guidance, set injectionPrompt (config key, or PUT /api/injection-model with a prompt value). The placeholders {{model}}, {{effort}}, and {{roster}} are substituted with the configured injection model, effort, and the resolved roster line. Firing gates are unchanged: a custom prompt never makes a turn fire that would otherwise stay silent.
Changing the mode
Section titled “Changing the mode”- Dashboard → first stat cell: click v1, base, or v2.
- Models page → top-row segmented control.
- Both pages have a ? button that opens a help modal with a link back here.
- Dashboard → Sub-agent delegation: choose a preferred model and optional reasoning effort. On v2 the injected guidance instructs the agent to spawn with
fork_turns: "none"so the choice actually takes effect.
ocx v2 mode v1 # force all models to v1ocx v2 mode default # restore upstream pinsocx v2 mode v2 # force all models to v2ocx v2 status # show current mode + Codex feature flag# Read the surface mode, feature flag, and thread limitcurl http://localhost:10100/api/v2
# Set the surface modecurl -X PUT http://localhost:10100/api/v2 \ -H 'Content-Type: application/json' \ -d '{"multiAgentMode": "v2"}'The /api/v2 PUT endpoint also accepts enabled (boolean, the Codex feature flag) and maxConcurrentThreadsPerSession (integer). It validates the request, saves the mode, resyncs the catalog, and reports that mode changes apply to new sessions.
The delegation picker uses a separate endpoint:
# Read the current model/effort and the available picker valuescurl http://localhost:10100/api/injection-model
# Set both valuescurl -X PUT http://localhost:10100/api/injection-model \ -H 'Content-Type: application/json' \ -d '{"model": "anthropic/claude-sonnet-5", "effort": "xhigh"}'
# Set a custom guidance prompt ({{model}}/{{effort}}/{{roster}} placeholders)curl -X PUT http://localhost:10100/api/injection-model \ -H 'Content-Type: application/json' \ -d '{"model": "anthropic/claude-sonnet-5", "prompt": "Delegate to {{model}}.{{roster}}"}'
# Clear both valuescurl -X PUT http://localhost:10100/api/injection-model \ -H 'Content-Type: application/json' \ -d '{"model": null}'GET /api/injection-model returns model, effort, prompt, the global efforts ladder, and enabled native/routed available models. For PUT, omitting effort or prompt keeps the current value, null clears it, and clearing model always clears the effort too. The API validates effort against the global Codex ladder; Codex still validates a spawn effort against the target catalog entry.
Reasoning effort
Section titled “Reasoning effort”The optional sub-agent effort setting is stored as injectionEffort and is meaningful only with an injection model. It adds a reasoning_effort instruction to the injected v2 guidance; it does not change the parent session’s effort. On any fork that accepts overrides, Codex applies a reasoning_effort passed to spawn_agent directly.
ultra ranks above max in the Codex catalog and adds automatic-delegation semantics, but it never reaches a provider as a literal wire value. Codex converts ultra to max at the client boundary. opencodex then keeps the provider request valid:
| Model | max on wire |
ultra selection on wire |
|---|---|---|
| gpt-5.5, gpt-5.4, gpt-5.4-mini | xhigh | xhigh (via max, then nativeEffortClamp) |
| gpt-5.6-sol, gpt-5.6-terra | max | max |
| gpt-5.6-luna | max | Not advertised by its exact upstream ladder |
| Routed models | Mapped or clamped by the adapter | Converted to max, then mapped or clamped by the adapter |
Catalog availability is independent of the v1/v2 mode. Reasoning-capable generated entries advertise max so direct sub-agent effort overrides validate; current generated routed entries also advertise ultra. Exact upstream model ladders are preserved, which is why gpt-5.6-luna stops at max.
Context cap
Section titled “Context cap”The global context cap value defaults to 350k and limits the advertised context_window only for routed providers whose cap is enabled. Native OpenAI models keep their real context windows.
Change the value or the all-provider setting in the Models page, or toggle the cap next to an individual provider group header.

