From 164094b6646323cb589eabdaf5124fb7e9ef9e11 Mon Sep 17 00:00:00 2001 From: luvs01 <27862058+luvs01@users.noreply.github.com> Date: Mon, 10 Aug 2026 03:13:55 +0900 Subject: [PATCH] fix(codex-catalog): preserve native fallback without catalog --- src/codex/catalog/metadata.ts | 10 +++++++--- tests/codex-catalog-sync-hardening.test.ts | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/codex/catalog/metadata.ts b/src/codex/catalog/metadata.ts index c5550bf373..80ba299fc0 100644 --- a/src/codex/catalog/metadata.ts +++ b/src/codex/catalog/metadata.ts @@ -253,11 +253,11 @@ export function shouldUpgradeToUpstreamEntry(entry: RawEntry): boolean { } export function nativeOpenAiSlugs(): string[] { - const live = listCatalogNativeSlugs(); + const live = catalogNativeSlugs(); return live.length > 0 ? unique([...live, ...DOCUMENTED_NATIVE_OPENAI_ADDITIONS]) : NATIVE_OPENAI_MODELS; } -export function listCatalogNativeSlugs(): string[] { +function catalogNativeSlugs(): string[] { const cat = readCurrentCatalogOrCache(); const models = cat?.models ?? []; const live = models.flatMap(entry => { @@ -271,7 +271,11 @@ export function listCatalogNativeSlugs(): string[] { // Deliberately ignore `visibility`: it is a rendered projection of disabledModels and account // selectors, so treating it as fresh availability would shrink the supported set between syncs. // visibleNativeSlugs applies the current disabledModels source of truth for public consumers. + return unique([...live, ...accountBound]); +} + +export function listCatalogNativeSlugs(): string[] { // Ensure documented additions (e.g. gpt-5.3-codex-spark) appear even when the bundled catalog // predates the slug — mirrors nativeOpenAiSlugs() which already merges them for /v1/models. - return unique([...live, ...accountBound, ...DOCUMENTED_NATIVE_OPENAI_ADDITIONS]); + return unique([...catalogNativeSlugs(), ...DOCUMENTED_NATIVE_OPENAI_ADDITIONS]); } diff --git a/tests/codex-catalog-sync-hardening.test.ts b/tests/codex-catalog-sync-hardening.test.ts index 4a1bf62a90..b0487a26ca 100644 --- a/tests/codex-catalog-sync-hardening.test.ts +++ b/tests/codex-catalog-sync-hardening.test.ts @@ -479,6 +479,23 @@ describe("Codex catalog sync hardening", () => { expect(rows.some(row => row.slug.startsWith("team/"))).toBe(false); }); + test("native model fallback remains reachable without a live catalog", () => { + writeFileSync( + join(codexHome, "config.toml"), + 'model_catalog_json = "missing-catalog.json"\n', + "utf8", + ); + const r = runScript(codexHome, opencodexHome, ` + const { listCatalogNativeSlugs, nativeOpenAiSlugs, NATIVE_OPENAI_MODELS } = await import("./src/codex/catalog"); + console.log(JSON.stringify({ picker: listCatalogNativeSlugs(), native: nativeOpenAiSlugs(), fallback: NATIVE_OPENAI_MODELS })); + `); + + expect(r.status).toBe(0); + const result = JSON.parse(r.stdout) as { picker: string[]; native: string[]; fallback: string[] }; + expect(result.picker).toContain("gpt-5.3-codex-spark"); + expect(result.native).toEqual(result.fallback); + }); + test("account sync recovers supported natives that were hidden before selectors existed", () => { const catalogPath = join(codexHome, "catalog.json"); writeFileSync(join(codexHome, "config.toml"), 'model_catalog_json = "catalog.json"\n', "utf8");