Skip to content

Commit 75b903a

Browse files
authored
Merge pull request lidge-jun#833 from lidge-jun/agent/fix-codex-auto-review-routing-816
fix(router): pin Codex auto review to OpenAI
2 parents 0d6eed2 + 514b91e commit 75b903a

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

src/router.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,13 @@ export class NoEnabledOpenAiProviderError extends Error {
306306
}
307307
}
308308

309+
// Codex uses a small number of control-plane model ids that are not part of the public GPT/o
310+
// naming families. Keep this exact: a broad `codex-*` rule could capture a third-party model.
311+
const CODEX_INTERNAL_OPENAI_MODELS = new Set(["codex-auto-review"]);
312+
309313
function isBareOpenAiFamilyModel(modelId: string): boolean {
310-
return !modelId.includes("/") && /^(?:gpt-|o1-|o3-|o4-)/.test(modelId);
314+
return !modelId.includes("/")
315+
&& (/^(?:gpt-|o1-|o3-|o4-)/.test(modelId) || CODEX_INTERNAL_OPENAI_MODELS.has(modelId));
311316
}
312317

313318
function routeResult(providerName: string, provider: OcxProviderConfig, modelId: string): RouteResult {

tests/router.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,42 @@ describe("routeModel registry effort defaults", () => {
139139
},
140140
};
141141
expect(routeModel(base, "gpt-5.5")).toMatchObject({ providerName: "openai", codexAccountMode: "pool" });
142+
expect(routeModel(base, "codex-auto-review")).toMatchObject({
143+
providerName: "openai",
144+
modelId: "codex-auto-review",
145+
codexAccountMode: "pool",
146+
});
147+
expect(routeModel(base, "codex-third-party-model")).toMatchObject({
148+
providerName: "openai-apikey",
149+
modelId: "codex-third-party-model",
150+
});
151+
const withDeepSeekDefault: OcxConfig = {
152+
...base,
153+
defaultProvider: "deepseek",
154+
providers: {
155+
...base.providers,
156+
deepseek: {
157+
adapter: "openai-chat",
158+
baseUrl: "https://api.deepseek.com/v1",
159+
defaultModel: "deepseek-chat",
160+
},
161+
},
162+
};
163+
expect(routeModel(withDeepSeekDefault, "codex-auto-review")).toMatchObject({
164+
providerName: "openai",
165+
modelId: "codex-auto-review",
166+
});
167+
expect(routeModel(withDeepSeekDefault, "codex-third-party-model")).toMatchObject({
168+
providerName: "deepseek",
169+
modelId: "codex-third-party-model",
170+
});
142171
expect(routeModel({ ...base, providers: { ...base.providers, openai: { ...forward, codexAccountMode: "direct" } } }, "gpt-5.5"))
143172
.toMatchObject({ providerName: "openai", codexAccountMode: "direct" });
144173
expect(() => routeModel({ ...base, providers: { ...base.providers, openai: { ...forward, disabled: true } } }, "gpt-5.5"))
145174
.toThrow(/requires the canonical openai provider/);
146175
const unavailable = { ...base, providers: { "openai-proxy": base.providers["openai-proxy"] } };
147176
expect(() => routeModel(unavailable, "gpt-5.5")).toThrow(/ocx provider add openai/);
177+
expect(() => routeModel(unavailable, "codex-auto-review")).toThrow(NoEnabledOpenAiProviderError);
148178
});
149179

150180
test("rejects legacy chatgpt namespaces even when configured", () => {

0 commit comments

Comments
 (0)