Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions docs-site/src/content/docs/guides/codex-app-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,45 @@ gpt-5.6-sol # openai (Pool or Direct option)
openai-apikey/gpt-5.6-sol # API key
```

When multiple Codex accounts are logged in, turn on **Show each Codex account separately in the
model picker** under **Codex Auth** to target one account for a conversation without logging out.
You can also configure `codexAccountNamespaces` and run `ocx sync`. The picker then shows a separate
copy of every GPT model for every configured account:

```text
main/gpt-5.6-sol # exact main/Desktop account
side/gpt-5.6-sol # exact added account
```

`main` identifies the built-in Codex login. `side` is a public selector that maps privately to one
stored account; it is not the account's internal ID or an account type. Dashboard-generated
selectors use the account's explicit user-owned alias, or a stable privacy-safe `pXXXXXX` label when
no alias is set. They never derive from the stored account ID or email. A numeric suffix avoids
existing provider or combo prefixes. The equivalent config is:

```json
{
"codexAccountNamespaces": { "main": "main", "side": "added-account-id" }
}
```

The object keys are public selectors; the values are private stored account IDs used only for exact
routing. Existing and custom selectors are never regenerated. Plain `gpt-*` ids remain valid for
saved threads and config, and continue to use the provider's Pool/Direct behavior. Omitting the map
keeps the existing picker unchanged. Turning the dashboard setting off hides account-specific rows
but preserves their bindings and explicit selectors. The **Codex Auth** dashboard refreshes the
catalog automatically after changing the toggle.
Deleting an added account removes its picker rows but retains the selector binding so saved
conversations fail closed instead of falling through. Re-adding the same stored account restores
those rows.

An account-qualified native selector still routes through the canonical `openai` provider and pins
the request to its exact Codex account; it never falls through to Pool/Direct account selection.
Missing credentials, cooldown, or reauthentication fail the request. Bare models retain normal
Pool/Direct behavior, and future native models added to opencodex's supported catalog automatically
receive the configured prefixes on the next sync. See the
[configuration reference](/reference/configuration/#account-qualified-native-models).

Fresh installs and configs with no saved mode default to Pool. Current configs use marker 2 and
retain the shipped v1 source at `~/.opencodex/config.json.pre-openai-tiers-v2.bak`; restore it with:

Expand Down
19 changes: 14 additions & 5 deletions docs-site/src/content/docs/guides/model-routing.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ Pool(default, main plus added accounts) or Direct(current caller/main bearer) wi
model id. `openai-apikey/<model>` explicitly selects API-key transport. The two credential routes
do not fall through to one another.

Configured `codexAccountNamespaces` are checked first. A selector such as `side/gpt-5.6-sol`
resolves to the canonical `openai` provider plus one immutable account id. It bypasses pool
selection and fails closed instead of changing accounts. Account namespace keys cannot collide with
configured provider names.

## Precedence

1. **Explicit `provider/model`** — if the id contains `/` and the part before it is the name of a
1. **Account-qualified native model** — if the prefix is configured in
`codexAccountNamespaces`, the remainder must be a bare native OpenAI model id and the exact
configured account is used.

2. **Explicit `provider/model`** — if the id contains `/` and the part before it is the name of a
configured provider, that provider is used and the id is stripped to the part after the slash.

```text
Expand All @@ -25,10 +34,10 @@ do not fall through to one another.
This is the unambiguous form, and the one Codex's model picker uses for routed models.
If the named provider is disabled, this explicit form throws instead of routing.

2. **A provider's `defaultModel`** — if any provider's `defaultModel` equals the id, that provider
3. **A provider's `defaultModel`** — if any provider's `defaultModel` equals the id, that provider
is used (id passed through unchanged).

3. **Built-in prefix patterns** — the id is matched against known model-family prefixes, then routed
4. **Built-in prefix patterns** — the id is matched against known model-family prefixes, then routed
to a configured provider of that name (or name-prefix):

