Summary
Switching an active live session from a claude-cli live-backend (e.g. anthropic/opus) to a Codex-app-server model (codex/gpt-5.5, a custom OpenAI-Responses provider behind a local HTTP proxy) genuinely works — the Codex app-server starts, binds to the session, and streams tool calls. But two user-facing surfaces misreport it, making it look broken.
1. Misleading "not allowed; reverted" message
The first turns after /model codex/gpt-5.5 emit:
Model override codex/gpt-5.5 is not allowed for this agent; reverted to <fallback>.
Add codex/gpt-5.5 to agents.defaults.models or pick an allowed model with /model list.
The model is allowed:
- the agent has no own allow-list; it inherits
agents.defaults.models, which contains codex/gpt-5.5;
- building OpenClaw's own visibility policy on the live config returns
allowsKey('codex/gpt-5.5') === true.
So the "add to agents.defaults.models" hint is wrong. The real trigger is a transient runtime/cold-start failure of the Codex app-server on its first handshake, surfaced to the user as an allow-list rejection. Once the app-server completes one successful handshake, the switch holds.
2. /status misreports the active runtime
While the Codex runtime is actually active, /status shows:
🧠 Model: anthropic/claude-opus-4-8 (default)
⚙️ Runtime: OpenClaw Default
Cause: /status reads persisted sessionEntry fields (model, modelProvider) and liveModelSwitchPending stays true. The live model switch is applied per-turn at runtime but is never consolidated back into the persisted fields that /status reads (agent-runtime-label, status-text resolveStatusHarnessId). So the status card lags the actual active harness — showing the persisted base model + OpenClaw Default instead of the running Codex runtime.
Proof it actually runs (not /status, not log-parsing)
The harness writes <sessionId>.jsonl.codex-app-server.json only when it really starts a Codex app-server for that session. For the affected session this file exists with model: gpt-5.5, modelProvider: "wire", authProfileId: openai-codex:default, bound to the session's threadId. If the switch hadn't engaged, this runtime-state file wouldn't exist.
Note for anyone diagnosing: successful Codex /responses calls (200) are not logged by the local proxy (only WARN/errors), so the proxy log can look "empty of codex" even when the runtime is working fine — easy to misdiagnose as "codex never ran".
Expected
- No false "not allowed" — surface the real cause (runtime start / cold-start failure), not an allow-list rejection, when the model is actually allowed.
/status runtime + model should reflect the active live-switched harness (or at least flag that a live switch is pending / runtime differs from the persisted snapshot).
Environment
- OpenClaw 2026.6.10 (aa69b12)
- Codex CLI 0.141.0
- Main runtime: anthropic via
claude-cli live-session backend; target: Codex app-server via a custom OpenAI-Responses provider over a local HTTP proxy.
Related
Summary
Switching an active live session from a
claude-clilive-backend (e.g. anthropic/opus) to a Codex-app-server model (codex/gpt-5.5, a custom OpenAI-Responses provider behind a local HTTP proxy) genuinely works — the Codex app-server starts, binds to the session, and streams tool calls. But two user-facing surfaces misreport it, making it look broken.1. Misleading "not allowed; reverted" message
The first turns after
/model codex/gpt-5.5emit:The model is allowed:
agents.defaults.models, which containscodex/gpt-5.5;allowsKey('codex/gpt-5.5') === true.So the "add to agents.defaults.models" hint is wrong. The real trigger is a transient runtime/cold-start failure of the Codex app-server on its first handshake, surfaced to the user as an allow-list rejection. Once the app-server completes one successful handshake, the switch holds.
2.
/statusmisreports the active runtimeWhile the Codex runtime is actually active,
/statusshows:Cause:
/statusreads persistedsessionEntryfields (model,modelProvider) andliveModelSwitchPendingstaystrue. The live model switch is applied per-turn at runtime but is never consolidated back into the persisted fields that/statusreads (agent-runtime-label,status-textresolveStatusHarnessId). So the status card lags the actual active harness — showing the persisted base model +OpenClaw Defaultinstead of the running Codex runtime.Proof it actually runs (not
/status, not log-parsing)The harness writes
<sessionId>.jsonl.codex-app-server.jsononly when it really starts a Codex app-server for that session. For the affected session this file exists withmodel: gpt-5.5,modelProvider: "wire",authProfileId: openai-codex:default, bound to the session's threadId. If the switch hadn't engaged, this runtime-state file wouldn't exist.Note for anyone diagnosing: successful Codex
/responsescalls (200) are not logged by the local proxy (only WARN/errors), so the proxy log can look "empty of codex" even when the runtime is working fine — easy to misdiagnose as "codex never ran".Expected
/statusruntime + model should reflect the active live-switched harness (or at least flag that a live switch is pending / runtime differs from the persisted snapshot).Environment
claude-clilive-session backend; target: Codex app-server via a custom OpenAI-Responses provider over a local HTTP proxy.Related
AgentSession.this.modelsnapshot not refreshed after/model(related session-snapshot staleness, different reads)./statususage should follow session-selected model after/model./model <default>silently fails when a different model is running.