Skip to content

Commit 02fe0d8

Browse files
authored
Keep OpenAI Codex migrations on automatic runtime routing (#79238)
* fix: keep migrated openai codex routes automatic * scope runtime policy to providers and models * fix runtime policy surfaces * fix ci runtime policy checks * fix doctor stale session runtime pins
1 parent b7aca7d commit 02fe0d8

92 files changed

Lines changed: 1410 additions & 1253 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ Docs: https://docs.openclaw.ai
180180
- fix(discord): gate user allowlist name resolution [AI]. (#79002) Thanks @pgondhi987.
181181
- fix(msteams): gate startup user allowlist resolution [AI]. (#79003) Thanks @pgondhi987.
182182
- Harden macOS shell wrapper allowlist parsing [AI]. (#78518) Thanks @pgondhi987.
183+
- Doctor/OpenAI: stop pinning migrated `openai-codex/*` routes to the Codex runtime so mixed-provider agents keep automatic PI routing for MiniMax, Anthropic, and other non-OpenAI model switches.
183184
- Gateway/macOS: `openclaw gateway stop` now uses `launchctl bootout` by default instead of unconditionally calling `launchctl disable`, so KeepAlive auto-recovery still works after unexpected crashes; use the new `--disable` flag to opt into the persistent-disable behavior when a manual stop should survive reboots. Fixes #77934. Thanks @bmoran1022.
184185
- Gateway/macOS: `repairLaunchAgentBootstrap` no longer kickstarts an already-running LaunchAgent, preventing unnecessary service restarts and session disconnects when repair runs against a healthy gateway. Fixes #77428. Thanks @ramitrkar-hash.
185186
- Gateway/macOS: `openclaw gateway stop --disable` now persists the LaunchAgent disable bit even after a previous bootout left the service not loaded, keeping the explicit stay-down path reliable. (#78412) Thanks @wdeveloper16.
@@ -341,7 +342,7 @@ Docs: https://docs.openclaw.ai
341342
- CLI/status: show the selected agent runtime/harness in `openclaw status` session rows so terminal status matches the `/status` runtime line. Thanks @vincentkoc.
342343

343344
- CLI/sessions: prune old unreferenced transcript, compaction checkpoint, and trajectory artifacts during normal `sessions cleanup`, so gateway restart or crash orphans do not accumulate indefinitely outside `sessions.json`. Fixes #77608. Thanks @slideshow-dingo.
344-
- Doctor/Codex: repair legacy `openai-codex/*` routes in primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel overrides, and stale session pins to canonical `openai/*`, selecting `agentRuntime.id: "codex"` only when the Codex plugin is installed, enabled, contributes the `codex` harness, and has usable OAuth; otherwise select `agentRuntime.id: "pi"`. Thanks @vincentkoc.
345+
- Doctor/Codex: repair legacy `openai-codex/*` routes to canonical `openai/*`, keep OpenAI agent turns on Codex by default, ignore stale whole-agent/session runtime pins, preserve explicit provider/model runtime policy, and migrate legacy runtime model refs to model-scoped runtime entries. Thanks @vincentkoc.
345346
- Video generation: wait up to 20 minutes for slow fal/MiniMax queue-backed jobs, stop forwarding unsupported Google Veo generated-audio options, and normalize MiniMax `720P` requests to its supported `768P` resolution with the usual override warning/details instead of failing fallback.
346347
- Video generation: accept provider-specific aspect-ratio and resolution hints at the tool boundary, normalize `720P` to MiniMax's supported `768P`, and stop sending Google `generateAudio` on Gemini video requests so provider fallback can recover from model-specific parameter differences. Thanks @vincentkoc.
347348
- Channels/durable delivery: preserve channel-specific final reply semantics when using durable sends, including Telegram selected quotes and silent error replies plus WhatsApp message-sending cancellations.
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
885a734aa93cf04f6c14f8d83c1e96a66a5b96705327ea2de7b2aa7314238976 config-baseline.json
2-
074eb9a1480ff40836d98090ccb9be3465345ac4b46e0d273b7995504bbb8008 config-baseline.core.json
1+
98f80c92fc4fcb37d41470216ae6cd19b094d7f67b0ddc4983eba04aba314fe0 config-baseline.json
2+
d9c4b2035178d3ffe637b751036f12082d4f26761681bb8496b86550565307e8 config-baseline.core.json
33
ed15b24c1ccf0234e6b3435149a6f1c1e709579d1259f1d09402688799b149bd config-baseline.channel.json
4-
c4e8d8898eebc4d40f35b167c987870e426e6c82121696dc055ff929f6a24046 config-baseline.plugin.json
4+
7a9ed89a6ff7e578bfcab7828ab660af59e62402a85bfbfc05d5ae3d975e9728 config-baseline.plugin.json

docs/cli/crestodian.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ configured OpenClaw model. If no configured model is usable yet, it can fall
170170
back to local runtimes already present on the machine:
171171

172172
- Claude Code CLI: `claude-cli/claude-opus-4-7`
173-
- Codex app-server harness: `openai/gpt-5.5` with `agentRuntime.id: "codex"`
173+
- Codex app-server harness: `openai/gpt-5.5`
174174
- Codex CLI: `codex-cli/gpt-5.5`
175175

176176
The model-assisted planner cannot mutate config directly. It must translate the

docs/cli/doctor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Notes:
5656
- Doctor also scans `~/.openclaw/cron/jobs.json` (or `cron.store`) for legacy cron job shapes and can rewrite them in place before the scheduler has to auto-normalize them at runtime.
5757
- On Linux, doctor warns when the user's crontab still runs legacy `~/.openclaw/bin/ensure-whatsapp.sh`; that script is no longer maintained and can log false WhatsApp gateway outages when cron lacks the systemd user-bus environment.
5858
- When WhatsApp is enabled, doctor checks for a degraded Gateway event loop with local `openclaw-tui` clients still running. `doctor --fix` stops only verified local TUI clients so WhatsApp replies are not queued behind stale TUI refresh loops.
59-
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` selects `agentRuntime.id: "codex"` only when the Codex plugin is installed, enabled, contributes the `codex` harness, and has usable OAuth; otherwise it selects `agentRuntime.id: "pi"` so the route stays on the default OpenClaw runner.
59+
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` preserves explicit provider/model `agentRuntime` policy, removes stale whole-agent/session runtime pins, and leaves canonical OpenAI agent refs on the default Codex harness when the official OpenAI provider is in use.
6060
- Doctor cleans legacy plugin dependency staging state created by older OpenClaw versions. It also repairs missing downloadable plugins that are referenced by config, such as `plugins.entries`, configured channels, configured provider/search settings, or configured agent runtimes. During package updates, doctor skips package-manager plugin repair until the package swap is complete; rerun `openclaw doctor --fix` afterward if a configured plugin still needs recovery. If the download fails, doctor reports the install error and preserves the configured plugin entry for the next repair attempt.
6161
- Doctor repairs stale plugin config by removing missing plugin ids from `plugins.allow`/`plugins.entries`, plus matching dangling channel config, heartbeat targets, and channel model overrides when plugin discovery is healthy.
6262
- Doctor quarantines invalid plugin config by disabling the affected `plugins.entries.<id>` entry and removing its invalid `config` payload. Gateway startup already skips only that bad plugin so other plugins and channels can keep running.

docs/concepts/agent-runtimes.md

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ configuration. They are different layers:
2323

2424
You will also see the word **harness** in code. A harness is the implementation
2525
that provides an agent runtime. For example, the bundled Codex harness
26-
implements the `codex` runtime. Public config uses `agentRuntime.id`; `openclaw
27-
doctor --fix` rewrites older runtime-policy keys to that shape.
26+
implements the `codex` runtime. Public config uses `agentRuntime.id` on
27+
provider or model entries; whole-agent runtime keys are legacy and ignored.
28+
`openclaw doctor --fix` removes old whole-agent runtime pins and rewrites
29+
legacy runtime model refs to canonical provider/model refs plus model-scoped
30+
runtime policy where needed.
2831

2932
There are two runtime families:
3033

@@ -33,9 +36,9 @@ There are two runtime families:
3336
`codex`.
3437
- **CLI backends** run a local CLI process while keeping the model ref
3538
canonical. For example, `anthropic/claude-opus-4-7` with
36-
`agentRuntime.id: "claude-cli"` means "select the Anthropic model, execute
37-
through Claude CLI." `claude-cli` is not an embedded harness id and must not
38-
be passed to AgentHarness selection.
39+
a model-scoped `agentRuntime.id: "claude-cli"` means "select the Anthropic
40+
model, execute through Claude CLI." `claude-cli` is not an embedded harness id
41+
and must not be passed to AgentHarness selection.
3942

4043
## Codex surfaces
4144

@@ -87,9 +90,9 @@ This is the agent-facing decision tree:
8790
2. If the user asks for **Codex as the embedded runtime** or wants the normal
8891
subscription-backed Codex agent experience, use `openai/<model>`.
8992
3. If the user explicitly chooses **PI for an OpenAI model**, keep the model ref
90-
as `openai/<model>` and set `agentRuntime.id: "pi"`. A selected
91-
`openai-codex` auth profile is routed internally through PI's legacy
92-
Codex-auth transport.
93+
as `openai/<model>` and set provider/model runtime policy to
94+
`agentRuntime.id: "pi"`. A selected `openai-codex` auth profile is routed
95+
internally through PI's legacy Codex-auth transport.
9396
4. If legacy config still contains **`openai-codex/*` model refs**, repair it to
9497
`openai/<model>` with `openclaw doctor --fix`.
9598
5. If the user explicitly says **ACP**, **acpx**, or **Codex ACP adapter**, use
@@ -132,21 +135,26 @@ This ownership split is the main design rule:
132135

133136
OpenClaw chooses an embedded runtime after provider and model resolution:
134137

135-
1. A session's recorded runtime wins. Config changes do not hot-switch an
136-
existing transcript to a different native thread system.
137-
2. `OPENCLAW_AGENT_RUNTIME=<id>` forces that runtime for new or reset sessions.
138-
3. `agents.defaults.agentRuntime.id` or `agents.list[].agentRuntime.id` can set
139-
`auto`, `pi`, a registered embedded harness id such as `codex`, or a
140-
supported CLI backend alias such as `claude-cli`.
141-
4. In `auto` mode, registered plugin runtimes can claim supported provider/model
138+
1. Model-scoped runtime policy wins. This can live in a configured provider
139+
model entry or in `agents.defaults.models["provider/model"].agentRuntime` /
140+
`agents.list[].models["provider/model"].agentRuntime`.
141+
2. Provider-scoped runtime policy comes next at
142+
`models.providers.<provider>.agentRuntime`.
143+
3. In `auto` mode, registered plugin runtimes can claim supported provider/model
142144
pairs.
143-
5. If no runtime claims a turn in `auto` mode, OpenClaw uses PI as the
145+
4. If no runtime claims a turn in `auto` mode, OpenClaw uses PI as the
144146
compatibility runtime. Use an explicit runtime id when the run must be
145147
strict.
146148

147-
Explicit plugin runtimes fail closed. For example, `agentRuntime.id: "codex"`
148-
means Codex or a clear selection/runtime error; it is never silently routed back
149-
to PI.
149+
Whole-session and whole-agent runtime pins are ignored. That includes
150+
`OPENCLAW_AGENT_RUNTIME`, session `agentHarnessId`/`agentRuntimeOverride` state,
151+
`agents.defaults.agentRuntime`, and `agents.list[].agentRuntime`. Run
152+
`openclaw doctor --fix` to remove stale whole-agent runtime config and convert
153+
legacy runtime model refs where OpenClaw can preserve the intent.
154+
155+
Explicit provider/model plugin runtimes fail closed. For example,
156+
`agentRuntime.id: "codex"` on a provider or model means Codex or a clear
157+
selection/runtime error; it is never silently routed back to PI.
150158

151159
CLI backend aliases are different from embedded harness ids. The preferred
152160
Claude CLI form is:
@@ -156,23 +164,27 @@ Claude CLI form is:
156164
agents: {
157165
defaults: {
158166
model: "anthropic/claude-opus-4-7",
159-
agentRuntime: { id: "claude-cli" },
167+
models: {
168+
"anthropic/claude-opus-4-7": {
169+
agentRuntime: { id: "claude-cli" },
170+
},
171+
},
160172
},
161173
},
162174
}
163175
```
164176

165177
Legacy refs such as `claude-cli/claude-opus-4-7` remain supported for
166178
compatibility, but new config should keep the provider/model canonical and put
167-
the execution backend in `agentRuntime.id`.
179+
the execution backend in provider/model runtime policy.
168180

169181
`auto` mode is intentionally conservative for most providers. OpenAI agent
170182
models are the exception: unset runtime and `auto` both resolve to the Codex
171183
harness. Explicit PI runtime config remains an opt-in compatibility route for
172184
`openai/*` agent turns; when paired with a selected `openai-codex` auth profile,
173185
OpenClaw routes PI internally through the legacy Codex-auth transport while
174-
keeping the public model ref as `openai/*`. Stale OpenAI PI session pins without
175-
explicit config are repaired back to Codex.
186+
keeping the public model ref as `openai/*`. Stale OpenAI PI session pins are
187+
ignored by runtime selection and can be cleaned with `openclaw doctor --fix`.
176188

177189
If `openclaw doctor` warns that the `codex` plugin is enabled while
178190
`openai-codex/*` remains in config, treat that as legacy route state. Run
@@ -206,10 +218,8 @@ diagnostics, not as provider names.
206218
- A runtime id such as `codex` tells you which loop is executing the turn.
207219
- A channel label such as Telegram or Discord tells you where the conversation is happening.
208220

209-
If a session still shows PI after changing runtime config, start a new session
210-
with `/new` or clear the current one with `/reset`. Existing sessions keep their
211-
recorded runtime so a transcript is not replayed through two incompatible native
212-
session systems.
221+
If a run still shows an unexpected runtime, inspect the selected provider/model
222+
runtime policy first. Legacy session runtime pins no longer decide routing.
213223

214224
## Related
215225

docs/concepts/model-providers.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,19 @@ Reference for **LLM/model providers** (not chat channels like WhatsApp/Telegram)
2929
<Accordion title="OpenAI provider/runtime split">
3030
OpenAI-family routes are prefix-specific:
3131

32-
- `openai/<model>` plus `agents.defaults.agentRuntime.id: "codex"` uses the native Codex app-server harness. This is the usual ChatGPT/Codex subscription setup.
33-
- `openai-codex/<model>` uses Codex OAuth in PI.
34-
- `openai/<model>` without a Codex runtime override uses the direct OpenAI API-key provider in PI.
32+
- `openai/<model>` uses the native Codex app-server harness for agent turns by default. This is the usual ChatGPT/Codex subscription setup.
33+
- `openai-codex/<model>` is legacy config that doctor rewrites to `openai/<model>`.
34+
- `openai/<model>` plus provider/model `agentRuntime.id: "pi"` uses PI for explicit API-key or compatibility routes.
3535

3636
See [OpenAI](/providers/openai) and [Codex harness](/plugins/codex-harness). If the provider/runtime split is confusing, read [Agent runtimes](/concepts/agent-runtimes) first.
3737

38-
Plugin auto-enable follows the same boundary: `openai-codex/<model>` belongs to the OpenAI plugin, while the Codex plugin is enabled by `agentRuntime.id: "codex"` or legacy `codex/<model>` refs.
38+
Plugin auto-enable follows the same boundary: `openai/*` agent refs enable the Codex plugin for the default route, and explicit provider/model `agentRuntime.id: "codex"` or legacy `codex/<model>` refs also require it.
3939

40-
GPT-5.5 is available through the native Codex app-server harness when `agentRuntime.id: "codex"` is set, through `openai-codex/gpt-5.5` in PI for Codex OAuth, and through `openai/gpt-5.5` in PI for direct API-key traffic when your account exposes it.
40+
GPT-5.5 is available through the native Codex app-server harness by default on `openai/gpt-5.5`, and through PI only when provider/model runtime policy explicitly selects `pi`.
4141

4242
</Accordion>
4343
<Accordion title="CLI runtimes">
44-
CLI runtimes use the same split: choose canonical model refs such as `anthropic/claude-*`, `google/gemini-*`, or `openai/gpt-*`, then set `agents.defaults.agentRuntime.id` to `claude-cli`, `google-gemini-cli`, or `codex-cli` when you want a local CLI backend.
44+
CLI runtimes use the same split: choose canonical model refs such as `anthropic/claude-*`, `google/gemini-*`, or `openai/gpt-*`, then set provider/model runtime policy to `claude-cli`, `google-gemini-cli`, or `codex-cli` when you want a local CLI backend.
4545

4646
Legacy `claude-cli/*`, `google-gemini-cli/*`, and `codex-cli/*` refs migrate back to canonical provider refs with the runtime recorded separately.
4747

@@ -118,7 +118,7 @@ OpenClaw ships with the pi-ai catalog. These providers require **no** `models.pr
118118
- Direct public Anthropic requests support the shared `/fast` toggle and `params.fastMode`, including API-key and OAuth-authenticated traffic sent to `api.anthropic.com`; OpenClaw maps that to Anthropic `service_tier` (`auto` vs `standard_only`)
119119
- Preferred Claude CLI config keeps the model ref canonical and selects the CLI
120120
backend separately: `anthropic/claude-opus-4-7` with
121-
`agents.defaults.agentRuntime.id: "claude-cli"`. Legacy
121+
model-scoped `agentRuntime.id: "claude-cli"`. Legacy
122122
`claude-cli/claude-opus-4-7` refs still work for compatibility.
123123

124124
<Note>
@@ -135,8 +135,8 @@ Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so Ope
135135

136136
- Provider: `openai-codex`
137137
- Auth: OAuth (ChatGPT)
138-
- PI model ref: `openai-codex/gpt-5.5`
139-
- Native Codex app-server harness ref: `openai/gpt-5.5` with `agents.defaults.agentRuntime.id: "codex"`
138+
- Legacy PI model ref: `openai-codex/gpt-5.5`
139+
- Native Codex app-server harness ref: `openai/gpt-5.5`
140140
- Native Codex app-server harness docs: [Codex harness](/plugins/codex-harness)
141141
- Legacy model refs: `codex/gpt-*`
142142
- Plugin boundary: `openai-codex/*` loads the OpenAI plugin; the native Codex app-server plugin is selected only by the Codex harness runtime or legacy `codex/*` refs.
@@ -148,8 +148,8 @@ Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so Ope
148148
- Shares the same `/fast` toggle and `params.fastMode` config as direct `openai/*`; OpenClaw maps that to `service_tier=priority`
149149
- `openai-codex/gpt-5.5` uses the Codex catalog native `contextWindow = 400000` and default runtime `contextTokens = 272000`; override the runtime cap with `models.providers.openai-codex.models[].contextTokens`
150150
- Policy note: OpenAI Codex OAuth is explicitly supported for external tools/workflows like OpenClaw.
151-
- For the common subscription plus native Codex runtime route, sign in with `openai-codex` auth but configure `openai/gpt-5.5` plus `agents.defaults.agentRuntime.id: "codex"`.
152-
- Use `openai-codex/gpt-5.5` only when you want the Codex OAuth/subscription route through PI; use `openai/gpt-5.5` without the Codex runtime override when your API-key setup and local catalog expose the public API route.
151+
- For the common subscription plus native Codex runtime route, sign in with `openai-codex` auth but configure `openai/gpt-5.5`; OpenAI agent turns select Codex by default.
152+
- Use provider/model `agentRuntime.id: "pi"` only when you want a compatibility route through PI; otherwise keep `openai/gpt-5.5` on the default Codex harness.
153153
- Older `openai-codex/gpt-5.1*`, `openai-codex/gpt-5.2*`, and `openai-codex/gpt-5.3*` refs are suppressed because ChatGPT/Codex OAuth accounts reject them; use `openai-codex/gpt-5.5` or the native Codex runtime route instead.
154154

155155
```json5
@@ -158,7 +158,6 @@ Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so Ope
158158
agents: {
159159
defaults: {
160160
model: { primary: "openai/gpt-5.5" },
161-
agentRuntime: { id: "codex" },
162161
},
163162
},
164163
}

docs/concepts/models.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ sidebarTitle: "Models CLI"
2323
</Card>
2424
</CardGroup>
2525

26-
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. For example, `openai/gpt-5.5` can run through the normal OpenAI provider path or through the Codex app-server runtime, depending on `agents.defaults.agentRuntime.id`. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai-codex` auth profile. See [Agent runtimes](/concepts/agent-runtimes).
26+
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. OpenAI agent refs are the main exception: `openai/gpt-5.5` runs through the Codex app-server runtime by default on the official OpenAI provider. Explicit runtime overrides belong on provider/model policy, not on the whole agent or session. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai-codex` auth profile. See [Agent runtimes](/concepts/agent-runtimes).
2727

2828
## How model selection works
2929

0 commit comments

Comments
 (0)