Skip to content
Draft
43 changes: 30 additions & 13 deletions docs-site/src/content/docs/guides/codex-app-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,28 @@ opencodex does not patch Codex App. It writes the same Codex configuration and m
Codex CLI/TUI already use. Because Codex App reads that shared state, routed models can appear in the
App's model picker as normal Codex catalog entries.

OpenAI entries have two stable identities: one bare native `openai` group whose Pool(default) or
Direct account selection is controlled by `codexAccountMode`, and namespaced
`openai-apikey/<model>` API-key transport. Changing the account mode does not change picker ids.
OpenAI entries use two credential routes: native Codex login and the namespaced
`openai-apikey/<model>` API-key transport. Changing `codexAccountMode` between Pool and Direct by
itself does not change picker ids. When `codexAccountNamespaces` has eligible selectors whose
mapped accounts still exist, however,
opencodex adds separate `<selector>/<native-openai-model>` rows for the mapped accounts and hides

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update model-routing docs for selector precedence

With account-qualified picker ids now documented here, the separate Model Routing guide still describes provider/model as the first routing rule and never mentions <selector>/<native-openai-model> (checked docs-site/src/content/docs/guides/model-routing.md lines 14-48). In configs with a selector, router.ts resolves that selector before provider namespaces and sends the bare native id to the mapped account, so users following the routing guide can reason about the wrong precedence; update that guide and its translations alongside this picker change.

AGENTS.md reference: docs-site/AGENTS.md:L7-L10

Useful? React with 👍 / 👎.

