Codex account state, model traffic, and chat history are related but separate. Most mysterious 401s, compaction failures, and “missing” chats come from treating them as one thing.
Start with the right mental model
| Name | Stored in | What it actually does |
|---|---|---|
| OcHub connection ID | OcHub database | Identifies one connection card; it may remain a UUID |
| Codex Provider ID | model_provider in config.toml |
Selects [model_providers.<id>] and identifies the Codex history bucket |
| Codex provider name | [model_providers.<id>].name |
Display and capability-compatibility field; not the history bucket |
| ChatGPT login | auth.json or OS credential store |
Stores and refreshes ChatGPT credentials |
| Model-provider credential | Active provider authentication fields | Authenticates model requests to a third party or the local OcHub gateway |
Renaming an OcHub card does not migrate chats. Changing model_provider can
move new chats to a different bucket. OcHub separates its internal UUID from
the Codex Provider ID; new model-provider connections default to stable
custom, and you can choose an explicit value such as company_proxy.
Keep ChatGPT login while using a model provider
Use this mode when you still need ChatGPT account state but want model inference to go through a third-party Responses API or an OcHub model provider.
-
Sign in to ChatGPT first. Verify that the official Codex connection works alone. Credentials may live in
~/.codex/auth.jsonor the OS keychain. -
Save the signed-in state as the connection version. While the official connection is current, switch away and choose Save as new version when OcHub shows the
auth.jsonandconfig.tomldiff. -
Add a Codex connection and select Model provider. Choose an existing provider and the client-facing model.
-
Set a stable Provider ID. Use a value such as
company_proxy. It is the history bucket, not the internal OcHub connection ID. -
Choose ChatGPT login + third-party API. OcHub includes the login material in this connection version and issues a separate client key for its local gateway.
-
Review the preview.
model_providershould contain the stable ID;base_urlshould point to the local OcHub gateway; the provider should keep both the OpenAI-login requirement and the gateway bearer. -
Save, switch, and restart Codex. Send one short request and confirm the
gatewaydata source under Usage → Request logs.
A generated configuration looks like this. OcHub generates the key; do not copy it manually to unrelated machines:
model_provider = "company_proxy"
[model_providers.company_proxy]
name = "Company Proxy"
base_url = "http://127.0.0.1:4180/v1"
wire_api = "responses"
requires_openai_auth = true
experimental_bearer_token = "rd-..."There are two independent authentication chains:
- Codex owns the ChatGPT login cache.
- Model requests use
rd-...to enter the OcHub gateway; the gateway then uses the model provider’s upstream credential.
Keeping auth.json does not make a third-party API accept ChatGPT OAuth.
Having only the gateway key does not mean Codex is signed in to ChatGPT.
Launch Codex with native Fast and Ultra
On macOS, open the local Codex app page in OcHub and click Launch Codex. OcHub starts a separate desktop instance whose native model picker can expose Fast and Ultra for compatible models. This is useful when inference is routed through a custom model provider and the normal account entitlement check would otherwise hide or clear those choices.
The launcher performs an in-memory JavaScript injection. It opens a
loopback-only Chrome DevTools Protocol endpoint, attaches to each renderer
before its first application script runs, and intercepts
app-initial-*.js. The patch removes the native picker’s ChatGPT-account gates
for Fast and Ultra and prevents Codex from clearing the selected Fast service
tier before thread/start or turn/start. It keeps Codex’s own picker, React
components, setting storage, and request format. The installed application is
not modified or re-signed.
-
Configure and switch the Codex connection. Select a direct connection or model provider whose client-facing model is one of the supported exact model IDs below.
-
Open the local Codex page. The launcher is intentionally unavailable for remote nodes and non-macOS builds.
-
Click Launch Codex. OcHub finds
Codex.apporChatGPT.appin/Applicationsor~/Applications, starts a separate instance, injects the first renderer document, and then reports success. -
Use the native picker beneath the composer. Choose the model, reasoning effort, and Fast mode in Codex itself.
-
Send a short request and inspect Usage → Request logs. Confirm the model and upstream accepted the selected mode before using it for important work.
Current generated-catalog capabilities are exact-match only:
| Model ID | Fast | Max | Ultra |
|---|---|---|---|
gpt-5.6-sol |
Yes | Yes | Yes |
gpt-5.6-terra |
Yes | Yes | Yes |
gpt-5.6-luna |
Yes | Yes | No |
Unknown or similarly named third-party models do not inherit these capabilities. An exact model entry already supplied by Codex keeps its own capability metadata.
The injection lasts only for the instance launched by OcHub. Keep OcHub running
so newly created renderer documents can also be patched, and launch through
OcHub again after quitting Codex. The debugging listener is bound to
127.0.0.1; OcHub rejects non-loopback targets.
The patch deliberately fails closed when a Codex update changes the expected renderer gates. If OcHub reports that injection failed, quit all Codex or ChatGPT app windows, install a newer OcHub build if available, and launch again. Do not repeatedly open the failed instance from the Dock, because that bypasses the OcHub launcher.
What compaction actually compacts
Long chats have two different kinds of state:
- Local transcript: retained on disk for
/resume, session lists, and inspection. - Active context: history sent with the next model request, limited by the model context window.
/compact compacts active context. Codex replaces older turns with a concise
summary so later requests retain key decisions without unbounded context
growth. It is not the same as deleting the local transcript. Codex may also
compact automatically at its model default; advanced users can override the
trigger with model_auto_compact_token_limit.
What remote compaction means
Ordinary compaction can summarize on the client. Remote compaction delegates a
Responses-specific compaction request to an upstream that implements that
semantics. In the current OcHub implementation, such requests contain a
Responses compaction_trigger; there is no faithful Chat Completions or
Anthropic Messages equivalent.
OcHub therefore offers remote compaction only when the selected model provider has at least one native Responses upstream:
- Enable a Responses interface on the model provider.
- Edit the Codex connection and select that provider.
- Enable Remote compaction in the Provider section.
- Confirm that the preview writes the provider name as exactly
OpenAI. - Restart Codex and test
/compactin a long chat.
Writing the provider name as OpenAI is a current Codex/OcHub capability
compatibility rule. Do not confuse it with model_provider = "openai".
The former names your custom provider; the latter selects Codex’s reserved
built-in OpenAI provider and cannot define your relay.
What Responses WebSocket means
supports_websockets = true tells Codex that this model provider supports the
Responses API WebSocket transport. A capable provider can then carry Responses
events over a persistent bidirectional connection instead of opening a normal
HTTP/SSE request each time.
Two unrelated WebSocket features are easy to confuse:
| WebSocket | Connects | OcHub/Codex setting |
|---|---|---|
| Responses WebSocket | Codex model client ↔ model provider | supports_websockets = true |
| app-server WebSocket | External client ↔ codex app-server |
codex --remote / app-server --listen |
OcHub configures the first. It does not turn Codex CLI into a remote app server.
When to enable WebSocket
Enable it only when all of these are true:
- The upstream explicitly supports Responses WebSocket, not only HTTP streaming.
- The Responses interface in the model provider has WebSocket enabled.
- Network proxies, TLS termination, and corporate CAs allow
wss://handshakes and long-lived connections. - An ordinary Responses request already succeeds.
After enabling WebSocket in the model-provider editor, OcHub projects the
capability into the Codex connection. Check the config.toml preview:
[model_providers.company_proxy]
wire_api = "responses"
supports_websockets = trueWebSocket can reduce repeated connection overhead and fit continuous event streams, but it does not guarantee lower latency for every upstream. Disable it when handshakes fail, connections churn, or a corporate proxy supports only ordinary HTTPS. It cannot fix a wrong model, credential, or Base URL.
Where chats are stored
Official Codex behavior keeps resumable session transcripts locally. Current
versions typically use these locations under $CODEX_HOME (default
~/.codex):
sessions/: rollout JSONL for active sessions.archived_sessions/: archived but restorable sessions.state_5.sqlite: thread lists, indexes, and provider-bucket state.
These filenames are current implementation details and may change in later
Codex releases. Prefer /resume, /archive, codex unarchive, and OcHub
session management over bulk-editing files while Codex is running.
auth.json is not chat history. It contains sensitive login material and
should be protected like a password: never commit it, paste it into tickets,
or share it in public chat.
Why Provider ID changes history
Codex records model_provider in session metadata and its thread index. This
distinguishes the built-in openai, shared custom, and other providers, but
it also means a Provider ID change changes the session bucket.
Practical rules:
- Changing only the upstream URL, model, or key: keep the Provider ID.
- Sharing history across third-party connections: give them the same stable ID,
such as
custom. - Isolating team and personal history: use distinct IDs such as
team_proxyandpersonal_proxy. - Replacing a legacy UUID ID: quit Codex and save the new ID through OcHub so it can back up and migrate JSONL plus SQLite state.
/archiveretains the session locally;/deletepermanently deletes the current session and spawned descendant sessions.
A reliable troubleshooting order
- Login layer: Does Codex still show a signed-in account? Is the credential in a file or keychain?
- Provider layer: Does
model_providerpoint to an existing[model_providers.<id>]? - Gateway layer: Is the Base URL local to OcHub, and was the
rd-...key issued for this connection? - Ordinary request: Disable remote compaction and WebSocket, then verify one normal Responses request.
- WebSocket: Enable it only after confirming upstream and network support.
- Compaction: Enable remote compaction last and test
/compactseparately. - History: If
/resumechanges, verifyCODEX_HOMEand Provider ID before deleting anything.
Official references and implementation boundaries
- OpenAI’s Codex configuration reference
defines
model_provider,requires_openai_auth,supports_websockets, and auto-compaction thresholds. - OpenAI’s Codex authentication and sessions explains login caching and credential storage.
- OpenAI’s Codex CLI commands
documents
/compact,/resume,/archive, and/delete. - OpenAI’s Codex model selection describes model, reasoning, Max, and Ultra controls.
- OpenAI’s Codex speed guide distinguishes ChatGPT Fast mode from API Priority processing.
- Provider-name remote-compaction detection, Responses-only routing guards, native-picker injection, UUID history migration, and exact scanned file paths are OcHub compatibility behavior for current Codex versions, not a permanent OpenAI protocol promise.

