Skip to content

Commit 6952ea7

Browse files
nxmxbbdnex-dh
andcommitted
fix(doctor): preserve explicit non-default agentRuntime pin during legacy model-ref migration
`maybeRepairCodexRoutes` migrates `openai-codex/*` model refs to their canonical `openai/*` form, then calls `ensureCodexRuntimePolicy` on each hit so the rewritten ref keeps Codex auth routing. When the user already had an explicit non-default pin on the legacy form (for example `models["openai-codex/gpt-5.4"].agentRuntime = { id: "pi" }` as a deliberate opt-out from the broken native Codex runtime), the previous sequence silently overwrote it: 1. The `AGENT_MODEL_CONFIG_KEYS` loop rewrote `model.primary`, then `preserveCodexRuntimePolicyForNewHits` synthesized `models["openai/gpt-5.4"].agentRuntime = { id: "codex" }` because that canonical entry did not yet exist. 2. `rewriteModelsMap` then renamed `openai-codex/gpt-5.4` → `openai/gpt-5.4`. Its spread merge `{ ...legacyRecord, ...canonicalRecord }` placed the synthesized `{ id: "codex" }` last, silently dropping the user's `{ id: "pi" }` pin. End state: the explicit PI runtime opt-out was gone, gateway fell back to the native Codex runtime, and per-request token usage grew 3-4x because the upstream Codex runtime issue still applies. Fix: in `ensureCodexRuntimePolicy`, skip synthesizing the default `{ id: "codex" }` pin when the user already has an explicit non-default pin on a legacy `openai-codex/*` form of the same canonical model ref. `rewriteModelsMap` then carries the legacy pin forward unmodified via its existing `canonicalEntry ?? legacyEntry` falsy branch. This narrow fix matches the existing behavior covered by `preserves explicit model-scoped runtime pins when repairing legacy model map keys` (only the models map, no `model.primary` slot to trigger synthesis) and `overwrites non-concrete model-scoped runtime pins when preserving Codex route intent` (auto/default pins still get codex applied). The combined-config path from #84038 was the previously uncovered regression. Fixes #84038. Co-Authored-By: Nex <nex@dbitstec.com>
1 parent 4133c58 commit 6952ea7

1 file changed

Lines changed: 24 additions & 0 deletions

File tree

src/commands/doctor/shared/codex-route-warnings.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,27 @@ function maybeMigrateLegacyLosslessCompactionConfig(params: {
19971997
return changes;
19981998
}
19991999

2000+
function legacyEntryHasExplicitNonDefaultRuntimePin(
2001+
models: MutableRecord,
2002+
canonicalModelRef: string,
2003+
): boolean {
2004+
for (const ref of Object.keys(models)) {
2005+
if (ref === canonicalModelRef) {
2006+
continue;
2007+
}
2008+
if (toCanonicalOpenAIModelRef(ref) !== canonicalModelRef) {
2009+
continue;
2010+
}
2011+
const legacyEntry = asMutableRecord(models[ref]);
2012+
const legacyRuntime = asMutableRecord(legacyEntry?.agentRuntime);
2013+
const id = normalizeString(legacyRuntime?.id);
2014+
if (id && id !== "auto" && id !== "default") {
2015+
return true;
2016+
}
2017+
}
2018+
return false;
2019+
}
2020+
20002021
function ensureCodexRuntimePolicy(params: {
20012022
cfg: OpenClawConfig;
20022023
agent: MutableRecord;
@@ -2025,6 +2046,9 @@ function ensureCodexRuntimePolicy(params: {
20252046
if (runtimeId && runtimeId !== "auto" && runtimeId !== "default") {
20262047
return;
20272048
}
2049+
if (legacyEntryHasExplicitNonDefaultRuntimePin(models, params.modelRef)) {
2050+
return;
2051+
}
20282052
setModelRuntimePolicy({
20292053
agent: params.agent,
20302054
agentPath: params.agentPath,

0 commit comments

Comments
 (0)