From 27e16944808cf43210d4505993c9846fdd7309e4 Mon Sep 17 00:00:00 2001 From: "Kai (Tam Nhu) Tran" <61256810+kaitranntt@users.noreply.github.com> Date: Sat, 30 May 2026 14:57:04 -0400 Subject: [PATCH] fix(cliproxy): prefer explicit Codex free fallbacks --- .../__tests__/codex-plan-compatibility.test.ts | 15 +++++++++++++++ .../ai-providers/codex-plan-compatibility.ts | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/cliproxy/ai-providers/__tests__/codex-plan-compatibility.test.ts b/src/cliproxy/ai-providers/__tests__/codex-plan-compatibility.test.ts index 28201039..45548c1d 100644 --- a/src/cliproxy/ai-providers/__tests__/codex-plan-compatibility.test.ts +++ b/src/cliproxy/ai-providers/__tests__/codex-plan-compatibility.test.ts @@ -78,6 +78,21 @@ describe('codex plan compatibility', () => { ).toBe('gpt-5.4-mini'); }); + it('prefers a rejected model explicit free-plan fallback over saved paid-only models', () => { + expect( + resolveRuntimeCodexFallbackModel({ + requestedModel: 'gpt-5.3-codex-spark', + modelMap: { + defaultModel: 'gpt-5.3-codex', + opusModel: 'gpt-5.3-codex', + sonnetModel: 'gpt-5.3-codex', + haikuModel: 'gpt-5.3-codex-spark', + }, + excludeModels: ['gpt-5.3-codex-spark'], + }) + ).toBe('gpt-5.4-mini'); + }); + it('tracks Codex thinking caps for current safe defaults, paid models, and legacy aliases', () => { expect(getModelMaxLevel('codex', 'gpt-5.5')).toBe('xhigh'); expect(getModelMaxLevel('codex', 'gpt-5.4')).toBe('xhigh'); diff --git a/src/cliproxy/ai-providers/codex-plan-compatibility.ts b/src/cliproxy/ai-providers/codex-plan-compatibility.ts index 291b396e..dad29a02 100644 --- a/src/cliproxy/ai-providers/codex-plan-compatibility.ts +++ b/src/cliproxy/ai-providers/codex-plan-compatibility.ts @@ -114,8 +114,8 @@ export function resolveRuntimeCodexFallbackModel(options: { (options.excludeModels ?? []).map((model) => normalizeCodexModelId(model)).filter(Boolean) ); const candidates = [ - options.modelMap.defaultModel, getFreePlanFallbackCodexModel(requestedModel), + options.modelMap.defaultModel, options.modelMap.opusModel, options.modelMap.sonnetModel, options.modelMap.haikuModel,