fix: repair providerless Codex session overrides

Co-authored-by: Earl Vanze <earlvanze@gmail.com>
This commit is contained in:
Peter Steinberger
2026-05-31 21:45:39 +01:00
committed by GitHub
parent 90712f6d5e
commit ce1165afda
2 changed files with 116 additions and 1 deletions

View File

@@ -3776,6 +3776,80 @@ describe("collectCodexRouteWarnings", () => {
expect(store.main.agentRuntimeOverride).toBeUndefined();
});
it("repairs providerless auto Codex session overrides", () => {
const store: Record<string, SessionEntry> = {
main: {
sessionId: "s1",
updatedAt: 1,
modelProvider: "ollama",
model: "gpt-5.5",
modelOverride: "gpt-5.5",
modelOverrideSource: "auto",
authProfileOverride: "openai-codex:default",
authProfileOverrideSource: "auto",
contextTokens: 64_000,
contextBudgetStatus: {
schemaVersion: 1,
source: "pre-prompt-estimate",
updatedAt: 1,
provider: "ollama",
model: "gpt-5.5",
route: "fits",
shouldCompact: false,
estimatedPromptTokens: 1_000,
contextTokenBudget: 64_000,
promptBudgetBeforeReserve: 62_000,
reserveTokens: 2_000,
effectiveReserveTokens: 2_000,
remainingPromptBudgetTokens: 61_000,
overflowTokens: 0,
toolResultReducibleChars: 0,
messageCount: 1,
unwindowedMessageCount: 1,
},
},
};
const result = repairCodexSessionStoreRoutes({
store,
now: 123,
});
expect(result).toEqual({ changed: true, sessionKeys: ["main"] });
expect(store.main.updatedAt).toBe(123);
expect(store.main.providerOverride).toBe("openai");
expect(store.main.modelOverride).toBe("gpt-5.5");
expect(store.main.modelOverrideSource).toBe("auto");
expect(store.main.authProfileOverride).toBe("openai-codex:default");
expect(store.main.authProfileOverrideSource).toBe("auto");
expect(store.main.modelProvider).toBeUndefined();
expect(store.main.model).toBeUndefined();
expect(store.main.contextTokens).toBeUndefined();
expect(store.main.contextBudgetStatus).toBeUndefined();
});
it("preserves legacy providerless overrides with Codex auth pins", () => {
const store: Record<string, SessionEntry> = {
main: {
sessionId: "s1",
updatedAt: 1,
modelOverride: "gpt-5.5",
authProfileOverride: "openai-codex:default",
authProfileOverrideSource: "auto",
},
};
const result = repairCodexSessionStoreRoutes({
store,
now: 123,
});
expect(result).toEqual({ changed: false, sessionKeys: [] });
expect(store.main.updatedAt).toBe(1);
expect(store.main.providerOverride).toBeUndefined();
expect(store.main.modelOverride).toBe("gpt-5.5");
});
it("preserves canonical OpenAI sessions that are explicitly pinned to OpenClaw", () => {
const store: Record<string, SessionEntry> = {
main: {

View File

@@ -91,6 +91,15 @@ function isOpenAICodexModelRef(model: string | undefined): model is string {
return normalizeString(model)?.startsWith("openai-codex/") === true;
}
function isOpenAICodexAuthProfileRef(profile: unknown): boolean {
return normalizeString(profile)?.startsWith("openai-codex:") === true;
}
function isProviderlessModelRef(model: unknown): model is string {
const normalized = normalizeString(model);
return Boolean(normalized && !normalized.includes("/"));
}
function toCanonicalOpenAIModelRef(model: string): string | undefined {
if (!isOpenAICodexModelRef(model)) {
return undefined;
@@ -2918,6 +2927,31 @@ function clearStaleSessionRuntimePins(entry: SessionEntry): boolean {
return changed;
}
function repairProviderlessCodexSessionOverride(entry: SessionEntry): boolean {
if (
!isProviderlessModelRef(entry.modelOverride) ||
!isOpenAICodexAuthProfileRef(entry.authProfileOverride) ||
entry.authProfileOverrideSource !== "auto" ||
entry.modelOverrideSource !== "auto" ||
normalizeString(entry.providerOverride)
) {
return false;
}
entry.providerOverride = "openai";
if (entry.model !== undefined || entry.modelProvider !== undefined) {
delete entry.model;
delete entry.modelProvider;
}
if (entry.contextTokens !== undefined) {
delete entry.contextTokens;
}
if (entry.contextBudgetStatus !== undefined) {
delete entry.contextBudgetStatus;
}
return true;
}
export function repairCodexSessionStoreRoutes(params: {
store: Record<string, SessionEntry>;
now?: number;
@@ -2938,7 +2972,9 @@ export function repairCodexSessionStoreRoutes(params: {
providerKey: "providerOverride",
modelKey: "modelOverride",
});
const changedModelRoute = changedRuntimeModelRoute || changedOverrideModelRoute;
const changedProviderlessOverride = repairProviderlessCodexSessionOverride(entry);
const changedModelRoute =
changedRuntimeModelRoute || changedOverrideModelRoute || changedProviderlessOverride;
const changedFallbackNotice = clearStaleCodexFallbackNotice(entry);
const changedRuntimePins =
changedModelRoute || changedFallbackNotice ? clearStaleSessionRuntimePins(entry) : false;
@@ -2964,6 +3000,11 @@ function scanCodexSessionStoreRoutes(store: Record<string, SessionEntry>): strin
normalizeString(entry.providerOverride) === "openai-codex" ||
isOpenAICodexModelRef(entry.model) ||
isOpenAICodexModelRef(entry.modelOverride) ||
(isProviderlessModelRef(entry.modelOverride) &&
isOpenAICodexAuthProfileRef(entry.authProfileOverride) &&
entry.authProfileOverrideSource === "auto" &&
entry.modelOverrideSource === "auto" &&
!normalizeString(entry.providerOverride)) ||
isOpenAICodexModelRef(entry.fallbackNoticeSelectedModel) ||
isOpenAICodexModelRef(entry.fallbackNoticeActiveModel);
return hasLegacyRoute ? [sessionKey] : [];