Model Ordering
The Codex model picker does not preserve the order of provider declarations or model arrays in the opencodex configuration. Its final order comes from catalog priorities, with a deterministic alphabetical order for routed models that share the same priority.
The rule Codex applies
Section titled “The rule Codex applies”Codex’s models-manager sorts picker-visible catalog entries by priority in ascending order. It
discards the catalog array order, so moving an entry earlier in a generated JSON array does not move
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. 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.
Without complete-picker ordering, the relevant no-selector priorities are:
| Catalog entry | Priority | Source |
|---|---|---|
subagentModels[i] |
i (0 through 4) |
The featured rank map in src/codex/catalog/sync.ts |
| Other routed models | 5 |
Routed entry creation in src/codex/catalog/sync.ts |
Non-featured routed models listed in modelPickerOrder |
1000 + i |
Display-only picker rank in src/codex/catalog/sync.ts |
| Native GPT slugs by default | 9 |
Native entry creation in src/codex/catalog/sync.ts |
| Unselected native models while a featured list exists | At least featured.length + 100 |
Native catalog merge in src/codex/catalog/sync.ts |
The management API limits subagentModels to five entries with slice(0, 5) in
src/server/management/agent-settings-routes.ts. This matches the Codex spawn_agent surface, which
advertises only the first five model overrides. Models outside those five can still remain visible
in the main picker and callable by their exact id.
How ties are ordered
Section titled “How ties are ordered”All ordinary routed models have priority 5, so they need a tie-breaker. Before catalog entries are
built, gatherRoutedModels() sorts the routed model list by provider name and then by model id, both
alphabetically (src/codex/catalog/provider-fetch.ts).
This means neither of these configuration details changes the final order:
- the declaration order of keys in the
providersobject; - the order of ids in a provider’s
modelsarray.
orderForSubagents() then uses a stable sort to move configured featured picks to the front in the
same order as subagentModels. Non-featured models keep the provider/id alphabetical relative order
established earlier (src/codex/catalog/sync.ts). The featured rank is also converted to
priorities 0 through 4 when entries are built, so Codex’s priority sort preserves that leading
sequence.
Visibility is separate from ordering
Section titled “Visibility is separate from ordering”selectedModels and disabledModels decide which routed models are exposed; they are not ordering
controls. filterCatalogVisibleModels() converts both selections to Set lookups and filters the
gathered list without using the arrays as ranks (src/codex/catalog/provider-fetch.ts).
As a result, reordering selectedModels or disabledModels has no effect on picker position. It can
only change whether a model is included.
Effective picker pattern
Section titled “Effective picker pattern”With no eligible account selectors and a non-empty featured list, the resulting order is:
- Models in the exact configured
subagentModelsorder, with priorities0through4. - All remaining routed models, ordered alphabetically by provider and then model id, at priority
5. - Unselected native models, pushed below the featured block during catalog merge.
Without subagentModels, routed models remain at priority 5, native GPT entries use their normal
priority (normally 9 for entries built by opencodex), and the routed group remains provider/id
alphabetical.
Example
Section titled “Example”Suppose subagentModels contains these five ids in this exact order:
subagentModels = [ "gpt-5.5", "opencode-go/glm-5.2", "anthropic/claude-opus-4-6", "gpt-5.6-sol", "gpt-5.6-terra",]The picker begins as follows:
| Picker position | Model | Priority | Why it appears there |
|---|---|---|---|
| 1 | gpt-5.5 |
0 |
First subagentModels selection |
| 2 | opencode-go/glm-5.2 |
1 |
Second selection, even though its provider sorts after anthropic |
| 3 | anthropic/claude-opus-4-6 |
2 |
Third selection |
| 4 | gpt-5.6-sol |
3 |
Fourth selection |
| 5 | gpt-5.6-terra |
4 |
Fifth selection |
| 6 | anthropic/claude-fable-5 |
5 |
First remaining routed id in provider/id alphabetical order |
| 7 onward | Remaining routed models | 5 |
Provider alphabetically, then model id alphabetically |
| 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. With account selectors, the five-entry limit applies after bare native choices
have expanded into selector-qualified groups.
Changing the order
Section titled “Changing the order”Use subagentModels to choose and order the leading models that Codex also advertises to
spawn_agent. 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 retains those ids once saved, including choices currently unavailable. 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.
Use modelPickerOrder for display-only ordering of routed <provider>/<model> rows beyond that
featured block:
{ "modelPickerOrder": [ "tyler/deepseek-v4-pro", "jd-chat/kimi-k3", "jd-chat/glm-5.2" ]}Listed routed rows appear in the configured order. A routed row omitted from the array keeps its
normal priority, so it remains ahead of the modelPickerOrder display band; list every routed row
whose relative position you want to control. A row also present in subagentModels keeps its
featured priority. With a routed-only list, native rows keep their normal positions.
To order the complete picker, include a bare native id:
{ "modelPickerOrder": ["gpt-5.6-sol", "opencode-go/glm-5.3"]}Listed rows appear first in array order, followed by unlisted rows in natural priority
order. Matching uses exact catalog ids: gpt-5.6-sol and openai/gpt-5.6-sol are separate
rows. Raw and encoded spellings of the same routed id are also accepted, with exact
matches taking precedence. Empty entries are ignored. Account-qualified rows need
their selector-qualified id in the list.
Migration note: native ids in existing orders
Section titled “Migration note: native ids in existing orders”Previously, native ids in modelPickerOrder were ignored. An existing list containing
a bare native id now activates complete-picker ordering, including featured rows.
Remove bare native ids to keep the previous routed-only behavior. Unset, empty and
routed-only lists retain their behavior; OpenCodex’s natural-priority guidance candidate calculation is unchanged.
modelPickerOrder preserves OpenCodex’s natural-priority calculation of up to five preferred
candidates for subagent guidance. Each moved row retains its natural priority separately from
its native priority; changing picker order alone must not change that OpenCodex calculation.
It does not restrict eligibility for an exact-name model override: the native advertised list
is not an allowlist, and existing authentication, model/effort and backend constraints still apply.
Native Codex uses native priority to select the first five eligible picker-visible models
advertised by spawn_agent on V1 and on V2 when model overrides are exposed. Those advertised
five may therefore change with picker order, even when OpenCodex’s preferred candidates remain
unchanged. V1 receives no OpenCodex preferred-roster injection. V2 may additionally receive
OpenCodex’s natural-priority guidance when the client catalog state permits; that guidance does
not reorder the native tool’s advertised list.
disabledModels and each provider’s selectedModels remain visibility fields,
not ordering controls. There is no separate modelOrder, providerOrder, or priority-map setting.
Dashboard picker presets
Section titled “Dashboard picker presets”On Models, choose Default, A–Z by model, Group by provider, or Most used snapshot, then Apply order. This saves the currently visible routed ids and modelPickerOrderMode (alphabetical, provider, or most-used). Most used reads all retained usage once when applied; reloads restore the snapshot without fetching usage again. New or removed models do not automatically recompute it. A manually saved order, including a complete/native order, remains untouched until you explicitly apply a replacement. Default clears both picker fields, even when no routed models are available.
The controls use GET/PUT /api/subagent-models: chosen and available retain saved roster choices, including disabled or missing models; pickerAvailable contains only eligible routed catalog ids. The Models page sends pickerOrder and pickerOrderMode, never models. Roster-only saves preserve picker settings. Invalid combined updates and failed persistence leave the previous picker/roster state intact.
Routed-only presets keep the existing featured/native priority bands. They affect the Codex catalog and Claude discovery’s routed groups; Claude’s native prefix and explicit Desktop profile/alias ownership remain unchanged. OpenCodex guidance ranks and configured fallback settings are preserved, but native Codex’s advertised five and recommended default can change with display priority. Saving does not restart clients; a catalog refresh may remain pending, and clients holding an old catalog may need reopening.
Custom routed order
Section titled “Custom routed order”Choose Custom order on Models to load a fresh routed snapshot. Drag a movable row before another row, or use its Up/Down buttons, then Save draft. Featured routed rows stay at the front in their configured rank and cannot move. Native rows are not shown; this is not a preview of the complete native picker. Surviving saved rows keep their relative order and new candidates follow the current candidate list. Every save sends the complete routed list, without changing the featured roster.
An order containing bare native ids remains protected until you explicitly apply a routed preset or Default. Selecting a different option alone does not replace it. Unknown featured state blocks editing. Before saving, the editor checks a fresh snapshot; changes preserve your draft and block saving until Reload and discard draft loads current settings. Request failures retain the draft. Accepted saves can still have a pending catalog refresh; reload before editing again.
The editor also requires an unambiguous model identity for every routed candidate. If the model catalog is incomplete, refresh the Models page before editing; reloading picker settings alone cannot restore missing catalog identities. Featured choices are matched exactly without trimming; duplicate choices use their last configured position, and canonical ids take precedence over raw ids.

