Skip to content

Commit 4f3530f

Browse files
committed
docs: record Codex App catalog integration
1 parent 8e1c770 commit 4f3530f

6 files changed

Lines changed: 420 additions & 0 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ for every field.
158158
The full developer documentation — architecture, every adapter, the request lifecycle, the sidecars,
159159
Codex integration, and the CLI/config reference — is an Astro site under [`docs-site/`](./docs-site)
160160
and published to **[lidge-jun.github.io/opencodex](https://lidge-jun.github.io/opencodex/)**.
161+
Deep implementation notes live under [`docs/`](./docs), including the Codex App/model catalog path
162+
that makes routed opencodex models appear in the Codex App picker.
161163

162164
## Development
163165

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# 90.1 — Codex App Fast + Model Visibility
2+
3+
Date: 2026-06-20
4+
5+
## Outcome
6+
7+
The Phase 90 patch did more than fix the Codex TUI `/fast` status line. The user confirmed that
8+
Codex App also:
9+
10+
- exposes the fast option for native OpenAI passthrough models, and
11+
- shows opencodex routed model names in the model picker.
12+
13+
This is a major integration result because Codex App appears to consume the same Codex home
14+
configuration and model catalog path as Codex CLI/TUI.
15+
16+
## Why it worked
17+
18+
opencodex is now aligned with Codex's native integration surfaces:
19+
20+
1. `model_provider = "opencodex"` is written at the TOML root, not inside a stale table.
21+
2. `[model_providers.opencodex]` is shaped like a Codex Responses provider:
22+
- `base_url = "http://localhost:10100/v1"`
23+
- `wire_api = "responses"`
24+
- `requires_openai_auth = true`
25+
3. `model_catalog_json` is also written at the TOML root, pointing Codex to
26+
`$CODEX_HOME/opencodex-catalog.json`.
27+
4. Routed catalog entries are cloned from a native Codex model template, preserving strict parser
28+
fields such as `base_instructions`, `supported_reasoning_levels`, `shell_type`, and
29+
`supported_in_api`.
30+
5. Routed entries set `slug`, `display_name`, `description`, `priority`, and `visibility = "list"`,
31+
making them picker-visible without Codex App-specific code.
32+
6. Native OpenAI passthrough models keep fast-tier metadata, while routed provider models strip
33+
speed/service-tier metadata so fast does not leak to non-OpenAI providers.
34+
35+
## Important split
36+
37+
Current Codex uses different spellings for persistence vs runtime/catalog semantics:
38+
39+
- Config persistence: `service_tier = "fast"`
40+
- Runtime/catalog service-tier id: `priority`
41+
- UI feature gate: `[features].fast_mode = true`
42+
- Account/provider gate: `requires_openai_auth = true`
43+
44+
opencodex must preserve this split. Rewriting everything to `fast` or everything to `priority`
45+
breaks one side of Codex.
46+
47+
## Regression checks
48+
49+
Use these checks before claiming this path is still working:
50+
51+
```bash
52+
codex debug models
53+
```
54+
55+
Confirm native OpenAI passthrough models include fast support:
56+
57+
```text
58+
gpt-5.5
59+
additional_speed_tiers: ["fast"]
60+
service_tiers: [{ id: "priority", name: "Fast" }]
61+
```
62+
63+
Confirm routed models do not expose fast/service tiers:
64+
65+
```text
66+
opencode-go/*
67+
xai/*
68+
anthropic/*
69+
```
70+
71+
Expected:
72+
73+
```text
74+
no additional_speed_tiers
75+
no service_tier
76+
no service_tiers
77+
no default_service_tier
78+
```
79+
80+
Also confirm the injected Codex config contains:
81+
82+
```toml
83+
model_provider = "opencodex"
84+
model_catalog_json = "/absolute/path/to/opencodex-catalog.json"
85+
service_tier = "fast"
86+
87+
[features]
88+
fast_mode = true
89+
90+
[model_providers.opencodex]
91+
name = "OpenCodex Proxy"
92+
base_url = "http://localhost:10100/v1"
93+
wire_api = "responses"
94+
requires_openai_auth = true
95+
```
96+
97+
## Files
98+
99+
- `src/codex-inject.ts`
100+
- `src/codex-catalog.ts`
101+
- `src/codex-paths.ts`
102+
- `src/server.ts`
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
---
2+
title: Codex App model picker
3+
description: How opencodex models appear in Codex App, Codex CLI, and Codex TUI through the shared Codex catalog.
4+
---
5+
6+
opencodex does not patch Codex App. It writes the same Codex configuration and model catalog that
7+
Codex CLI/TUI already use. Because Codex App reads that shared state, routed models can appear in the
8+
App's model picker as normal Codex catalog entries.
9+
10+
## Integration path
11+
12+
`ocx init`, `ocx start`, and `ocx sync` keep these Codex files aligned under the resolved
13+
`CODEX_HOME` directory:
14+
15+
```text
16+
$CODEX_HOME/config.toml
17+
$CODEX_HOME/opencodex.config.toml
18+
$CODEX_HOME/opencodex-catalog.json
19+
$CODEX_HOME/models_cache.json
20+
```
21+
22+
The active provider is installed as a root config key:
23+
24+
```toml
25+
model_provider = "opencodex"
26+
model_catalog_json = "/absolute/path/to/opencodex-catalog.json"
27+
```
28+
29+
The provider itself is registered as a Responses-compatible endpoint:
30+
31+
```toml
32+
[model_providers.opencodex]
33+
name = "OpenCodex Proxy"
34+
base_url = "http://localhost:10100/v1"
35+
wire_api = "responses"
36+
requires_openai_auth = true
37+
```
38+
39+
## Why routed models show up
40+
41+
Codex's model picker expects Codex-shaped catalog entries. opencodex builds those entries by cloning
42+
a native Codex model template, then replacing the routed model identity:
43+
44+
```text
45+
slug = "anthropic/claude-sonnet-..."
46+
display_name = "anthropic/claude-sonnet-..."
47+
visibility = "list"
48+
```
49+
50+
The clone keeps strict-parser fields such as reasoning levels, shell type, API support flags, and
51+
base instructions. That makes each routed entry look like a valid picker-visible Codex model.
52+
53+
## Fast tier rules
54+
55+
Codex currently stores fast mode as:
56+
57+
```toml
58+
service_tier = "fast"
59+
60+
[features]
61+
fast_mode = true
62+
```
63+
64+
But the model catalog and runtime request tier id use:
65+
66+
```text
67+
priority
68+
```
69+
70+
opencodex preserves that split. Native OpenAI passthrough models keep fast support; routed
71+
non-OpenAI models strip service-tier metadata so the fast option is not advertised where it cannot
72+
be honored.
73+
74+
## Refreshing model state
75+
76+
If the picker still shows stale entries, refresh the catalog and restart the target Codex surface:
77+
78+
```bash
79+
ocx sync
80+
```
81+
82+
opencodex also invalidates Codex's `models_cache.json` when it changes routed model visibility or
83+
catalog metadata.

docs/codex-app-model-catalog.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Codex App Model Catalog Integration
2+
3+
Date: 2026-06-20
4+
5+
This document records why opencodex routed models can appear in Codex App's model picker without
6+
patching Codex App itself.
7+
8+
## Summary
9+
10+
Codex CLI, TUI, and App share the Codex home configuration surface. opencodex integrates by writing
11+
Codex-native config and catalog files under the resolved `CODEX_HOME`:
12+
13+
- `$CODEX_HOME/config.toml`
14+
- `$CODEX_HOME/opencodex.config.toml`
15+
- `$CODEX_HOME/opencodex-catalog.json`
16+
- `$CODEX_HOME/models_cache.json`
17+
18+
When Codex App reads the same config/catalog state, routed opencodex models are visible because they
19+
look like valid Codex catalog entries.
20+
21+
## Required config shape
22+
23+
The global provider must be a root TOML key:
24+
25+
```toml
26+
model_provider = "opencodex"
27+
```
28+
29+
It must not be appended under whichever TOML table happened to be last. TOML root keys after a table
30+
header become part of that table, which makes Codex ignore the provider as a global setting.
31+
32+
The custom model catalog path must also be a root TOML key:
33+
34+
```toml
35+
model_catalog_json = "/absolute/path/to/opencodex-catalog.json"
36+
```
37+
38+
The provider block must advertise a Responses-compatible provider:
39+
40+
```toml
41+
[model_providers.opencodex]
42+
name = "OpenCodex Proxy"
43+
base_url = "http://localhost:10100/v1"
44+
wire_api = "responses"
45+
requires_openai_auth = true
46+
```
47+
48+
`requires_openai_auth = true` is important for Codex App/TUI account-gated behavior. Codex derives
49+
ChatGPT-account capability from the active provider; without this flag, fast-related UI can stay
50+
hidden even when the user has ChatGPT auth.
51+
52+
## Catalog entry shape
53+
54+
opencodex does not generate minimal JSON entries. It clones a native Codex model catalog entry and
55+
then changes the routed fields:
56+
57+
```text
58+
slug = "<provider>/<model>"
59+
display_name = "<provider>/<model>"
60+
description = "Routed via opencodex -> <provider> ..."
61+
priority = <picker priority>
62+
visibility = "list"
63+
```
64+
65+
Cloning a native entry preserves fields Codex's strict parser expects, including:
66+
67+
- `base_instructions`
68+
- `supported_reasoning_levels`
69+
- `default_reasoning_level`
70+
- `shell_type`
71+
- `supported_in_api`
72+
73+
This is why routed entries can behave like normal picker-visible Codex models.
74+
75+
## Fast tier handling
76+
77+
Codex uses a split between config spelling and runtime/catalog spelling:
78+
79+
| Surface | Value |
80+
|---|---|
81+
| `config.toml` persistence | `service_tier = "fast"` |
82+
| catalog/request tier id | `priority` |
83+
| feature gate | `[features].fast_mode = true` |
84+
| provider/account gate | `requires_openai_auth = true` |
85+
86+
Native OpenAI passthrough models can keep fast metadata. Routed non-OpenAI models must not inherit
87+
that metadata from the native template:
88+
89+
```text
90+
delete additional_speed_tiers
91+
delete service_tier
92+
delete service_tiers
93+
delete default_service_tier
94+
```
95+
96+
This prevents fast from appearing for providers where Codex/OpenAI priority processing is not a valid
97+
request option.
98+
99+
## Cache invalidation
100+
101+
Codex caches models in:
102+
103+
```text
104+
$CODEX_HOME/models_cache.json
105+
```
106+
107+
After changing providers, hidden models, featured models, or service-tier metadata, opencodex should
108+
delete that cache so the next Codex process or model refresh sees the updated catalog.
109+
110+
## Verification
111+
112+
Useful probes:
113+
114+
```bash
115+
codex doctor --json
116+
codex debug models
117+
ocx sync
118+
ocx status
119+
```
120+
121+
Expected high-level result:
122+
123+
- active model provider is `opencodex`
124+
- provider uses ChatGPT auth reachability semantics
125+
- native `gpt-*` entries keep fast support
126+
- routed `<provider>/<model>` entries are `visibility = "list"`
127+
- routed entries have no fast/service-tier metadata

structure/00_overview.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# opencodex Structure
2+
3+
This folder records the implementation map for maintainers. It is intentionally shorter than
4+
`devlog/`: devlog records decisions over time; `structure/` records the current shape of the system.
5+
6+
## Main runtime
7+
8+
| Path | Responsibility |
9+
|---|---|
10+
| `src/cli.ts` | CLI entrypoint for `ocx` / `opencodex`; setup, service, sync, login, restore. |
11+
| `src/server.ts` | Bun proxy server, management API, `/v1/responses`, `/v1/models`. |
12+
| `src/router.ts` | Provider/model resolution before adapter dispatch. |
13+
| `src/types.ts` | Shared config, provider, request, and adapter event types. |
14+
| `src/config.ts` | `~/.opencodex/config.json` read/write and atomic writes. |
15+
16+
## Codex integration
17+
18+
| Path | Responsibility |
19+
|---|---|
20+
| `src/codex-paths.ts` | Resolve `CODEX_HOME`, config path, profile path, catalog path, and cache path. |
21+
| `src/codex-inject.ts` | Inject/strip `model_provider`, provider table, profile file, fast-mode feature. |
22+
| `src/codex-catalog.ts` | Merge routed models into Codex-shaped catalog entries and restore native catalog. |
23+
| `src/service.ts` | launchd, systemd user unit, and Windows Task Scheduler service integration. |
24+
| `src/open-url.ts` | Cross-platform browser opener for OAuth, GUI, and prompts. |
25+
26+
## Providers and adapters
27+
28+
| Path | Responsibility |
29+
|---|---|
30+
| `src/adapters/` | Provider wire adapters and stream bridges. |
31+
| `src/oauth/` | OAuth flows, token storage, refresh, and auth-token resolution. |
32+
| `src/oauth/key-providers.ts` | API-key provider catalog and provider defaults. |
33+
| `src/model-cache.ts` | Provider `/models` cache with fresh/stale fallback. |
34+
35+
## GUI and docs
36+
37+
| Path | Responsibility |
38+
|---|---|
39+
| `gui/` | React dashboard for provider setup, OAuth login, model visibility, and logs. |
40+
| `docs-site/` | Astro/Starlight public documentation site. |
41+
| `docs/` | Technical investigation notes and implementation references. |
42+
| `devlog/` | Time-ordered implementation plans, decisions, and verification records. |
43+
44+
## Generated/local state
45+
46+
| Path | Responsibility |
47+
|---|---|
48+
| `dist/` | Local build/bin output; ignored by git. |
49+
| `node_modules/` | Local dependencies; ignored by git. |
50+
| `~/.opencodex/` | User opencodex config, auth tokens, pid files, logs, catalog backup. |
51+
| `$CODEX_HOME/` | Codex config, profile, catalog, and model cache touched by opencodex. |

0 commit comments

Comments
 (0)