the bare native rows from the Codex picker. Selector labels are user-chosen public names with no
built-in account-role meaning. Selecting a qualified row uses only its mapped account, does not
change the active Pool account, and fails closed instead of switching accounts when the target is
unavailable. See [Exact Codex account selectors](/reference/configuration/routing/#exact-codex-account-selectors).
API GPT-5.6 entries use
1,050,000 context / 922,000 max input, and `*-pro` picker ids resolve to the base wire model with
`reasoning.mode: "pro"` while logs, usage, and picker state keep the virtual id.
The API catalog is fixed to exactly eight ids: `gpt-5.5`, `gpt-5.6`, Sol/Terra/Luna, and their
three Pro virtual ids; there is no generic `gpt-5.6-pro` alias.
Compact requests keep the selected tier but send the base model without a reasoning object.

Select a credential route explicitly; change Pool/Direct on the Providers page:
Select the credential route represented by the picker id. Change Pool/Direct on the Providers page;
`<selector>` below is a user-chosen public label mapped through `codexAccountNamespaces`:

```text
gpt-5.6-sol # openai (Pool or Direct option)
gpt-5.6-sol # bare Codex-login route via Pool or Direct
<selector>/gpt-5.6-sol # stored Codex account mapped by that selector
openai-apikey/gpt-5.6-sol # API key
```

Expand Down Expand Up @@ -64,7 +72,8 @@ metadata instead of an older-template approximation.

| Route | Picker ids and catalog metadata |
| --- | --- |
| Codex login (Pool or Direct) | `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` (372,000-token catalog window) |
| Codex login (no eligible account selectors) | Bare native ids such as `gpt-5.6-sol`, `gpt-5.6-terra`, and `gpt-5.6-luna`; Pool or Direct is selected through `codexAccountMode`. GPT-5.6 rows use a 372,000-token catalog window. |
| Codex login (eligible account selectors) | One `<selector>/<native-openai-model>` row per eligible selector and supported native model; each row uses only its mapped account, and bare native rows are hidden from the picker. Native metadata and context windows are preserved. |
| OpenAI (API key) | Exactly eight namespaced rows: `gpt-5.5`, `gpt-5.6`, Sol/Terra/Luna, and the three `*-pro` virtual ids (1,050,000 context; 922,000 max input for all eight) |
| OpenRouter | `openrouter/openai/gpt-5.6-sol`, `openrouter/openai/gpt-5.6-terra`, `openrouter/openai/gpt-5.6-luna` (1,050,000) |
| Cursor | Static fallback includes `cursor/gpt-5.6-sol`, `cursor/gpt-5.6-terra`, and `cursor/gpt-5.6-luna` (1,000,000), plus `cursor/grok-4.5` and `cursor/grok-4.5-fast` (500,000); live account discovery decides which remain visible. |
Expand All @@ -78,13 +87,18 @@ must still be entitled to use that model.

## Native and routed model toggles

The dashboard Models page uses `disabledModels` for both model families:
The dashboard Models page exposes `disabledModels` toggles for bare native ids and routed
`provider/model` ids. Account-qualified `<selector>/<native-openai-model>` ids are also supported by
`disabledModels`, but the dashboard does not list or toggle those exact selector rows; add them to
the configuration manually:

- Routed ids are namespaced (`provider/model`). Disabling one excludes it from the synced catalog
and `/v1/models`.
- Native GPT ids are bare slugs. Disabling one keeps its catalog entry but changes
`visibility` to `hide`, preserving the exact entry for a later re-enable; the bare OpenAI list
shape omits it while disabled.
- Account-qualified native ids use `<selector>/<native-openai-model>`. Adding one to
`disabledModels` hides only that selector row.
- Native GPT ids are bare slugs. Disabling one keeps its catalog entry but changes `visibility` to
`hide`, preserving the exact entry for a later re-enable; it hides the bare row and every
selector-qualified clone for that model from discovery.
- Native rows come from the supported static set, so a disabled native model stays visible in the
dashboard and can be turned back on.

Expand Down Expand Up @@ -129,9 +143,12 @@ never advertised where it cannot be honored, and custom gateways can opt in expl
## Subagent selection

Codex sorts picker-visible catalog entries by ascending `priority` and advertises the first five as
`spawn_agent` model overrides. Pick up to five bare native ids or namespaced `provider/model` ids
through `subagentModels` or the dashboard Subagents page; opencodex gives those entries priorities
0-4 in the chosen order. Other models remain callable by exact id.
`spawn_agent` model overrides. The dashboard Subagents page can select and save up to five bare
native ids or routed `provider/model` ids. Manually configured `subagentModels` also accepts
account-qualified `<selector>/<native-openai-model>` ids, but the dashboard does not offer those
exact ids; saving the page replaces the list with dashboard-visible choices. opencodex assigns low
catalog priorities in the selected order; when account selectors are active, bare native selections
expand into selector-qualified groups. Other models remain callable by exact id.

The featured-model list is separate from the Dashboard's **Sub-agent delegation** selection. It
controls which overrides Codex offers first; it does not select a model or trigger delegation by
Expand Down
31 changes: 21 additions & 10 deletions docs-site/src/content/docs/guides/model-ordering.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,15 @@ it earlier in the picker. The implementation records this constraint directly in
`src/codex/catalog/sync.ts`.

opencodex therefore controls featured placement by assigning lower priorities, not by relying on
array position. The relevant priorities are:
array position. Unless noted otherwise, the fixed priorities and worked example below describe a
catalog with no eligible Codex account selectors. With `N` eligible selectors, featured priorities
use `N` as a stride: a bare native choice at configured rank `i` expands to selector rows at
priorities `i * N + j`, where `j` is the selector's zero-based position; a routed choice uses
`i * N`; and an exact selector-qualified choice uses `i * N + j` for its selector. Unselected routed
rows are moved outside those selector groups. Codex still advertises only the first five
picker-visible rows.

The relevant no-selector priorities are:

| Catalog entry | Priority | Source |
| --- | ---: | --- |
Expand Down Expand Up @@ -57,7 +65,7 @@ only change whether a model is included.

## Effective picker pattern

With a non-empty featured list, the resulting order is:
With no eligible account selectors and a non-empty featured list, the resulting order is:

1. Models in the exact configured `subagentModels` order, with priorities `0` through `4`.
2. All remaining routed models, ordered alphabetically by provider and then model id, at priority `5`.
Expand Down Expand Up @@ -95,16 +103,19 @@ The picker begins as follows:
| After routed models | Remaining native models | `featured.length + 100` or higher | Unselected natives are moved below the featured block |

The first five entries are the overrides advertised to `spawn_agent`; the rest continue in the
normal picker order.
normal picker order. With account selectors, the five-entry limit applies after bare native choices
have expanded into selector-qualified groups.

## Changing the order

The only supported way to customize leading model order is to reorder `subagentModels`. You can do
that on the dashboard's **Sub-agents** page or in the opencodex configuration. The list accepts at
most five models, and its order is significant.
The supported way to customize leading model order is to reorder `subagentModels`. The dashboard's
**Sub-agents** page can reorder bare native and routed ids. Use `ocx agent subagents set` or edit the
opencodex configuration for exact `<selector>/<native-openai-model>` choices; the dashboard does not
list those choices and omits them if it saves the roster. Use at most five configured ids. With
account selectors, one bare native choice can expand into multiple selector-qualified catalog rows,
so configured choices and advertised rows are not necessarily one-to-one.

There is currently no general `modelOrder`, `providerOrder`, or priority-map setting in `OcxConfig`.
The supported ordering field is `subagentModels` (`src/types.ts:238-246`); `disabledModels` and each
provider's `selectedModels` are visibility fields (`src/types.ts:276-282` and
`src/types.ts:439-446`). To change the rest of the picker order would require a code-level behavior
change rather than a configuration edit.
The supported ordering field is `subagentModels`; `disabledModels` and each provider's
`selectedModels` are visibility fields. Changing the remaining picker order would require a
code-level behavior change rather than a configuration edit.
9 changes: 5 additions & 4 deletions docs-site/src/content/docs/guides/sub-agent-surface.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,16 @@ Custom `injectionPrompt` text can use all four placeholders:

| Placeholder | Replaced with |
| --- | --- |
| `{{model}}` | The configured `injectionModel`, or an empty string |
| `{{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 |

The built-in v2 guidance has a 700-character budget. If it would exceed the budget, opencodex drops
the roster first rather than truncating the core spawn instructions. Guidance fires only when a
preferred model, eligible roster, or fallback chain resolves. A custom prompt does not bypass that
gate.
the roster first rather than truncating the core spawn instructions. 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, opencodex 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.
Expand Down
Loading
Loading