From 3666fa68251ee74cdd70a244b4df0085ff709c5e Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 18 Aug 2026 19:47:31 -0700 Subject: [PATCH] fix(config): clone catalog metadata before defaults (#126123) * fix(config): clone catalog metadata before defaults * refactor(config): keep catalog clone net neutral --- src/config/defaults.test.ts | 50 +++++++++++++++++++++++++++++++++++++ src/config/defaults.ts | 2 +- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/config/defaults.test.ts b/src/config/defaults.test.ts index a7bfcbf9486f..3f493a907883 100644 --- a/src/config/defaults.test.ts +++ b/src/config/defaults.test.ts @@ -310,6 +310,56 @@ describe("applyModelDefaults catalog seeding", () => { expect(model.input).toEqual(["text", "image"]); }); + it("copies frozen catalog metadata before downstream normalization", async () => { + const supportedReasoningEfforts = Object.freeze(["low", "high"]); + const compat = Object.freeze({ supportedReasoningEfforts }); + const frozenRegistry = { + plugins: [ + { + id: "openai", + modelCatalog: { + providers: { + openai: { + models: [ + Object.freeze({ + id: "gpt-5.6-sol", + name: "GPT-5.6 Sol", + reasoning: true, + compat, + }), + ], + }, + }, + }, + }, + ], + // SAFETY: minimal frozen manifest record reproducing production registry ownership. + } as never; + const { applyModelDefaults } = await import("./defaults.js"); + const cfg = applyModelDefaults( + { + models: { + providers: { + openai: { + baseUrl: "https://api.openai.com/v1", + models: [{ id: "gpt-5.6-sol", name: "GPT-5.6" } as never], + }, + }, + }, + }, + { manifestRegistry: frozenRegistry }, + ); + const model = expectDefined( + cfg.models?.providers?.openai?.models?.[0], + "materialized model entry", + ); + + expect(() => { + model.compat!.supportedReasoningEfforts = ["low"]; + }).not.toThrow(); + expect(compat.supportedReasoningEfforts).toEqual(["low", "high"]); + }); + it("falls back to generic defaults when no catalog row matches", async () => { const { applyModelDefaults } = await import("./defaults.js"); const cfg = applyModelDefaults( diff --git a/src/config/defaults.ts b/src/config/defaults.ts index f4cd93b4306e..3984a122a3fd 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -206,7 +206,7 @@ function buildManifestCatalogModelLookup( } } } - return index.get(keyFor(providerId, modelId)); + return structuredClone(index.get(keyFor(providerId, modelId))); }; }