From 8fb8d08eafb8b985a39baf66f39167afd63450d2 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Thu, 5 Mar 2026 23:42:16 -0500 Subject: [PATCH] Tests: cover GPT-5.4 raw registry fallbacks --- src/agents/context.lookup.test.ts | 31 ++++++++++++++++++++++++ src/commands/models.list.e2e.test.ts | 36 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/agents/context.lookup.test.ts b/src/agents/context.lookup.test.ts index 81263481c34..884f83ef9ae 100644 --- a/src/agents/context.lookup.test.ts +++ b/src/agents/context.lookup.test.ts @@ -34,6 +34,37 @@ describe("lookupContextTokens", () => { expect(lookupContextTokens("openrouter/claude-sonnet")).toBe(321_000); }); + it("adds GPT-5.4 context windows from forward-compat discovery fallbacks", async () => { + vi.doMock("../config/config.js", () => ({ + loadConfig: () => ({ + models: { providers: {} }, + }), + })); + vi.doMock("./models-config.js", () => ({ + ensureOpenClawModelsJson: vi.fn(async () => {}), + })); + vi.doMock("./agent-paths.js", () => ({ + resolveOpenClawAgentDir: () => "/tmp/openclaw-agent", + })); + vi.doMock("./pi-model-discovery.js", () => ({ + discoverAuthStorage: vi.fn(() => ({})), + discoverModels: vi.fn(() => ({ + getAll: () => [ + { + provider: "openai", + id: "gpt-5.2", + contextWindow: 400_000, + }, + ], + })), + })); + + const { lookupContextTokens } = await import("./context.js"); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(lookupContextTokens("gpt-5.4")).toBe(1_050_000); + expect(lookupContextTokens("gpt-5.4-pro")).toBe(1_050_000); + }); + it("does not skip eager warmup when --profile is followed by -- terminator", async () => { const loadConfigMock = vi.fn(() => ({ models: {} })); vi.doMock("../config/config.js", () => ({ diff --git a/src/commands/models.list.e2e.test.ts b/src/commands/models.list.e2e.test.ts index 1469effeff1..9bbda294f64 100644 --- a/src/commands/models.list.e2e.test.ts +++ b/src/commands/models.list.e2e.test.ts @@ -264,6 +264,42 @@ describe("models list/status", () => { expect(payload.models[0]?.available).toBe(false); }); + it("loadModelRegistry augments raw OpenAI models with GPT-5.4 fallbacks", async () => { + modelRegistryState.models = [ + { + provider: "openai", + id: "gpt-5.2", + name: "GPT-5.2", + api: "openai-responses", + input: ["text", "image"], + baseUrl: "https://api.openai.com/v1", + contextWindow: 400_000, + maxTokens: 128_000, + reasoning: true, + cost: { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 }, + }, + ]; + modelRegistryState.available = modelRegistryState.models; + + const { models } = await loadModelRegistry({}); + expect(models).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + provider: "openai", + id: "gpt-5.4", + api: "openai-responses", + contextWindow: 1_050_000, + }), + expect.objectContaining({ + provider: "openai", + id: "gpt-5.4-pro", + api: "openai-responses", + contextWindow: 1_050_000, + }), + ]), + ); + }); + it("models list does not treat availability-unavailable code as discovery fallback", async () => { configureGoogleAntigravityModel("claude-opus-4-6-thinking"); modelRegistryState.getAllError = Object.assign(new Error("model discovery failed"), {