| Prefixes | Provider |
Expand All @@ -40,11 +49,11 @@ do not fall through to one another.
This matcher is name-based and, unlike the `defaultModel` / `models[]` scans, currently does not
filter a matching provider whose `disabled` flag is true.

4. **A provider's `models[]`** — if no prefix rule won and an active provider lists the id in its
5. **A provider's `models[]`** — if no prefix rule won and an active provider lists the id in its
`models[]`, that provider is used. This order matters: with an OpenAI-named provider configured,
a bare `gpt-*` id reaches it before another provider's `models[]` claim.

5. **Default provider** — if nothing matched, the id is sent to `config.defaultProvider` unchanged.
6. **Default provider** — if nothing matched, the id is sent to `config.defaultProvider` unchanged.
(If no default provider is configured, or it is disabled, routing throws.)

## API keys and environment variables
Expand Down
23 changes: 23 additions & 0 deletions docs-site/src/content/docs/ja/guides/codex-app-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ OpenAI ID は 2 種類に固定されます。bare native ID は `codexAccountMo
ID は変わりません。API GPT-5.6 は context 1,050,000 / max input 922,000 で、
`*-pro` ピッカー ID は公開状態を維持しつつ wire でベースモデル + `reasoning.mode: "pro"` になります。

複数の Codex アカウントにログインしている場合は、**Codex Auth** の **各 Codex アカウントを
モデル選択に個別表示**を有効にすると、ログアウトせずに会話で使うアカウントを明示できます。
各 GPT モデルはアカウントごとに別の項目として表示されます。

```text
main/gpt-5.6-sol # 組み込みの Codex ログインに固定
side/gpt-5.6-sol # 公開セレクター side に対応する追加アカウントに固定
```

`main` は組み込みログインを表します。`side` は保存済みアカウント 1 件に非公開で対応する公開
セレクターであり、内部アカウント ID やアカウント種別ではありません。ダッシュボードが生成する
セレクターには、ユーザーが明示した表示名を使います。表示名がなければ、安定したプライバシー保護
ラベル `pXXXXXX` を使い、保存済みアカウント ID やメールアドレスからは生成しません。既存または
カスタムのセレクターは変更されず、名前が重なる場合だけ数字が付きます。アカウント指定の native
セレクターは引き続き canonical `openai` プロバイダーを通り、選択したアカウントに固定されます。
Pool/Direct のアカウント選択やフォールバックは行わず、選択したアカウントが利用できない場合は
失敗します。プレフィックスなしの `gpt-*` は従来の Pool/Direct 動作を維持します。設定を無効にしても
項目が非表示になるだけで、保存済みのバインドは削除されません。追加アカウントを削除するとその項目は
消えますが、保存済みの選択が別アカウントへ流れないようバインドは残ります。同じ保存済みアカウントを
再追加すると項目が戻ります。
手動設定と `ocx sync` については
[設定リファレンス](/ja/reference/configuration/)を参照してください。

## 統合経路

`ocx init`、`ocx start`、`ocx sync` は解決された `CODEX_HOME` の下のファイルを合わせます。
Expand Down
21 changes: 21 additions & 0 deletions docs-site/src/content/docs/ko/guides/codex-app-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,27 @@ OpenAI id는 두 가지로 고정됩니다. bare native id는 `codexAccountMode`
id는 변하지 않습니다. API GPT-5.6은 context 1,050,000 / max input 922,000이고,
`*-pro` picker id는 공개 상태를 유지하면서 wire에서 base 모델 + `reasoning.mode: "pro"`가 됩니다.

여러 Codex 계정에 로그인한 경우 **Codex Auth**에서 **각 Codex 계정을 모델 선택기에 별도로 표시**를
켜면 로그아웃하지 않고도 대화에 사용할 계정을 명시적으로 고를 수 있습니다. 각 GPT 모델은 계정마다
별도 항목으로 표시됩니다.

```text
main/gpt-5.6-sol # 내장 Codex 로그인에 고정
side/gpt-5.6-sol # 공개 선택기 side에 연결된 추가 계정에 고정
```

`main`은 내장 로그인을 뜻합니다. `side`는 저장된 계정 하나에 비공개로 연결되는 공개 선택기이며 내부
계정 ID나 계정 유형이 아닙니다. 대시보드가 선택기를 만들 때는 사용자가 명시한 표시 이름을 사용하고,
표시 이름이 없으면 안정적인 개인정보 보호 라벨 `pXXXXXX`를 사용합니다. 저장된 계정 ID나 이메일에서
선택기를 만들지 않습니다. 기존 선택기와 사용자 지정 선택기는 바뀌지 않으며 이름이 겹칠 때만 숫자
접미사가 붙습니다. 계정 지정 native 선택기는 계속 canonical `openai` 프로바이더를 통해 라우팅되고
정확히 선택한 계정에 고정됩니다. Pool/Direct 계정 선택이나 폴백을 사용하지 않으며, 선택한 계정을 사용할
수 없으면 요청이 실패합니다. 접두사 없는 `gpt-*`는 기존 Pool/Direct 동작을 유지합니다. 설정을 꺼도
항목만 숨겨지고 저장된 바인딩은 삭제되지 않습니다. 추가 계정을 삭제하면 선택기 항목은 사라지지만 저장된
선택이 다른 계정으로 넘어가지 않도록 바인딩은 남습니다. 같은 저장 계정을 다시 추가하면 항목이 복원됩니다.
수동 설정과 `ocx sync`는
[설정 레퍼런스](/ko/reference/configuration/)를 참고하세요.

## 통합 경로

`ocx init`, `ocx start`, `ocx sync`는 해석된 `CODEX_HOME` 아래의 파일을 맞춥니다.
Expand Down
64 changes: 64 additions & 0 deletions docs-site/src/content/docs/reference/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ differing backup and rewrites known legacy namespaced selected ids to bare ids.
| `codexShimAutoRestore?` | `boolean` | `true` | Restore a previously installed Codex shim when a completed external Codex update replaces it. Set `false`, or set `OPENCODEX_CODEX_SHIM_AUTO_RESTORE=0` for a process-level opt-out. |
| `syncResumeHistory?` | `boolean` | `true` | Reversible Codex App history compatibility mode. opencodex backs up original Codex thread metadata, remaps old OpenAI interactive rows to `opencodex`, and temporarily promotes opencodex-created `exec` rows to an app-visible source. `ocx stop` / `ocx restore` restore backed-up OpenAI rows and eject remaining opencodex user threads to OpenAI so native Codex can resume them after the proxy is removed from `config.toml`. Set `false` to opt out. |
| `codexAccounts?` | `CodexAccount[]` | `[]` | ChatGPT/Codex pool account metadata managed by the Codex Auth dashboard. Secrets live separately in `codex-accounts.json`. |
| `codexAccountNamespaces?` | `Record<string,string>` | `{}` | Optional public picker selector to private exact Codex account id map. Use `"main"` for the current Codex Desktop/main login. Keys are catalog- and log-visible; values remain server-side. When picker visibility is enabled and at least one binding is available, account-qualified native rows replace plain GPT rows in the picker and fail closed instead of switching accounts. If no binding is available, plain rows remain visible. Plain model ids remain routable. Selector keys cannot collide with provider ids. |
| `codexAccountPickerEnabled?` | `boolean` | inferred | Picker-visibility override. A non-empty namespace map is visible when this is omitted. The dashboard writes `false` to hide account-specific rows without deleting their bindings. |
| `activeCodexAccountId?` | `string` | — | Pool account used for the next new Codex thread. Existing thread affinities keep their original account. |
| `autoSwitchThreshold?` | `number` | `80` | Usage percent threshold for new-session auto-switching. The score uses the hottest known 5h, weekly, or 30d quota window. Set `0` to disable quota auto-switching. |
| `upstreamFailoverThreshold?` | `number` | `3` | Consecutive transient upstream failures before future new sessions fail over to another eligible pool account. Set `0` to disable failure failover. |
Expand All @@ -77,6 +79,68 @@ credential store. Existing thread ids keep account affinity, while new sessions
on quota, cooldown, and health.
:::

### Account-qualified native models

Use `codexAccountNamespaces` when account choice must be visible and intentional in the model picker:

```json
{
"codexAccountNamespaces": {
"main": "main",
"side": "added-account-id"
}
}
```

Each object key is a public, user-owned picker selector; each value is the private stored account ID
used for exact routing. `side` may be any valid selector chosen by the user. The value can be found
locally with `ocx account list openai`, but it is never copied into model catalog rows, errors, or
provider log labels. After `ocx sync`, Codex exposes `main/gpt-*` and `side/gpt-*` copies of every
available supported native model. When a later opencodex update adds support for another native
model, the next catalog sync gives it the same selectors without adding the model separately to this
map.

The dashboard's **Codex Auth** page exposes **Show each Codex account separately in the model
picker** as the single opt-in. Turning it on creates a prefix based on `main` for the main/Desktop
login. For an added account, it uses the explicit user-owned display alias when one is set; otherwise
it generates a stable privacy-safe selector in the form `pXXXXXX`. It never derives a public selector
from the stored account ID or email. A numeric suffix resolves provider or combo-prefix collisions.
These names identify accounts; they do not represent built-in account types. Existing and custom
selectors are never regenerated. Turning the setting off hides the account-qualified rows while
preserving their configured bindings, so turning it back on restores the same picker identifiers.
Stored account IDs, upstream ChatGPT account IDs, emails, and credentials stay server-side. Picker
selectors stay stable if an account's display alias is renamed; accounts added later receive a new
privacy-safe selector automatically while the feature remains enabled.

Deleting an added account hides its rows but keeps its namespace binding as a fail-closed marker for
saved selectors. Re-adding the same stored account restores the existing selector instead of creating
a new one.

When enabled, plain native rows are hidden from the picker and replaced by readable account-labeled
entries such as `Main / 5.6 Sol` and `Side / 5.6 Sol`. Plain model ids are not removed or rerouted:
saved threads and configuration that use `gpt-*` continue to follow Pool/Direct behavior. Because
Codex exposes a flat picker rather than section metadata, the account-specific pairs stay together
ahead of ordinary routed rows; explicitly featured subagent models retain their higher priority.

These selectors do not change `activeCodexAccountId`. They bypass quota auto-switch, transient-
failure failover, affinity rebinding, and unsupported-model retry. If the exact account is missing,
cooling down, or needs reauthentication, the request fails instead of using another account. Bare
`gpt-*` models keep the configured Pool/Direct behavior.

Account-qualified native selectors still route through the canonical `openai` provider and pin the
request to the selected Codex account. They never fall through to Pool/Direct account selection.

Account-qualified ids remain explicitly routable while their picker rows are hidden. This preserves
saved selections; the visibility toggle controls discovery, not the fail-closed account binding.

Account binding follows the model selector. A bare `subagentModels` entry is projected onto its
visible account-specific rows so Codex can advertise those choices; the
client's five-model subagent limit still applies. Use qualified values in `subagentModels`,
`injectionModel`, and `shadowCallIntercept.model` when those calls must use the same account. A
child explicitly launched with a bare model uses ordinary Pool/Direct routing. Standalone client-
side image and alpha-search relays do not reliably carry the selected chat model, so they continue
to use the provider's global Pool/Direct account behavior.

### claudeCode (OcxClaudeCodeConfig)

Claude Code inbound settings consumed by the `/v1/messages` surface, the `ocx claude`
Expand Down
Loading
Loading