fix(sdk): fix ChatGPT provider models (#10836)

* fix(sdk): restore ChatGPT subscription models

* fix(sdk): tighten ChatGPT provider model tests
This commit is contained in:
Saoud Rizwan
2026-05-17 16:26:38 -07:00
committed by GitHub
parent acca9186f1
commit 2b2fa8a473
6 changed files with 77 additions and 17 deletions
@@ -79,18 +79,38 @@ describe("resolveProviderConfig", () => {
it("does not expose generic OpenAI models for OpenAI Codex OAuth fallback", async () => {
const resolved = await resolveProviderConfig("openai-codex");
const modelIds = Object.keys(resolved?.knownModels ?? {});
const additionalOAuthModelIds = new Set([
"gpt-5.2",
"gpt-5.4",
"gpt-5.4-mini",
]);
expect(modelIds).toEqual(
expect.arrayContaining([
"gpt-5.1-codex-max",
"gpt-5.3-codex",
"gpt-5.4",
"gpt-5.4-mini",
]),
);
expect(
modelIds.every(
(id) => id.includes("codex") || additionalOAuthModelIds.has(id),
),
).toBe(true);
expect(resolved?.knownModels?.["gpt-5.4"]).toBeDefined();
expect(resolved?.knownModels?.["gpt-5.4-nano"]).toBeUndefined();
});
it("uses OpenAI Codex account models as the authoritative authenticated list", async () => {
it("merges OpenAI Codex account models into the ChatGPT OAuth fallback list", async () => {
const listModels = vi
.spyOn(Llms, "listOpenAICodexModels")
.mockResolvedValue([
{ id: "gpt-5.3-codex", name: "GPT-5.3 Codex" },
{ id: "gpt-5.4", name: "GPT-5.4" },
{ id: "gpt-5.4-mini", name: "gpt-5.4-mini" },
{ id: "account-only-codex", name: "Account Only Codex" },
]);
const resolved = await resolveProviderConfig(
@@ -110,11 +130,16 @@ describe("resolveProviderConfig", () => {
accountId: "acct_123",
}),
);
expect(Object.keys(resolved?.knownModels ?? {}).sort()).toEqual([
"gpt-5.3-codex",
"gpt-5.4",
"gpt-5.4-mini",
]);
expect(Object.keys(resolved?.knownModels ?? {})).toEqual(
expect.arrayContaining([
"account-only-codex",
"gpt-5.1-codex-max",
"gpt-5.2",
"gpt-5.3-codex",
"gpt-5.4",
"gpt-5.4-mini",
]),
);
expect(resolved?.knownModels?.["gpt-5.4-mini"]).toEqual(
expect.objectContaining({
name: "gpt-5.4-mini",
@@ -172,10 +172,12 @@ async function mergeKnownModels(
...userKnownModels,
});
}
const privateHasResults = Object.keys(privateModels).length > 0;
if (providerId === "openai-codex" && privateHasResults) {
if (providerId === "openai-codex") {
return Llms.sortModelsByReleaseDate({
...defaultKnownModels,
...liveModels,
...privateModels,
...publicModels,
...userKnownModels,
});
}
@@ -63,7 +63,31 @@ describe("built-in provider metadata", () => {
it("enriches OpenAI Codex fallback models from the generated OpenAI catalog", async () => {
const models = await getModelsForProvider("openai-codex");
const modelIds = Object.keys(models);
const additionalOAuthModelIds = new Set([
"gpt-5.2",
"gpt-5.4",
"gpt-5.4-mini",
]);
expect(modelIds).toEqual(
expect.arrayContaining([
"gpt-5.1-codex-max",
"gpt-5.3-codex",
"gpt-5.4",
"gpt-5.4-mini",
]),
);
expect(
modelIds.every(
(id) => id.includes("codex") || additionalOAuthModelIds.has(id),
),
).toBe(true);
expect(modelIds.filter((id) => !id.includes("codex")).sort()).toEqual([
"gpt-5.2",
"gpt-5.4",
"gpt-5.4-mini",
]);
expect(models["gpt-5.4"]).toEqual(
expect.objectContaining({
name: "GPT-5.4",
@@ -78,5 +102,6 @@ describe("built-in provider metadata", () => {
contextWindow: expect.any(Number),
}),
);
expect(models["gpt-5.4-nano"]).toBeUndefined();
});
});
+7 -1
View File
@@ -132,7 +132,13 @@ function buildClaudeCodeModels(): Record<string, ModelInfo> {
function buildOpenAICodexModels(): Record<string, ModelInfo> {
const openaiModels = generatedModels("openai-native");
const fallbackIds = ["gpt-5.4", "gpt-5.3-codex"];
const additionalOAuthModelIds = ["gpt-5.2", "gpt-5.4", "gpt-5.4-mini"];
const fallbackIds = Array.from(
new Set([
...Object.keys(openaiModels).filter((id) => id.includes("codex")),
...additionalOAuthModelIds,
]),
);
return Object.fromEntries(
fallbackIds.map((id) => [
id,
+7 -7
View File
@@ -22,15 +22,15 @@ describe("listOpenAICodexModels", () => {
closeSpy.mockResolvedValue(undefined);
});
it("uses the codex executable on PATH by default", async () => {
it("lets the provider resolve its bundled Codex CLI by default", async () => {
await listOpenAICodexModels();
expect(createCodexAppServerSpy).toHaveBeenCalledWith(
expect.objectContaining({
defaultSettings: expect.objectContaining({
codexPath: "codex",
}),
}),
const options = createCodexAppServerSpy.mock.calls[0]?.[0] as
| { defaultSettings?: Record<string, unknown> }
| undefined;
expect(options?.defaultSettings).toBeDefined();
expect(Object.hasOwn(options?.defaultSettings ?? {}, "codexPath")).toBe(
false,
);
expect(listModelsSpy).toHaveBeenCalledWith(["openai"]);
expect(closeSpy).toHaveBeenCalled();
+3 -1
View File
@@ -63,7 +63,9 @@ export async function listOpenAICodexModels(
: undefined;
const provider = createCodexAppServer({
defaultSettings: {
codexPath: options.codexPath ?? "codex",
...(options.codexPath !== undefined
? { codexPath: options.codexPath }
: {}),
cwd: options.cwd,
env: options.env,
logger: false,