From cd5bc2fc93371b8a337d9b68188b0f58198a826f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 23 Apr 2026 20:00:51 +0100 Subject: [PATCH] test(openai): cover GPT-5.5 defaults --- .../openai/openai-codex-provider.test.ts | 54 ++++++++- .../openai/openai-provider.live.test.ts | 20 +++- extensions/openai/openai-provider.test.ts | 107 ++++++++++++++++++ extensions/openai/openai.live.test.ts | 4 +- .../provider-catalog.contract-test-support.ts | 6 +- extensions/qa-lab/src/character-eval.test.ts | 4 +- extensions/qa-lab/src/cli.runtime.test.ts | 10 +- .../qa-lab/src/model-catalog.runtime.test.ts | 8 +- .../src/model-selection.runtime.test.ts | 8 +- extensions/qa-lab/src/reply-failure.test.ts | 4 +- extensions/qa-lab/src/run-config.test.ts | 22 ++-- .../qa-lab/src/scenario-catalog.test.ts | 8 +- .../src/suite-runtime-transport.test.ts | 6 +- qa/frontier-harness-plan.md | 8 +- .../models/codex-harness-no-meta-leak.md | 6 +- .../gpt54-thinking-visibility-switch.md | 22 ++-- .../models/openai-native-web-search-live.md | 8 +- .../models/thinking-slash-model-remap.md | 8 +- .../medium-game-plan-codex-harness.md | 8 +- .../workspace/medium-game-plan-pi-harness.md | 10 +- src/agents/cli-backends.test.ts | 4 +- src/agents/model-auth.profiles.test.ts | 4 +- src/agents/model-compat.test.ts | 12 +- src/agents/models.profiles.live.test.ts | 2 +- .../pi-embedded-runner.cache.live.test.ts | 2 +- src/agents/pi-mcp-style.cache.live.test.ts | 2 +- src/agents/provider-headers.live.test.ts | 2 +- ...imple-completion-runtime.selection.test.ts | 4 +- .../reply/agent-runner-execution.test.ts | 4 +- .../reply/agent-runner-memory.test.ts | 2 +- src/commands/agent-command.test-mocks.ts | 4 +- src/commands/agent.acp.test.ts | 4 +- src/commands/auth-choice.test.ts | 2 +- ...re.gateway-auth.prompt-auth-config.test.ts | 4 +- .../doctor-cron-store-migration.test.ts | 4 +- src/commands/model-picker.test.ts | 50 ++++---- src/commands/models/auth.test.ts | 10 +- src/commands/models/list.configured.test.ts | 6 +- src/commands/models/list.rows.test.ts | 8 +- src/commands/models/list.status.test.ts | 4 +- .../onboard-auth.config-shared.test.ts | 4 +- src/commands/openai-model-default.test.ts | 2 +- src/commands/status-overview-rows.test.ts | 2 +- src/commands/status-overview-values.test.ts | 4 +- src/commands/status.summary.runtime.test.ts | 6 +- src/commands/status.summary.test.ts | 6 +- src/commands/status.test-support.ts | 4 +- src/gateway/gateway-acp-bind.live.test.ts | 2 +- .../gateway-cli-backend.live-helpers.test.ts | 2 +- .../gateway-models.profiles.live.test.ts | 2 +- .../chat.directive-tags.test.ts | 4 +- src/gateway/server-startup.test.ts | 2 +- src/media-understanding/defaults.test.ts | 2 +- src/plugins/config-state.test.ts | 4 +- .../provider-auth-choice-helpers.test.ts | 4 +- src/plugins/provider-runtime.test-support.ts | 16 ++- src/plugins/provider-runtime.test.ts | 2 +- src/plugins/status.test.ts | 8 +- .../trigger-handling-test-harness.ts | 4 +- test/helpers/plugins/plugin-runtime-mock.ts | 2 +- .../helpers/plugins/provider-auth-contract.ts | 4 +- test/helpers/plugins/provider-catalog.ts | 1 + .../plugins/provider-runtime-contract.ts | 56 +++++++++ ui/src/ui/views/agents-utils.test.ts | 8 +- ui/src/ui/views/config-quick.test.ts | 2 +- 65 files changed, 437 insertions(+), 181 deletions(-) diff --git a/extensions/openai/openai-codex-provider.test.ts b/extensions/openai/openai-codex-provider.test.ts index dac350406b9..66b5bf1c3d5 100644 --- a/extensions/openai/openai-codex-provider.test.ts +++ b/extensions/openai/openai-codex-provider.test.ts @@ -224,7 +224,7 @@ describe("openai codex provider", () => { }, }, ], - defaultModel: "openai-codex/gpt-5.4", + defaultModel: "openai-codex/gpt-5.5", }); expect(result?.profiles[0]?.credential).not.toHaveProperty("idToken"); expect(result?.profiles[0]?.credential).not.toHaveProperty("accountId"); @@ -329,6 +329,40 @@ describe("openai codex provider", () => { }); }); + it("resolves gpt-5.5 and gpt-5.5-pro with launch pricing and codex-sized runtime cap", () => { + const provider = buildOpenAICodexProviderPlugin(); + + const model = provider.resolveDynamicModel?.({ + provider: "openai-codex", + modelId: "gpt-5.5", + modelRegistry: createSingleModelRegistry(createCodexTemplate({ id: "gpt-5.4" })) as never, + }); + const pro = provider.resolveDynamicModel?.({ + provider: "openai-codex", + modelId: "gpt-5.5-pro", + modelRegistry: createSingleModelRegistry(createCodexTemplate({ id: "gpt-5.4-pro" })) as never, + }); + + expect(model).toMatchObject({ + id: "gpt-5.5", + api: "openai-codex-responses", + baseUrl: "https://chatgpt.com/backend-api", + contextWindow: 1_000_000, + contextTokens: 272_000, + maxTokens: 128_000, + cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 }, + }); + expect(pro).toMatchObject({ + id: "gpt-5.5-pro", + api: "openai-codex-responses", + baseUrl: "https://chatgpt.com/backend-api", + contextWindow: 1_000_000, + contextTokens: 272_000, + maxTokens: 128_000, + cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + }); + }); + it("resolves gpt-5.4-pro from a gpt-5.4 runtime template when legacy codex rows are absent", () => { const provider = buildOpenAICodexProviderPlugin(); @@ -398,7 +432,7 @@ describe("openai codex provider", () => { expect(model).not.toHaveProperty("contextTokens"); }); - it("augments catalog with gpt-5.4 native contextWindow and runtime cap", () => { + it("augments catalog with gpt-5.5 and gpt-5.4 native metadata", () => { const provider = buildOpenAICodexProviderPlugin(); const entries = provider.augmentModelCatalog?.({ @@ -415,6 +449,22 @@ describe("openai codex provider", () => { ], } as never); + expect(entries).toContainEqual( + expect.objectContaining({ + id: "gpt-5.5", + contextWindow: 1_000_000, + contextTokens: 272_000, + cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 }, + }), + ); + expect(entries).toContainEqual( + expect.objectContaining({ + id: "gpt-5.5-pro", + contextWindow: 1_000_000, + contextTokens: 272_000, + cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + }), + ); expect(entries).toContainEqual( expect.objectContaining({ id: "gpt-5.4", diff --git a/extensions/openai/openai-provider.live.test.ts b/extensions/openai/openai-provider.live.test.ts index a8a59ff4d9e..c2c7d6cf8d2 100644 --- a/extensions/openai/openai-provider.live.test.ts +++ b/extensions/openai/openai-provider.live.test.ts @@ -3,7 +3,7 @@ import { describe, expect, it } from "vitest"; import { buildOpenAIProvider } from "./openai-provider.js"; const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? ""; -const DEFAULT_LIVE_MODEL_IDS = ["gpt-5.4-mini", "gpt-5.4-nano"] as const; +const DEFAULT_LIVE_MODEL_IDS = ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4-nano"] as const; const liveEnabled = OPENAI_API_KEY.trim().length > 0 && process.env.OPENCLAW_LIVE_TEST === "1"; const describeLive = liveEnabled ? describe : describe.skip; @@ -18,6 +18,24 @@ type LiveModelCase = { function resolveLiveModelCase(modelId: string): LiveModelCase { switch (modelId) { + case "gpt-5.5": + return { + modelId, + templateId: "gpt-5.4", + templateName: "GPT-5.4", + cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 1_000_000, + maxTokens: 128_000, + }; + case "gpt-5.5-pro": + return { + modelId, + templateId: "gpt-5.4-pro", + templateName: "GPT-5.4 Pro", + cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 1_000_000, + maxTokens: 128_000, + }; case "gpt-5.4": return { modelId, diff --git a/extensions/openai/openai-provider.test.ts b/extensions/openai/openai-provider.test.ts index bd25c3684f1..869c7048a21 100644 --- a/extensions/openai/openai-provider.test.ts +++ b/extensions/openai/openai-provider.test.ts @@ -229,6 +229,101 @@ describe("buildOpenAIProvider", () => { }); }); + it("resolves gpt-5.5 and gpt-5.5-pro with launch metadata", () => { + const provider = buildOpenAIProvider(); + + const model = provider.resolveDynamicModel?.({ + provider: "openai", + modelId: "gpt-5.5", + modelRegistry: { + find: (_provider: string, id: string) => + id === "gpt-5.4" + ? { + id, + name: "GPT-5.4", + provider: "openai", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + reasoning: true, + input: ["text", "image"], + cost: { input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }, + contextWindow: 1_050_000, + maxTokens: 128_000, + } + : null, + } as never, + }); + const pro = provider.resolveDynamicModel?.({ + provider: "openai", + modelId: "gpt-5.5-pro", + modelRegistry: { + find: (_provider: string, id: string) => + id === "gpt-5.4-pro" + ? { + id, + name: "GPT-5.4 Pro", + provider: "openai", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + reasoning: true, + input: ["text", "image"], + cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 1_050_000, + maxTokens: 128_000, + } + : null, + } as never, + }); + + expect(model).toMatchObject({ + provider: "openai", + id: "gpt-5.5", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + contextWindow: 1_000_000, + maxTokens: 128_000, + cost: { input: 5, output: 30, cacheRead: 0, cacheWrite: 0 }, + }); + expect(pro).toMatchObject({ + provider: "openai", + id: "gpt-5.5-pro", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + contextWindow: 1_000_000, + maxTokens: 128_000, + cost: { input: 30, output: 180, cacheRead: 0, cacheWrite: 0 }, + }); + }); + + it("surfaces gpt-5.5 in xhigh and augmented catalog metadata", () => { + const provider = buildOpenAIProvider(); + + expect( + provider + .resolveThinkingProfile?.({ + provider: "openai", + modelId: "gpt-5.5", + } as never) + ?.levels.some((level) => level.id === "xhigh"), + ).toBe(true); + + const entries = provider.augmentModelCatalog?.({ + env: process.env, + entries: [{ provider: "openai", id: "gpt-5.4", name: "GPT-5.4" }], + } as never); + + expect(entries).toContainEqual( + expect.objectContaining({ + provider: "openai", + id: "gpt-5.5", + name: "gpt-5.5", + reasoning: true, + input: ["text", "image"], + contextWindow: 1_000_000, + }), + ); + }); + it("keeps modern live selection on OpenAI 5.2+ and Codex 5.2+", () => { const provider = buildOpenAIProvider(); const codexProvider = buildOpenAICodexProviderPlugin(); @@ -251,6 +346,12 @@ describe("buildOpenAIProvider", () => { modelId: "gpt-5.4", } as never), ).toBe(true); + expect( + provider.isModernModelRef?.({ + provider: "openai", + modelId: "gpt-5.5", + } as never), + ).toBe(true); expect( codexProvider.isModernModelRef?.({ @@ -276,6 +377,12 @@ describe("buildOpenAIProvider", () => { modelId: "gpt-5.4", } as never), ).toBe(true); + expect( + codexProvider.isModernModelRef?.({ + provider: "openai-codex", + modelId: "gpt-5.5", + } as never), + ).toBe(true); }); it("owns replay policy for OpenAI and Codex transports", () => { diff --git a/extensions/openai/openai.live.test.ts b/extensions/openai/openai.live.test.ts index 8d6e7f92e51..220f94ed53a 100644 --- a/extensions/openai/openai.live.test.ts +++ b/extensions/openai/openai.live.test.ts @@ -17,7 +17,7 @@ import { runRealtimeSttLiveTest } from "../../test/helpers/stt-live-audio.js"; import plugin from "./index.js"; const OPENAI_API_KEY = process.env.OPENAI_API_KEY ?? ""; -const LIVE_MODEL_ID = process.env.OPENCLAW_LIVE_OPENAI_PLUGIN_MODEL?.trim() || "gpt-5.4-nano"; +const LIVE_MODEL_ID = process.env.OPENCLAW_LIVE_OPENAI_PLUGIN_MODEL?.trim() || "gpt-5.5"; const LIVE_IMAGE_MODEL = process.env.OPENCLAW_LIVE_OPENAI_IMAGE_MODEL?.trim() || "gpt-image-2"; const LIVE_VISION_MODEL = process.env.OPENCLAW_LIVE_OPENAI_VISION_MODEL?.trim() || "gpt-4.1-mini"; const liveEnabled = OPENAI_API_KEY.trim().length > 0 && process.env.OPENCLAW_LIVE_TEST === "1"; @@ -29,6 +29,8 @@ const ModelRegistryCtor = ModelRegistry as unknown as { function resolveTemplateModelId(modelId: string) { switch (modelId) { + case "gpt-5.5": + return "gpt-5.4"; case "gpt-5.4": return "gpt-5.2"; case "gpt-5.4-mini": diff --git a/extensions/openai/test-support/provider-catalog.contract-test-support.ts b/extensions/openai/test-support/provider-catalog.contract-test-support.ts index fb624690e86..44d9af4e870 100644 --- a/extensions/openai/test-support/provider-catalog.contract-test-support.ts +++ b/extensions/openai/test-support/provider-catalog.contract-test-support.ts @@ -1,6 +1,7 @@ import { beforeEach, describe, it, vi } from "vitest"; import { expectAugmentedCodexCatalog, + expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55, expectCodexBuiltInSuppression, expectCodexMissingAuthHint, importProviderRuntimeCatalogModule, @@ -116,7 +117,10 @@ export function describeOpenAIProviderCatalogContract() { it("keeps bundled model augmentation wired through the provider runtime", async () => { const { augmentModelCatalogWithProviderPlugins } = await contractDepsPromise; - await expectAugmentedCodexCatalog(augmentModelCatalogWithProviderPlugins); + await expectAugmentedCodexCatalog( + augmentModelCatalogWithProviderPlugins, + expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55, + ); }); }, ); diff --git a/extensions/qa-lab/src/character-eval.test.ts b/extensions/qa-lab/src/character-eval.test.ts index a799cc93154..b98530d1df4 100644 --- a/extensions/qa-lab/src/character-eval.test.ts +++ b/extensions/qa-lab/src/character-eval.test.ts @@ -223,7 +223,7 @@ describe("runQaCharacterEval", () => { expect(runSuite).toHaveBeenCalledTimes(8); expect(runSuite.mock.calls.map(([params]) => params.primaryModel)).toEqual([ - "openai/gpt-5.4", + "openai/gpt-5.5", "openai/gpt-5.2", "openai/gpt-5", "anthropic/claude-opus-4-6", @@ -254,7 +254,7 @@ describe("runQaCharacterEval", () => { ]); expect(runJudge).toHaveBeenCalledTimes(2); expect(runJudge.mock.calls.map(([params]) => params.judgeModel)).toEqual([ - "openai/gpt-5.4", + "openai/gpt-5.5", "anthropic/claude-opus-4-6", ]); expect(runJudge.mock.calls.map(([params]) => params.judgeThinkingDefault)).toEqual([ diff --git a/extensions/qa-lab/src/cli.runtime.test.ts b/extensions/qa-lab/src/cli.runtime.test.ts index 71690081841..e9a70464857 100644 --- a/extensions/qa-lab/src/cli.runtime.test.ts +++ b/extensions/qa-lab/src/cli.runtime.test.ts @@ -1135,8 +1135,8 @@ describe("qa cli runtime", () => { repoRoot: path.resolve("/tmp/openclaw-repo"), transportId: "qa-channel", providerMode: "live-frontier", - primaryModel: "openai/gpt-5.4", - alternateModel: "openai/gpt-5.4", + primaryModel: "openai/gpt-5.5", + alternateModel: "openai/gpt-5.5", fastMode: undefined, message: "read qa kickoff and reply short", timeoutMs: undefined, @@ -1166,7 +1166,7 @@ describe("qa cli runtime", () => { it("defaults manual frontier runs onto Codex OAuth when the runtime resolver prefers it", async () => { defaultQaRuntimeModelForMode.mockImplementation((mode, options) => mode === "live-frontier" - ? "openai-codex/gpt-5.4" + ? "openai-codex/gpt-5.5" : defaultQaProviderModelForMode(mode as QaProviderModeInput, options), ); @@ -1179,8 +1179,8 @@ describe("qa cli runtime", () => { repoRoot: path.resolve("/tmp/openclaw-repo"), transportId: "qa-channel", providerMode: "live-frontier", - primaryModel: "openai-codex/gpt-5.4", - alternateModel: "openai-codex/gpt-5.4", + primaryModel: "openai-codex/gpt-5.5", + alternateModel: "openai-codex/gpt-5.5", fastMode: undefined, message: "read qa kickoff and reply short", timeoutMs: undefined, diff --git a/extensions/qa-lab/src/model-catalog.runtime.test.ts b/extensions/qa-lab/src/model-catalog.runtime.test.ts index 74c94f5e866..c812d36e1e5 100644 --- a/extensions/qa-lab/src/model-catalog.runtime.test.ts +++ b/extensions/qa-lab/src/model-catalog.runtime.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { selectQaRunnerModelOptions } from "./model-catalog.runtime.js"; describe("qa runner model catalog", () => { - it("filters to available rows and prefers gpt-5.4 first", () => { + it("filters to available rows and prefers gpt-5.5 first", () => { expect( selectQaRunnerModelOptions([ { @@ -13,8 +13,8 @@ describe("qa runner model catalog", () => { missing: false, }, { - key: "openai/gpt-5.4", - name: "gpt-5.4", + key: "openai/gpt-5.5", + name: "gpt-5.5", input: "text,image", available: true, missing: false, @@ -27,6 +27,6 @@ describe("qa runner model catalog", () => { missing: false, }, ]).map((entry) => entry.key), - ).toEqual(["openai/gpt-5.4", "anthropic/claude-sonnet-4-5"]); + ).toEqual(["openai/gpt-5.5", "anthropic/claude-sonnet-4-5"]); }); }); diff --git a/extensions/qa-lab/src/model-selection.runtime.test.ts b/extensions/qa-lab/src/model-selection.runtime.test.ts index 2aca8920b70..c182e66459f 100644 --- a/extensions/qa-lab/src/model-selection.runtime.test.ts +++ b/extensions/qa-lab/src/model-selection.runtime.test.ts @@ -34,7 +34,7 @@ describe("qa model selection runtime", () => { resolveEnvApiKey.mockReturnValue({ apiKey: "sk-test" }); expect(resolveQaPreferredLiveModel()).toBeUndefined(); - expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai/gpt-5.4"); + expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai/gpt-5.5"); expect(loadAuthProfileStoreForRuntime).not.toHaveBeenCalled(); }); @@ -43,8 +43,8 @@ describe("qa model selection runtime", () => { provider === "openai-codex" ? ["openai-codex:user@example.com"] : [], ); - expect(resolveQaPreferredLiveModel()).toBe("openai-codex/gpt-5.4"); - expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai-codex/gpt-5.4"); + expect(resolveQaPreferredLiveModel()).toBe("openai-codex/gpt-5.5"); + expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai-codex/gpt-5.5"); }); it("keeps the OpenAI live default when stored OpenAI profiles are available", () => { @@ -53,7 +53,7 @@ describe("qa model selection runtime", () => { ); expect(resolveQaPreferredLiveModel()).toBeUndefined(); - expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai/gpt-5.4"); + expect(defaultQaRuntimeModelForMode("live-frontier")).toBe("openai/gpt-5.5"); }); it("leaves mock defaults unchanged", () => { diff --git a/extensions/qa-lab/src/reply-failure.test.ts b/extensions/qa-lab/src/reply-failure.test.ts index 2b37104cd70..71d5daefa10 100644 --- a/extensions/qa-lab/src/reply-failure.test.ts +++ b/extensions/qa-lab/src/reply-failure.test.ts @@ -19,7 +19,7 @@ describe("extractQaFailureReplyText", () => { it("classifies explicit provider auth guidance as a failure", () => { expect( extractQaFailureReplyText( - '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5.', ), ).toContain('No API key found for provider "openai".'); }); @@ -27,7 +27,7 @@ describe("extractQaFailureReplyText", () => { it("classifies curated missing-key guidance as a failure", () => { expect( extractQaFailureReplyText( - "⚠️ Missing API key for OpenAI on the gateway. Use `openai-codex/gpt-5.4` for OAuth, or set `OPENAI_API_KEY`, then try again.", + "⚠️ Missing API key for OpenAI on the gateway. Use `openai-codex/gpt-5.5` for OAuth, or set `OPENAI_API_KEY`, then try again.", ), ).toContain("Missing API key for OpenAI on the gateway."); }); diff --git a/extensions/qa-lab/src/run-config.test.ts b/extensions/qa-lab/src/run-config.test.ts index 8096f87d257..8b4d102ea5b 100644 --- a/extensions/qa-lab/src/run-config.test.ts +++ b/extensions/qa-lab/src/run-config.test.ts @@ -45,8 +45,8 @@ describe("qa run config", () => { it("creates a live-by-default selection that arms every scenario", () => { expect(createDefaultQaRunSelection(scenarios)).toEqual({ providerMode: "live-frontier", - primaryModel: "openai/gpt-5.4", - alternateModel: "openai/gpt-5.4", + primaryModel: "openai/gpt-5.5", + alternateModel: "openai/gpt-5.5", fastMode: true, scenarioIds: ["dm-chat-baseline", "thread-lifecycle"], }); @@ -57,7 +57,7 @@ describe("qa run config", () => { normalizeQaRunSelection( { providerMode: "live-frontier", - primaryModel: "openai/gpt-5.4", + primaryModel: "openai/gpt-5.5", alternateModel: "", fastMode: false, scenarioIds: ["thread-lifecycle", "missing", "thread-lifecycle"], @@ -66,8 +66,8 @@ describe("qa run config", () => { ), ).toEqual({ providerMode: "live-frontier", - primaryModel: "openai/gpt-5.4", - alternateModel: "openai/gpt-5.4", + primaryModel: "openai/gpt-5.5", + alternateModel: "openai/gpt-5.5", fastMode: true, scenarioIds: ["thread-lifecycle"], }); @@ -99,13 +99,13 @@ describe("qa run config", () => { }); it("keeps idle snapshots on static defaults so startup does not inspect auth profiles", () => { - defaultQaRuntimeModelForMode.mockReturnValue("openai-codex/gpt-5.4"); + defaultQaRuntimeModelForMode.mockReturnValue("openai-codex/gpt-5.5"); defaultQaRuntimeModelForMode.mockClear(); expect(createIdleQaRunnerSnapshot(scenarios).selection).toMatchObject({ providerMode: "live-frontier", - primaryModel: "openai/gpt-5.4", - alternateModel: "openai/gpt-5.4", + primaryModel: "openai/gpt-5.5", + alternateModel: "openai/gpt-5.5", }); expect(defaultQaRuntimeModelForMode).not.toHaveBeenCalled(); }); @@ -138,14 +138,14 @@ describe("qa run config", () => { it("prefers the Codex OAuth default when the runtime resolver says it is available", () => { defaultQaRuntimeModelForMode.mockImplementation((mode, options) => mode === "live-frontier" - ? "openai-codex/gpt-5.4" + ? "openai-codex/gpt-5.5" : defaultQaProviderModelForMode(mode as QaProviderModeInput, options), ); expect(createDefaultQaRunSelection(scenarios)).toEqual({ providerMode: "live-frontier", - primaryModel: "openai-codex/gpt-5.4", - alternateModel: "openai-codex/gpt-5.4", + primaryModel: "openai-codex/gpt-5.5", + alternateModel: "openai-codex/gpt-5.5", fastMode: true, scenarioIds: ["dm-chat-baseline", "thread-lifecycle"], }); diff --git a/extensions/qa-lab/src/scenario-catalog.test.ts b/extensions/qa-lab/src/scenario-catalog.test.ts index 295366b1f32..fb6532f9faf 100644 --- a/extensions/qa-lab/src/scenario-catalog.test.ts +++ b/extensions/qa-lab/src/scenario-catalog.test.ts @@ -137,7 +137,7 @@ describe("qa scenario catalog", () => { expect(scenario.sourcePath).toBe("qa/scenarios/models/gpt54-thinking-visibility-switch.md"); expect(config?.requiredLiveProvider).toBe("openai"); - expect(config?.requiredLiveModel).toBe("gpt-5.4"); + expect(config?.requiredLiveModel).toBe("gpt-5.5"); expect(config?.offDirective).toBe("/think off"); expect(config?.maxDirective).toBe("/think max"); expect(config?.reasoningDirective).toBe("/reasoning on"); @@ -169,10 +169,10 @@ describe("qa scenario catalog", () => { }, }); expect(config?.requiredProvider).toBe("openai"); - expect(config?.requiredModel).toBe("gpt-5.4"); + expect(config?.requiredModel).toBe("gpt-5.5"); expect(config?.expectedMarker).toBe("WEB-SEARCH-OK"); expect(scenario.execution.flow?.steps.map((step) => step.name)).toEqual([ - "confirms live OpenAI GPT-5.4 web search auto mode", + "confirms live OpenAI GPT-5.5 web search auto mode", "searches official OpenAI News through the live model", ]); }); @@ -191,7 +191,7 @@ describe("qa scenario catalog", () => { expect(scenario.sourcePath).toBe("qa/scenarios/models/thinking-slash-model-remap.md"); expect(config?.requiredProviderMode).toBe("live-frontier"); expect(config?.anthropicModelRef).toBe("anthropic/claude-sonnet-4-6"); - expect(config?.openAiXhighModelRef).toBe("openai/gpt-5.4"); + expect(config?.openAiXhighModelRef).toBe("openai/gpt-5.5"); expect(config?.noXhighModelRef).toBe("anthropic/claude-sonnet-4-6"); expect(scenario.execution.flow?.steps.map((step) => step.name)).toEqual([ "selects Anthropic and verifies adaptive options", diff --git a/extensions/qa-lab/src/suite-runtime-transport.test.ts b/extensions/qa-lab/src/suite-runtime-transport.test.ts index 433a9697827..71ca82636b1 100644 --- a/extensions/qa-lab/src/suite-runtime-transport.test.ts +++ b/extensions/qa-lab/src/suite-runtime-transport.test.ts @@ -35,7 +35,7 @@ describe("qa suite transport helpers", () => { state.addOutboundMessage({ to: "dm:qa-operator", - text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5.', senderId: "openclaw", senderName: "OpenClaw QA", }); @@ -117,7 +117,7 @@ describe("qa suite transport helpers", () => { state.addOutboundMessage({ to: "dm:qa-operator", - text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5.', senderId: "openclaw", senderName: "OpenClaw QA", }); @@ -164,7 +164,7 @@ describe("qa suite transport helpers", () => { state.addOutboundMessage({ to: "dm:qa-operator", - text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + text: '⚠️ No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5.', senderId: "openclaw", senderName: "OpenClaw QA", }); diff --git a/qa/frontier-harness-plan.md b/qa/frontier-harness-plan.md index b31c7ddbe33..32857c93758 100644 --- a/qa/frontier-harness-plan.md +++ b/qa/frontier-harness-plan.md @@ -37,8 +37,8 @@ GPT baseline: ```bash pnpm openclaw qa suite \ --provider-mode live-frontier \ - --model openai/gpt-5.4 \ - --alt-model openai/gpt-5.4 \ + --model openai/gpt-5.5 \ + --alt-model openai/gpt-5.5 \ --fast \ --scenario approval-turn-tool-followthrough \ --scenario model-switch-tool-continuity \ @@ -104,8 +104,8 @@ GPT manual lane: ```bash pnpm openclaw qa manual \ --provider-mode live-frontier \ - --model openai/gpt-5.4 \ - --alt-model openai/gpt-5.4 \ + --model openai/gpt-5.5 \ + --alt-model openai/gpt-5.5 \ --fast \ --message "read QA_KICKOFF_TASK.md, tell me what feels half-baked about this qa mission, and keep it to two short sentences" ``` diff --git a/qa/scenarios/models/codex-harness-no-meta-leak.md b/qa/scenarios/models/codex-harness-no-meta-leak.md index 1d568b003b0..54c262ffef3 100644 --- a/qa/scenarios/models/codex-harness-no-meta-leak.md +++ b/qa/scenarios/models/codex-harness-no-meta-leak.md @@ -24,10 +24,10 @@ codeRefs: - extensions/qa-lab/src/suite.ts execution: kind: flow - summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model codex/gpt-5.4 --alt-model codex/gpt-5.4 --scenario codex-harness-no-meta-leak`. + summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model codex/gpt-5.5 --alt-model codex/gpt-5.5 --scenario codex-harness-no-meta-leak`. config: requiredProvider: codex - requiredModel: gpt-5.4 + requiredModel: gpt-5.5 harnessRuntime: codex harnessFallback: none expectedReply: QA_LEAK_OK @@ -47,7 +47,7 @@ execution: ```yaml qa-flow steps: - - name: confirms GPT-5.4 Codex harness target + - name: confirms GPT-5.5 Codex harness target actions: - set: selected value: diff --git a/qa/scenarios/models/gpt54-thinking-visibility-switch.md b/qa/scenarios/models/gpt54-thinking-visibility-switch.md index 9b560f6c606..0bfba9af390 100644 --- a/qa/scenarios/models/gpt54-thinking-visibility-switch.md +++ b/qa/scenarios/models/gpt54-thinking-visibility-switch.md @@ -1,17 +1,17 @@ -# GPT-5.4 thinking visibility switch +# GPT-5.5 thinking visibility switch ```yaml qa-scenario id: gpt54-thinking-visibility-switch -title: GPT-5.4 thinking visibility switch +title: GPT-5.5 thinking visibility switch surface: models coverage: primary: - models.thinking secondary: - runtime.reasoning-visibility -objective: Verify GPT-5.4 can switch from disabled thinking to max thinking while reasoning display stays enabled. +objective: Verify GPT-5.5 can switch from disabled thinking to max thinking while reasoning display stays enabled. successCriteria: - - Live runs target openai/gpt-5.4, not a mini or pro variant. + - Live runs target openai/gpt-5.5, not a mini or pro variant. - The session enables reasoning display before the comparison turns. - The disabled-thinking turn returns its visible marker without a Reasoning-prefixed message. - The max-thinking turn returns its visible marker and a separate Reasoning-prefixed message. @@ -27,10 +27,10 @@ codeRefs: - extensions/qa-lab/src/providers/mock-openai/server.ts execution: kind: flow - summary: Toggle reasoning display and GPT-5.4 thinking between off/none and max/high, then verify visible reasoning only on the max turn. + summary: Toggle reasoning display and GPT-5.5 thinking between off/none and max/high, then verify visible reasoning only on the max turn. config: requiredLiveProvider: openai - requiredLiveModel: gpt-5.4 + requiredLiveModel: gpt-5.5 offDirective: /think off maxDirective: /think max reasoningDirective: /reasoning on @@ -60,7 +60,7 @@ steps: - assert: expr: "env.providerMode !== 'live-frontier' || (selected?.provider === config.requiredLiveProvider && selected?.model === config.requiredLiveModel)" message: - expr: "`expected live GPT-5.4, got ${env.primaryModel}`" + expr: "`expected live GPT-5.5, got ${env.primaryModel}`" - call: state.addInboundMessage args: - conversation: @@ -133,9 +133,9 @@ steps: value: expr: "requests.find((request) => String(request.allInputText ?? '').includes(config.offPrompt))" - assert: - expr: "String(offRequest?.model ?? '').includes('gpt-5.4')" + expr: "String(offRequest?.model ?? '').includes('gpt-5.5')" message: - expr: "`expected GPT-5.4 off mock request, got ${String(offRequest?.model ?? '')}`" + expr: "`expected GPT-5.5 off mock request, got ${String(offRequest?.model ?? '')}`" detailsExpr: "`off ack=${offAck.text}; off answer=${offAnswer.text}`" - name: switches to max thinking actions: @@ -204,8 +204,8 @@ steps: value: expr: "requests.find((request) => String(request.allInputText ?? '').includes(config.maxPrompt))" - assert: - expr: "String(maxRequest?.model ?? '').includes('gpt-5.4')" + expr: "String(maxRequest?.model ?? '').includes('gpt-5.5')" message: - expr: "`expected GPT-5.4 mock request, got ${String(maxRequest?.model ?? '')}`" + expr: "`expected GPT-5.5 mock request, got ${String(maxRequest?.model ?? '')}`" detailsExpr: "`answer=${maxAnswer.text}`" ``` diff --git a/qa/scenarios/models/openai-native-web-search-live.md b/qa/scenarios/models/openai-native-web-search-live.md index c1b2afe4854..9bd6faa1948 100644 --- a/qa/scenarios/models/openai-native-web-search-live.md +++ b/qa/scenarios/models/openai-native-web-search-live.md @@ -12,7 +12,7 @@ coverage: objective: Verify a live OpenAI GPT model can use OpenAI native web_search when OpenClaw web search is enabled in auto mode. successCriteria: - A live-frontier run fails fast unless the selected primary provider is openai. - - The selected primary model is GPT-5.4, not a mini or pro variant. + - The selected primary model is GPT-5.5, not a mini or pro variant. - Web search is enabled without pinning a managed web_search provider. - The live reply includes the required marker plus an official OpenAI News URL and headline found through web search. gatewayConfigPatch: @@ -32,10 +32,10 @@ codeRefs: - extensions/qa-lab/src/suite.ts execution: kind: flow - summary: Run with `OPENCLAW_LIVE_OPENAI_KEY="${OPENAI_API_KEY}" pnpm openclaw qa suite --provider-mode live-frontier --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --scenario openai-native-web-search-live`. + summary: Run with `OPENCLAW_LIVE_OPENAI_KEY="${OPENAI_API_KEY}" pnpm openclaw qa suite --provider-mode live-frontier --model openai/gpt-5.5 --alt-model openai/gpt-5.5 --scenario openai-native-web-search-live`. config: requiredProvider: openai - requiredModel: gpt-5.4 + requiredModel: gpt-5.5 expectedMarker: WEB-SEARCH-OK failureMarker: WEB-SEARCH-FAILED searchPrompt: |- @@ -49,7 +49,7 @@ execution: ```yaml qa-flow steps: - - name: confirms live OpenAI GPT-5.4 web search auto mode + - name: confirms live OpenAI GPT-5.5 web search auto mode actions: - call: waitForGatewayHealthy args: diff --git a/qa/scenarios/models/thinking-slash-model-remap.md b/qa/scenarios/models/thinking-slash-model-remap.md index 1b47f2bc66e..e11798ab703 100644 --- a/qa/scenarios/models/thinking-slash-model-remap.md +++ b/qa/scenarios/models/thinking-slash-model-remap.md @@ -13,8 +13,8 @@ coverage: objective: Verify /think lists provider-owned levels and remaps stored thinking levels when /model changes provider capabilities. successCriteria: - Anthropic Claude Sonnet 4.6 advertises adaptive but not OpenAI-only xhigh or Opus max. - - A stored adaptive level remaps to medium when switching to OpenAI GPT-5.4. - - OpenAI GPT-5.4 advertises xhigh but not adaptive or max. + - A stored adaptive level remaps to medium when switching to OpenAI GPT-5.5. + - OpenAI GPT-5.5 advertises xhigh but not adaptive or max. - A stored xhigh level remaps to high when switching to an Anthropic model without xhigh support. docsRefs: - docs/tools/thinking.md @@ -33,7 +33,7 @@ execution: config: requiredProviderMode: live-frontier anthropicModelRef: anthropic/claude-sonnet-4-6 - openAiXhighModelRef: openai/gpt-5.4 + openAiXhighModelRef: openai/gpt-5.5 noXhighModelRef: anthropic/claude-sonnet-4-6 conversationId: qa-thinking-slash-remap ``` @@ -165,7 +165,7 @@ steps: - assert: expr: "/Options: .*\\bxhigh\\b/i.test(openAiThinkStatus.text) && !/Options: .*\\badaptive\\b/i.test(openAiThinkStatus.text) && !/Options: .*\\bmax\\b/i.test(openAiThinkStatus.text)" message: - expr: "`expected OpenAI GPT-5.4 /think options to include xhigh only, got ${openAiThinkStatus.text}`" + expr: "`expected OpenAI GPT-5.5 /think options to include xhigh only, got ${openAiThinkStatus.text}`" detailsExpr: "`adaptive=${adaptiveAck.text}; switch=${openAiModelAck.text}; think=${openAiThinkStatus.text}`" - name: maps xhigh to high on a model without xhigh actions: diff --git a/qa/scenarios/workspace/medium-game-plan-codex-harness.md b/qa/scenarios/workspace/medium-game-plan-codex-harness.md index 2e9d0bcb642..956a9f78899 100644 --- a/qa/scenarios/workspace/medium-game-plan-codex-harness.md +++ b/qa/scenarios/workspace/medium-game-plan-codex-harness.md @@ -11,7 +11,7 @@ coverage: - models.codex-cli objective: Verify the Codex app-server harness can plan and build a medium-complex self-contained browser game. successCriteria: - - A live-frontier run fails fast unless the selected primary model is codex/gpt-5.4. + - A live-frontier run fails fast unless the selected primary model is codex/gpt-5.5. - The scenario forces the Codex embedded harness and disables PI fallback. - The prompt explicitly asks the agent to enter plan mode before editing. - The agent writes a self-contained HTML game with a canvas loop, controls, scoring, waves, pause, and restart. @@ -25,10 +25,10 @@ codeRefs: - extensions/qa-lab/src/suite.ts execution: kind: flow - summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model codex/gpt-5.4 --alt-model codex/gpt-5.4 --scenario medium-game-plan-codex-harness`. + summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model codex/gpt-5.5 --alt-model codex/gpt-5.5 --scenario medium-game-plan-codex-harness`. config: requiredProvider: codex - requiredModel: gpt-5.4 + requiredModel: gpt-5.5 harnessRuntime: codex harnessFallback: none artifactFile: star-garden-defenders-codex.html @@ -52,7 +52,7 @@ execution: ```yaml qa-flow steps: - - name: confirms GPT-5.4 Codex harness target + - name: confirms GPT-5.5 Codex harness target actions: - set: selected value: diff --git a/qa/scenarios/workspace/medium-game-plan-pi-harness.md b/qa/scenarios/workspace/medium-game-plan-pi-harness.md index 9c22709285d..32cbb724a23 100644 --- a/qa/scenarios/workspace/medium-game-plan-pi-harness.md +++ b/qa/scenarios/workspace/medium-game-plan-pi-harness.md @@ -9,9 +9,9 @@ coverage: - workspace.planning secondary: - agents.pi-harness -objective: Verify GPT-5.4 can use the PI harness to plan and build a medium-complex self-contained browser game. +objective: Verify GPT-5.5 can use the PI harness to plan and build a medium-complex self-contained browser game. successCriteria: - - A live-frontier run fails fast unless the selected primary model is openai/gpt-5.4. + - A live-frontier run fails fast unless the selected primary model is openai/gpt-5.5. - The scenario forces the embedded PI harness before the build turn. - The prompt explicitly asks the agent to enter plan mode before editing. - The agent writes a self-contained HTML game with a canvas loop, controls, scoring, waves, pause, and restart. @@ -25,10 +25,10 @@ codeRefs: - extensions/qa-lab/src/suite.ts execution: kind: flow - summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model openai/gpt-5.4 --alt-model openai/gpt-5.4 --scenario medium-game-plan-pi-harness`. + summary: Run with `pnpm openclaw qa suite --provider-mode live-frontier --model openai/gpt-5.5 --alt-model openai/gpt-5.5 --scenario medium-game-plan-pi-harness`. config: requiredProvider: openai - requiredModel: gpt-5.4 + requiredModel: gpt-5.5 harnessRuntime: pi harnessFallback: pi artifactFile: star-garden-defenders-pi.html @@ -52,7 +52,7 @@ execution: ```yaml qa-flow steps: - - name: confirms GPT-5.4 PI harness target + - name: confirms GPT-5.5 PI harness target actions: - set: selected value: diff --git a/src/agents/cli-backends.test.ts b/src/agents/cli-backends.test.ts index 10252cc9f92..044541271d6 100644 --- a/src/agents/cli-backends.test.ts +++ b/src/agents/cli-backends.test.ts @@ -46,7 +46,7 @@ function createBackendEntry(params: { params.id === "claude-cli" ? "claude-cli/claude-sonnet-4-6" : params.id === "codex-cli" - ? "codex-cli/gpt-5.4" + ? "codex-cli/gpt-5.5" : params.id === "google-gemini-cli" ? "google-gemini-cli/gemini-3-flash-preview" : undefined, @@ -385,7 +385,7 @@ describe("resolveCliBackendLiveTest", () => { it("returns plugin-owned live smoke metadata for codex", () => { expect(resolveCliBackendLiveTest("codex-cli")).toEqual({ - defaultModelRef: "codex-cli/gpt-5.4", + defaultModelRef: "codex-cli/gpt-5.5", defaultImageProbe: true, defaultMcpProbe: true, dockerNpmPackage: "@openai/codex", diff --git a/src/agents/model-auth.profiles.test.ts b/src/agents/model-auth.profiles.test.ts index 9ff9ff88b50..4e13f5aa736 100644 --- a/src/agents/model-auth.profiles.test.ts +++ b/src/agents/model-auth.profiles.test.ts @@ -117,7 +117,7 @@ vi.mock("../plugins/provider-runtime.js", () => ({ context: { listProfileIds: (providerId: string) => string[] }; }) => { if (params.provider === "openai" && params.context.listProfileIds("openai-codex").length > 0) { - return 'No API key found for provider "openai". Use openai-codex/gpt-5.4.'; + return 'No API key found for provider "openai". Use openai-codex/gpt-5.5.'; } return undefined; }, @@ -365,7 +365,7 @@ describe("getApiKeyForModel", () => { } catch (err) { error = err; } - expect(String(error)).toContain("openai-codex/gpt-5.4"); + expect(String(error)).toContain("openai-codex/gpt-5.5"); }, ); } finally { diff --git a/src/agents/model-compat.test.ts b/src/agents/model-compat.test.ts index 69cd7aa004f..c51a7597d15 100644 --- a/src/agents/model-compat.test.ts +++ b/src/agents/model-compat.test.ts @@ -386,10 +386,14 @@ describe("isModernModelRef", () => { it("includes plugin-advertised modern models", () => { providerRuntimeMocks.resolveProviderModernModelRef.mockImplementation(({ provider, context }) => provider === "openai" && - ["gpt-5.4", "gpt-5.4-pro", "gpt-5.4-mini", "gpt-5.4-nano"].includes(context.modelId) + ["gpt-5.5", "gpt-5.5-pro", "gpt-5.4", "gpt-5.4-pro", "gpt-5.4-mini", "gpt-5.4-nano"].includes( + context.modelId, + ) ? true : provider === "openai-codex" && - ["gpt-5.4", "gpt-5.4-pro", "gpt-5.4-mini"].includes(context.modelId) + ["gpt-5.5", "gpt-5.5-pro", "gpt-5.4", "gpt-5.4-pro", "gpt-5.4-mini"].includes( + context.modelId, + ) ? true : provider === "opencode" && ["claude-opus-4-6", "gemini-3-pro"].includes(context.modelId) ? true @@ -398,10 +402,14 @@ describe("isModernModelRef", () => { : undefined, ); + expect(isModernModelRef({ provider: "openai", id: "gpt-5.5" })).toBe(true); + expect(isModernModelRef({ provider: "openai", id: "gpt-5.5-pro" })).toBe(true); expect(isModernModelRef({ provider: "openai", id: "gpt-5.4" })).toBe(true); expect(isModernModelRef({ provider: "openai", id: "gpt-5.4-pro" })).toBe(true); expect(isModernModelRef({ provider: "openai", id: "gpt-5.4-mini" })).toBe(true); expect(isModernModelRef({ provider: "openai", id: "gpt-5.4-nano" })).toBe(true); + expect(isModernModelRef({ provider: "openai-codex", id: "gpt-5.5" })).toBe(true); + expect(isModernModelRef({ provider: "openai-codex", id: "gpt-5.5-pro" })).toBe(true); expect(isModernModelRef({ provider: "openai-codex", id: "gpt-5.4" })).toBe(true); expect(isModernModelRef({ provider: "openai-codex", id: "gpt-5.4-pro" })).toBe(true); expect(isModernModelRef({ provider: "openai-codex", id: "gpt-5.4-mini" })).toBe(true); diff --git a/src/agents/models.profiles.live.test.ts b/src/agents/models.profiles.live.test.ts index f4d84baa910..7af749ee3ab 100644 --- a/src/agents/models.profiles.live.test.ts +++ b/src/agents/models.profiles.live.test.ts @@ -680,7 +680,7 @@ describeLive("live models (profile keys)", () => { if ( model.provider === "openai" && model.api === "openai-responses" && - model.id === "gpt-5.4" + (model.id === "gpt-5.5" || model.id === "gpt-5.4") ) { logProgress(`${progressLabel}: tool-only regression`); const noopTool = { diff --git a/src/agents/pi-embedded-runner.cache.live.test.ts b/src/agents/pi-embedded-runner.cache.live.test.ts index 9557b8d3438..cf3dd403f8b 100644 --- a/src/agents/pi-embedded-runner.cache.live.test.ts +++ b/src/agents/pi-embedded-runner.cache.live.test.ts @@ -805,7 +805,7 @@ describeCacheLive("pi embedded runner prompt caching (live)", () => { provider: "openai", api: "openai-responses", envVar: "OPENCLAW_LIVE_OPENAI_CACHE_MODEL", - preferredModelIds: ["gpt-5.4-mini", "gpt-5.4", "gpt-5.4"], + preferredModelIds: ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4"], }); logLiveCache(`openai model=${fixture.model.provider}/${fixture.model.id}`); }, 120_000); diff --git a/src/agents/pi-mcp-style.cache.live.test.ts b/src/agents/pi-mcp-style.cache.live.test.ts index 51ae45e71de..8fc6da32a87 100644 --- a/src/agents/pi-mcp-style.cache.live.test.ts +++ b/src/agents/pi-mcp-style.cache.live.test.ts @@ -162,7 +162,7 @@ describeCacheLive("MCP-style prompt caching (live)", () => { provider: "openai", api: "openai-responses", envVar: "OPENCLAW_LIVE_OPENAI_CACHE_MODEL", - preferredModelIds: ["gpt-5.4-mini", "gpt-5.4", "gpt-5.4"], + preferredModelIds: ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4"], }); logLiveCache(`openai mcp-style model=${fixture.model.provider}/${fixture.model.id}`); diff --git a/src/agents/provider-headers.live.test.ts b/src/agents/provider-headers.live.test.ts index ac44ef11f88..ea6e1f5a633 100644 --- a/src/agents/provider-headers.live.test.ts +++ b/src/agents/provider-headers.live.test.ts @@ -17,7 +17,7 @@ describeLive("provider response headers (live)", () => { provider: "openai", api: "openai-responses", envVar: "OPENCLAW_LIVE_OPENAI_CACHE_MODEL", - preferredModelIds: ["gpt-5.4-mini", "gpt-5.4", "gpt-5.4"], + preferredModelIds: ["gpt-5.5", "gpt-5.4-mini", "gpt-5.4"], }); }, 120_000); diff --git a/src/agents/simple-completion-runtime.selection.test.ts b/src/agents/simple-completion-runtime.selection.test.ts index e8fc873353d..d511091c8a9 100644 --- a/src/agents/simple-completion-runtime.selection.test.ts +++ b/src/agents/simple-completion-runtime.selection.test.ts @@ -82,7 +82,7 @@ describe("resolveSimpleCompletionSelectionForAgent", () => { expect(selection).toEqual( expect.objectContaining({ provider: "openai", - modelId: "gpt-5.4", + modelId: "gpt-5.5", }), ); }); @@ -118,7 +118,7 @@ describe("resolveSimpleCompletionSelectionForAgent", () => { expect(selection).toEqual( expect.objectContaining({ provider: "openai", - modelId: "gpt-5.4", + modelId: "gpt-5.5", }), ); }); diff --git a/src/auto-reply/reply/agent-runner-execution.test.ts b/src/auto-reply/reply/agent-runner-execution.test.ts index be7a4ebc31a..0ce5b4ed08b 100644 --- a/src/auto-reply/reply/agent-runner-execution.test.ts +++ b/src/auto-reply/reply/agent-runner-execution.test.ts @@ -1517,7 +1517,7 @@ describe("runAgentTurnWithFallback", () => { it("surfaces direct provider auth guidance for missing API keys", async () => { state.runEmbeddedPiAgentMock.mockRejectedValueOnce( new Error( - 'No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4. | No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.4 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.4.', + 'No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5. | No API key found for provider "openai". You are authenticated with OpenAI Codex OAuth. Use openai-codex/gpt-5.5 (OAuth) or set OPENAI_API_KEY to use openai/gpt-5.5.', ), ); @@ -1549,7 +1549,7 @@ describe("runAgentTurnWithFallback", () => { expect(result.kind).toBe("final"); if (result.kind === "final") { expect(result.payload.text).toBe( - "⚠️ Missing API key for OpenAI on the gateway. Use `openai-codex/gpt-5.4` for OAuth, or set `OPENAI_API_KEY`, then try again.", + "⚠️ Missing API key for OpenAI on the gateway. Use `openai-codex/gpt-5.5` for OAuth, or set `OPENAI_API_KEY`, then try again.", ); } }); diff --git a/src/auto-reply/reply/agent-runner-memory.test.ts b/src/auto-reply/reply/agent-runner-memory.test.ts index 55c7e6f67e2..d8ca2221298 100644 --- a/src/auto-reply/reply/agent-runner-memory.test.ts +++ b/src/auto-reply/reply/agent-runner-memory.test.ts @@ -181,7 +181,7 @@ describe("runMemoryFlushIfNeeded", () => { cfg: { agents: { defaults: { cliBackends: { "codex-cli": { command: "codex" } } } } }, followupRun: createTestFollowupRun({ provider: "codex-cli" }), sessionCtx: { Provider: "whatsapp" } as unknown as TemplateContext, - defaultModel: "codex-cli/gpt-5.4", + defaultModel: "codex-cli/gpt-5.5", agentCfgContextTokens: 100_000, resolvedVerboseLevel: "off", sessionEntry, diff --git a/src/commands/agent-command.test-mocks.ts b/src/commands/agent-command.test-mocks.ts index 045b5650db4..528aaadba6d 100644 --- a/src/commands/agent-command.test-mocks.ts +++ b/src/commands/agent-command.test-mocks.ts @@ -83,8 +83,8 @@ vi.mock("../agents/model-selection.js", () => { return primary?.primary; }; const resolveDefaultRef = (cfg?: ConfigWithModels): ModelRef => { - const parsed = parseModelRefImpl(resolvePrimary(cfg) ?? "openai/gpt-5.4", "openai"); - return parsed ?? { provider: "openai", model: "gpt-5.4" }; + const parsed = parseModelRefImpl(resolvePrimary(cfg) ?? "openai/gpt-5.5", "openai"); + return parsed ?? { provider: "openai", model: "gpt-5.5" }; }; const resolveModelConfig = (cfg: ConfigWithModels | undefined, ref: ModelRef) => { const models = cfg?.agents?.defaults?.models ?? {}; diff --git a/src/commands/agent.acp.test.ts b/src/commands/agent.acp.test.ts index ac116d66652..7ae55c32328 100644 --- a/src/commands/agent.acp.test.ts +++ b/src/commands/agent.acp.test.ts @@ -130,8 +130,8 @@ function createAcpEnabledConfig(home: string, storePath: string): OpenClawConfig }, agents: { defaults: { - model: { primary: "openai/gpt-5.4" }, - models: { "openai/gpt-5.4": {} }, + model: { primary: "openai/gpt-5.5" }, + models: { "openai/gpt-5.5": {} }, workspace: path.join(home, "openclaw"), }, }, diff --git a/src/commands/auth-choice.test.ts b/src/commands/auth-choice.test.ts index 1cfe2e2fb30..bc59fbfab52 100644 --- a/src/commands/auth-choice.test.ts +++ b/src/commands/auth-choice.test.ts @@ -492,7 +492,7 @@ async function createDefaultProviderPlugins(): Promise { flagName: "--openai-api-key", envVar: "OPENAI_API_KEY", promptMessage: "Enter OpenAI API key", - defaultModel: "openai/gpt-5.4", + defaultModel: "openai/gpt-5.5", }), await createApiKeyProvider({ providerId: "opencode", diff --git a/src/commands/configure.gateway-auth.prompt-auth-config.test.ts b/src/commands/configure.gateway-auth.prompt-auth-config.test.ts index b23282d48ad..54c49ab45d2 100644 --- a/src/commands/configure.gateway-auth.prompt-auth-config.test.ts +++ b/src/commands/configure.gateway-auth.prompt-auth-config.test.ts @@ -168,7 +168,7 @@ describe("promptAuthConfig", () => { agents: { defaults: { models: { - "openai/gpt-5.4": { alias: "GPT" }, + "openai/gpt-5.5": { alias: "GPT" }, "anthropic/claude-opus-4-6": { alias: "Opus" }, }, }, @@ -193,7 +193,7 @@ describe("promptAuthConfig", () => { const result = await promptAuthConfig({}, makeRuntime(), noopPrompter); expect(result.agents?.defaults?.models).toEqual({ - "openai/gpt-5.4": { alias: "GPT" }, + "openai/gpt-5.5": { alias: "GPT" }, "anthropic/claude-sonnet-4-6": {}, }); }); diff --git a/src/commands/doctor-cron-store-migration.test.ts b/src/commands/doctor-cron-store-migration.test.ts index 1449b89c129..5a85ae51ec2 100644 --- a/src/commands/doctor-cron-store-migration.test.ts +++ b/src/commands/doctor-cron-store-migration.test.ts @@ -36,7 +36,7 @@ describe("normalizeStoredCronJobs", () => { jobId: "legacy-job", schedule: { kind: "cron", cron: "*/5 * * * *", tz: "UTC" }, message: "say hi", - model: "openai/gpt-5.4", + model: "openai/gpt-5.5", deliver: true, provider: " TeLeGrAm ", to: "12345", @@ -73,7 +73,7 @@ describe("normalizeStoredCronJobs", () => { expect(job?.payload).toMatchObject({ kind: "agentTurn", message: "say hi", - model: "openai/gpt-5.4", + model: "openai/gpt-5.5", }); }); diff --git a/src/commands/model-picker.test.ts b/src/commands/model-picker.test.ts index f3ada2a9f44..9ac565452cf 100644 --- a/src/commands/model-picker.test.ts +++ b/src/commands/model-picker.test.ts @@ -116,13 +116,13 @@ describe("promptDefaultModel", () => { loadModelCatalog.mockResolvedValue([ { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", }, { provider: "openai-codex", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", }, ]); @@ -141,11 +141,11 @@ describe("promptDefaultModel", () => { expect(options).toEqual( expect.arrayContaining([ expect.objectContaining({ - value: "openai/gpt-5.4", + value: "openai/gpt-5.5", hint: expect.stringContaining("API key route"), }), expect.objectContaining({ - value: "openai-codex/gpt-5.4", + value: "openai-codex/gpt-5.5", hint: expect.stringContaining("ChatGPT OAuth route"), }), ]), @@ -156,8 +156,8 @@ describe("promptDefaultModel", () => { loadModelCatalog.mockResolvedValue([ { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", }, { provider: "byteplus-plan", @@ -171,7 +171,7 @@ describe("promptDefaultModel", () => { const config = { agents: { defaults: { - model: "openai/gpt-5.4", + model: "openai/gpt-5.5", }, }, } as OpenClawConfig; @@ -276,8 +276,8 @@ describe("promptDefaultModel", () => { loadModelCatalog.mockResolvedValue([ { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", }, ]); providerModelPickerContributionRuntime.enabled = true; @@ -343,8 +343,8 @@ describe("promptModelAllowlist", () => { }, { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.2", + id: "gpt-5.5", + name: "GPT-5.5", }, ]); @@ -374,8 +374,8 @@ describe("promptModelAllowlist", () => { }, { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", }, { provider: "openai", @@ -396,7 +396,7 @@ describe("promptModelAllowlist", () => { const options = multiselect.mock.calls[0]?.[0]?.options ?? []; expect(options.map((opt: { value: string }) => opt.value)).toEqual([ - "openai/gpt-5.4", + "openai/gpt-5.5", "openai/gpt-5.4-mini", ]); }); @@ -440,16 +440,16 @@ describe("applyModelAllowlist", () => { agents: { defaults: { models: { - "openai/gpt-5.4": { alias: "gpt" }, + "openai/gpt-5.5": { alias: "gpt" }, "anthropic/claude-opus-4-6": { alias: "opus" }, }, }, }, } as OpenClawConfig; - const next = applyModelAllowlist(config, ["openai/gpt-5.4"]); + const next = applyModelAllowlist(config, ["openai/gpt-5.5"]); expect(next.agents?.defaults?.models).toEqual({ - "openai/gpt-5.4": { alias: "gpt" }, + "openai/gpt-5.5": { alias: "gpt" }, }); }); @@ -458,7 +458,7 @@ describe("applyModelAllowlist", () => { agents: { defaults: { models: { - "openai/gpt-5.4": { alias: "gpt" }, + "openai/gpt-5.5": { alias: "gpt" }, "anthropic/claude-opus-4-6": { alias: "opus" }, "anthropic/claude-sonnet-4-6": { alias: "sonnet" }, }, @@ -470,7 +470,7 @@ describe("applyModelAllowlist", () => { scopeKeys: ["anthropic/claude-opus-4-6", "anthropic/claude-sonnet-4-6"], }); expect(next.agents?.defaults?.models).toEqual({ - "openai/gpt-5.4": { alias: "gpt" }, + "openai/gpt-5.5": { alias: "gpt" }, "anthropic/claude-sonnet-4-6": { alias: "sonnet" }, }); }); @@ -480,7 +480,7 @@ describe("applyModelAllowlist", () => { agents: { defaults: { models: { - "openai/gpt-5.4": { alias: "gpt" }, + "openai/gpt-5.5": { alias: "gpt" }, }, }, }, @@ -515,15 +515,15 @@ describe("applyModelFallbacksFromSelection", () => { const config = { agents: { defaults: { - model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["openai/gpt-5.4"] }, + model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["openai/gpt-5.5"] }, }, }, } as OpenClawConfig; - const next = applyModelFallbacksFromSelection(config, ["openai/gpt-5.4"]); + const next = applyModelFallbacksFromSelection(config, ["openai/gpt-5.5"]); expect(next.agents?.defaults?.model).toEqual({ primary: "anthropic/claude-opus-4-6", - fallbacks: ["openai/gpt-5.4"], + fallbacks: ["openai/gpt-5.5"], }); }); }); diff --git a/src/commands/models/auth.test.ts b/src/commands/models/auth.test.ts index 8ebcd4939ec..daaf6874f2e 100644 --- a/src/commands/models/auth.test.ts +++ b/src/commands/models/auth.test.ts @@ -298,7 +298,7 @@ describe("modelsAuthLoginCommand", () => { }, }, ], - defaultModel: "openai-codex/gpt-5.4", + defaultModel: "openai-codex/gpt-5.5", }); mocks.resolvePluginProviders.mockReturnValue([ createProvider({ @@ -365,7 +365,7 @@ describe("modelsAuthLoginCommand", () => { "Auth profile: openai-codex:user@example.com (openai-codex/oauth)", ); expect(runtime.log).toHaveBeenCalledWith( - "Default model available: openai-codex/gpt-5.4 (use --set-default to apply)", + "Default model available: openai-codex/gpt-5.5 (use --set-default to apply)", ); expect(runtime.log).toHaveBeenCalledWith( "Tip: Codex-capable models can use native Codex web search. Enable it with openclaw configure --section web (recommended mode: cached). Docs: https://docs.openclaw.ai/tools/web", @@ -585,7 +585,7 @@ describe("modelsAuthLoginCommand", () => { "anthropic/claude-sonnet-4-6": { alias: "sonnet" }, "anthropic/claude-opus-4-6": { alias: "opus" }, "moonshot/kimi-k2.5": { alias: "kimi" }, - "openai-codex/gpt-5.4": { alias: "gpt54" }, + "openai-codex/gpt-5.5": { alias: "gpt55" }, }; currentConfig = { agents: { defaults: { models: existingModels } } }; runProviderAuth.mockResolvedValue({ @@ -602,8 +602,8 @@ describe("modelsAuthLoginCommand", () => { }, }, ], - configPatch: { agents: { defaults: { models: { "openai-codex/gpt-5.4": {} } } } }, - defaultModel: "openai-codex/gpt-5.4", + configPatch: { agents: { defaults: { models: { "openai-codex/gpt-5.5": {} } } } }, + defaultModel: "openai-codex/gpt-5.5", }); await modelsAuthLoginCommand({ provider: "openai-codex" }, runtime); diff --git a/src/commands/models/list.configured.test.ts b/src/commands/models/list.configured.test.ts index 04fb661c040..45cb21c9461 100644 --- a/src/commands/models/list.configured.test.ts +++ b/src/commands/models/list.configured.test.ts @@ -13,9 +13,9 @@ describe("resolveConfiguredEntries", () => { const { entries } = resolveConfiguredEntries({ agents: { defaults: { - model: { primary: "codex/gpt-5.4", fallbacks: ["codex/gpt-5.4-mini"] }, + model: { primary: "codex/gpt-5.5", fallbacks: ["codex/gpt-5.4-mini"] }, models: { - "codex/gpt-5.4": { alias: "Codex" }, + "codex/gpt-5.5": { alias: "Codex" }, "codex/gpt-5.4-mini": {}, }, }, @@ -23,7 +23,7 @@ describe("resolveConfiguredEntries", () => { models: { providers: {} }, }); - expect(entries.map((entry) => entry.key)).toEqual(["codex/gpt-5.4", "codex/gpt-5.4-mini"]); + expect(entries.map((entry) => entry.key)).toEqual(["codex/gpt-5.5", "codex/gpt-5.4-mini"]); expect(entries[0]?.tags).toEqual(new Set(["default", "configured"])); expect(entries[0]?.aliases).toEqual(["Codex"]); expect(entries[1]?.tags).toEqual(new Set(["fallback#1", "configured"])); diff --git a/src/commands/models/list.rows.test.ts b/src/commands/models/list.rows.test.ts index df8af8b264a..e2f77819e47 100644 --- a/src/commands/models/list.rows.test.ts +++ b/src/commands/models/list.rows.test.ts @@ -8,8 +8,8 @@ const mocks = vi.hoisted(() => ({ }), loadProviderCatalogModelsForList: vi.fn().mockResolvedValue([ { - id: "gpt-5.4", - name: "gpt-5.4", + id: "gpt-5.5", + name: "gpt-5.5", provider: "codex", api: "openai-codex-responses", baseUrl: "https://chatgpt.com/backend-api", @@ -57,7 +57,7 @@ describe("appendProviderCatalogRows", () => { seenKeys: new Set(), context: { cfg: { - agents: { defaults: { model: { primary: "codex/gpt-5.4" } } }, + agents: { defaults: { model: { primary: "codex/gpt-5.5" } } }, models: { providers: {} }, }, agentDir: "/tmp/openclaw-agent", @@ -72,7 +72,7 @@ describe("appendProviderCatalogRows", () => { expect(mocks.shouldSuppressBuiltInModel).not.toHaveBeenCalled(); expect(rows).toMatchObject([ { - key: "codex/gpt-5.4", + key: "codex/gpt-5.5", available: true, missing: false, }, diff --git a/src/commands/models/list.status.test.ts b/src/commands/models/list.status.test.ts index 357d5d991ba..16ba9c450a2 100644 --- a/src/commands/models/list.status.test.ts +++ b/src/commands/models/list.status.test.ts @@ -429,8 +429,8 @@ describe("modelsStatusCommand auth overview", () => { mocks.loadConfig.mockReturnValue({ agents: { defaults: { - model: { primary: "codex/gpt-5.4", fallbacks: [] }, - models: { "codex/gpt-5.4": {} }, + model: { primary: "codex/gpt-5.5", fallbacks: [] }, + models: { "codex/gpt-5.5": {} }, }, }, models: { providers: {} }, diff --git a/src/commands/onboard-auth.config-shared.test.ts b/src/commands/onboard-auth.config-shared.test.ts index 2f0c549aac9..dba920f1e41 100644 --- a/src/commands/onboard-auth.config-shared.test.ts +++ b/src/commands/onboard-auth.config-shared.test.ts @@ -64,7 +64,7 @@ describe("onboard auth provider config merges", () => { agents: { defaults: { models: { - "openai/gpt-5.4": { alias: "GPT" }, + "openai/gpt-5.5": { alias: "GPT" }, }, }, }, @@ -89,7 +89,7 @@ describe("onboard auth provider config merges", () => { }); expect(next.agents?.defaults?.models).toEqual({ - "openai/gpt-5.4": { alias: "GPT" }, + "openai/gpt-5.5": { alias: "GPT" }, ...agentModels, }); }); diff --git a/src/commands/openai-model-default.test.ts b/src/commands/openai-model-default.test.ts index 173fc94fb69..fc3e7ada9c7 100644 --- a/src/commands/openai-model-default.test.ts +++ b/src/commands/openai-model-default.test.ts @@ -73,7 +73,7 @@ describe("applyDefaultModelChoice", () => { }); it("uses applyDefaultConfig path when setDefaultModel is true", async () => { - const defaultModel = "openai/gpt-5.4"; + const defaultModel = "openai/gpt-5.5"; const applied = await applyDefaultModelChoice({ config: {}, setDefaultModel: true, diff --git a/src/commands/status-overview-rows.test.ts b/src/commands/status-overview-rows.test.ts index 451e72d8543..44719ffddf5 100644 --- a/src/commands/status-overview-rows.test.ts +++ b/src/commands/status-overview-rows.test.ts @@ -19,7 +19,7 @@ describe("status-overview-rows", () => { "1 files · 2 chunks · plugin memory · ok(vector ready) · warn(fts ready) · muted(cache warm)", }, { Item: "Plugin compatibility", Value: "warn(1 notice · 1 plugin)" }, - { Item: "Sessions", Value: "2 active · default gpt-5.4 (12k ctx) · store.json" }, + { Item: "Sessions", Value: "2 active · default gpt-5.5 (12k ctx) · store.json" }, ]), ); }); diff --git a/src/commands/status-overview-values.test.ts b/src/commands/status-overview-values.test.ts index e809d13c562..5bcd4b7880d 100644 --- a/src/commands/status-overview-values.test.ts +++ b/src/commands/status-overview-values.test.ts @@ -54,10 +54,10 @@ describe("status-overview-values", () => { sessions: { count: 2, paths: ["store.json", "other.json"], - defaults: { model: "gpt-5.4", contextTokens: 12_000 }, + defaults: { model: "gpt-5.5", contextTokens: 12_000 }, }, formatKTokens: (value) => `${Math.round(value / 1000)}k`, }), - ).toBe("2 active · default gpt-5.4 (12k ctx) · 2 stores"); + ).toBe("2 active · default gpt-5.5 (12k ctx) · 2 stores"); }); }); diff --git a/src/commands/status.summary.runtime.test.ts b/src/commands/status.summary.runtime.test.ts index 2c3b5319cbc..6d5d46e2e9f 100644 --- a/src/commands/status.summary.runtime.test.ts +++ b/src/commands/status.summary.runtime.test.ts @@ -79,17 +79,17 @@ describe("statusSummaryRuntime.resolveSessionModelRef", () => { { agents: { defaults: { - model: { primary: "openai/gpt-5.4" }, + model: { primary: "openai/gpt-5.5" }, }, }, } as never, { - model: "gpt-5.4", + model: "gpt-5.5", }, ), ).toEqual({ provider: "openai", - model: "gpt-5.4", + model: "gpt-5.5", }); }); diff --git a/src/commands/status.summary.test.ts b/src/commands/status.summary.test.ts index 4eab0d1b3e9..c7b48a1b5b3 100644 --- a/src/commands/status.summary.test.ts +++ b/src/commands/status.summary.test.ts @@ -14,11 +14,11 @@ vi.mock("./status.summary.runtime.js", () => ({ classifySessionKey: vi.fn(() => "direct"), resolveConfiguredStatusModelRef: vi.fn(() => ({ provider: "openai", - model: "gpt-5.4", + model: "gpt-5.5", })), resolveSessionModelRef: vi.fn(() => ({ provider: "openai", - model: "gpt-5.4", + model: "gpt-5.5", })), resolveContextTokensForModel: vi.fn(() => 200_000), }, @@ -26,7 +26,7 @@ vi.mock("./status.summary.runtime.js", () => ({ vi.mock("../agents/defaults.js", () => ({ DEFAULT_CONTEXT_TOKENS: 200_000, - DEFAULT_MODEL: "gpt-5.4", + DEFAULT_MODEL: "gpt-5.5", DEFAULT_PROVIDER: "openai", })); diff --git a/src/commands/status.test-support.ts b/src/commands/status.test-support.ts index 4e72f261fde..0e47a4ce7b5 100644 --- a/src/commands/status.test-support.ts +++ b/src/commands/status.test-support.ts @@ -92,14 +92,14 @@ export const baseStatusSummary = { sessions: { count: 2, paths: ["store.json"], - defaults: { model: "gpt-5.4", contextTokens: 12_000 }, + defaults: { model: "gpt-5.5", contextTokens: 12_000 }, recent: [ { key: "session-key", kind: "direct", updatedAt: 1, age: 5_000, - model: "gpt-5.4", + model: "gpt-5.5", totalTokens: 12_000, totalTokensFresh: true, remainingTokens: 4_000, diff --git a/src/gateway/gateway-acp-bind.live.test.ts b/src/gateway/gateway-acp-bind.live.test.ts index 04ca819eee6..0d8349b3a28 100644 --- a/src/gateway/gateway-acp-bind.live.test.ts +++ b/src/gateway/gateway-acp-bind.live.test.ts @@ -36,7 +36,7 @@ const describeLive = LIVE && ACP_BIND_LIVE ? describe : describe.skip; const CONNECT_TIMEOUT_MS = 90_000; const LIVE_TIMEOUT_MS = 240_000; -const DEFAULT_LIVE_CODEX_MODEL = "gpt-5.4"; +const DEFAULT_LIVE_CODEX_MODEL = "gpt-5.5"; type LiveAcpAgent = "claude" | "codex" | "gemini"; function createSlackCurrentConversationBindingRegistry() { diff --git a/src/gateway/gateway-cli-backend.live-helpers.test.ts b/src/gateway/gateway-cli-backend.live-helpers.test.ts index 105e7fae8ed..fa246caa573 100644 --- a/src/gateway/gateway-cli-backend.live-helpers.test.ts +++ b/src/gateway/gateway-cli-backend.live-helpers.test.ts @@ -112,7 +112,7 @@ describe("gateway cli backend live helpers", () => { ); expect(shouldRunCliModelSwitchProbe("claude-cli", "claude-cli/claude-sonnet-4-6")).toBe(true); expect(shouldRunCliModelSwitchProbe("claude-cli", "claude-cli/claude-opus-4-6")).toBe(false); - expect(shouldRunCliModelSwitchProbe("codex-cli", "codex-cli/gpt-5.4")).toBe(false); + expect(shouldRunCliModelSwitchProbe("codex-cli", "codex-cli/gpt-5.5")).toBe(false); }); it("lets env disable the model switch probe", async () => { diff --git a/src/gateway/gateway-models.profiles.live.test.ts b/src/gateway/gateway-models.profiles.live.test.ts index a3afb1f967d..108528c469a 100644 --- a/src/gateway/gateway-models.profiles.live.test.ts +++ b/src/gateway/gateway-models.profiles.live.test.ts @@ -515,7 +515,7 @@ describe("resolveGatewayLiveMaxModels", () => { }); it("keeps explicit gateway model lists uncapped unless a cap is provided", () => { - process.env.OPENCLAW_LIVE_GATEWAY_MODELS = "openai/gpt-5.4,anthropic/claude-opus-4-6"; + process.env.OPENCLAW_LIVE_GATEWAY_MODELS = "openai/gpt-5.5,anthropic/claude-opus-4-6"; delete process.env.OPENCLAW_LIVE_GATEWAY_MAX_MODELS; delete process.env.OPENCLAW_LIVE_MAX_MODELS; diff --git a/src/gateway/server-methods/chat.directive-tags.test.ts b/src/gateway/server-methods/chat.directive-tags.test.ts index c80af46a318..8e515fa45a6 100644 --- a/src/gateway/server-methods/chat.directive-tags.test.ts +++ b/src/gateway/server-methods/chat.directive-tags.test.ts @@ -344,8 +344,8 @@ function createChatContext(): Pick< mockState.modelCatalog ?? [ { provider: "openai", - id: "gpt-5.4", - name: "GPT-5.4", + id: "gpt-5.5", + name: "GPT-5.5", input: ["text", "image"], }, { diff --git a/src/gateway/server-startup.test.ts b/src/gateway/server-startup.test.ts index b5739d34b55..29f4e8c3783 100644 --- a/src/gateway/server-startup.test.ts +++ b/src/gateway/server-startup.test.ts @@ -122,7 +122,7 @@ describe("gateway startup primary model warmup", () => { agents: { defaults: { model: { - primary: "codex-cli/gpt-5.4", + primary: "codex-cli/gpt-5.5", }, cliBackends: { "codex-cli": { diff --git a/src/media-understanding/defaults.test.ts b/src/media-understanding/defaults.test.ts index 1effd6da0bc..6854e99a7b4 100644 --- a/src/media-understanding/defaults.test.ts +++ b/src/media-understanding/defaults.test.ts @@ -17,7 +17,7 @@ describe("resolveDefaultMediaModel", () => { "MiniMax-VL-01", ); expect(resolveDefaultMediaModel({ providerId: "openai-codex", capability: "image" })).toBe( - "gpt-5.4", + "gpt-5.5", ); expect(resolveDefaultMediaModel({ providerId: "moonshot", capability: "image" })).toBe( "kimi-k2.6", diff --git a/src/plugins/config-state.test.ts b/src/plugins/config-state.test.ts index 246a21bd29b..f153eac0914 100644 --- a/src/plugins/config-state.test.ts +++ b/src/plugins/config-state.test.ts @@ -94,12 +94,12 @@ describe("normalizePluginsConfig", () => { name: "normalizes plugin subagent override policy settings", subagent: { allowModelOverride: true, - allowedModels: [" anthropic/claude-sonnet-4-6 ", "", "openai/gpt-5.4"], + allowedModels: [" anthropic/claude-sonnet-4-6 ", "", "openai/gpt-5.5"], }, expected: { allowModelOverride: true, hasAllowedModelsConfig: true, - allowedModels: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.4"], + allowedModels: ["anthropic/claude-sonnet-4-6", "openai/gpt-5.5"], }, }, { diff --git a/src/plugins/provider-auth-choice-helpers.test.ts b/src/plugins/provider-auth-choice-helpers.test.ts index 8393a79bffb..931e5356126 100644 --- a/src/plugins/provider-auth-choice-helpers.test.ts +++ b/src/plugins/provider-auth-choice-helpers.test.ts @@ -17,11 +17,11 @@ describe("applyProviderAuthConfigPatch", () => { }; it("merges default model maps by default so other providers survive login", () => { - const patch = { agents: { defaults: { models: { "openai-codex/gpt-5.4": {} } } } }; + const patch = { agents: { defaults: { models: { "openai-codex/gpt-5.5": {} } } } }; const next = applyProviderAuthConfigPatch(base, patch); expect(next.agents?.defaults?.models).toEqual({ ...base.agents.defaults.models, - "openai-codex/gpt-5.4": {}, + "openai-codex/gpt-5.5": {}, }); expect(next.agents?.defaults?.model).toEqual(base.agents.defaults.model); }); diff --git a/src/plugins/provider-runtime.test-support.ts b/src/plugins/provider-runtime.test-support.ts index 9d55be7e8c6..74feb8f6d3b 100644 --- a/src/plugins/provider-runtime.test-support.ts +++ b/src/plugins/provider-runtime.test-support.ts @@ -23,6 +23,15 @@ export const expectedAugmentedOpenaiCodexCatalogEntries = [ }, ]; +export const expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55 = [ + { provider: "openai", id: "gpt-5.5", name: "gpt-5.5" }, + { provider: "openai", id: "gpt-5.5-pro", name: "gpt-5.5-pro" }, + ...expectedAugmentedOpenaiCodexCatalogEntries.slice(0, 4), + { provider: "openai-codex", id: "gpt-5.5", name: "gpt-5.5" }, + { provider: "openai-codex", id: "gpt-5.5-pro", name: "gpt-5.5-pro" }, + ...expectedAugmentedOpenaiCodexCatalogEntries.slice(4), +]; + export function expectCodexMissingAuthHint( buildProviderMissingAuthMessageWithPlugin: (params: { provider: string; @@ -44,7 +53,7 @@ export function expectCodexMissingAuthHint( listProfileIds: (providerId) => (providerId === "openai-codex" ? ["p1"] : []), }, }), - ).toContain("openai-codex/gpt-5.4"); + ).toContain("openai-codex/gpt-5.5"); } export function expectCodexBuiltInSuppression( @@ -80,6 +89,7 @@ export async function expectAugmentedCodexCatalog( entries: typeof openaiCodexCatalogEntries; }; }) => Promise, + expectedEntries = expectedAugmentedOpenaiCodexCatalogEntries, ) { const result = (await augmentModelCatalogWithProviderPlugins({ env: process.env, @@ -88,8 +98,8 @@ export async function expectAugmentedCodexCatalog( entries: openaiCodexCatalogEntries, }, })) as Array>; - expect(result).toHaveLength(expectedAugmentedOpenaiCodexCatalogEntries.length); - for (const entry of expectedAugmentedOpenaiCodexCatalogEntries) { + expect(result).toHaveLength(expectedEntries.length); + for (const entry of expectedEntries) { expect(result).toContainEqual(expect.objectContaining(entry)); } } diff --git a/src/plugins/provider-runtime.test.ts b/src/plugins/provider-runtime.test.ts index 25a2e7e89eb..748a1b8bc5a 100644 --- a/src/plugins/provider-runtime.test.ts +++ b/src/plugins/provider-runtime.test.ts @@ -943,7 +943,7 @@ describe("provider-runtime", () => { { ...createOpenAiCatalogProviderPlugin({ buildMissingAuthMessage: () => - 'No API key found for provider "openai". Use openai-codex/gpt-5.4.', + 'No API key found for provider "openai". Use openai-codex/gpt-5.5.', buildUnknownModelHint, }), } as ProviderPlugin, diff --git a/src/plugins/status.test.ts b/src/plugins/status.test.ts index fd8955de044..258ad6acaca 100644 --- a/src/plugins/status.test.ts +++ b/src/plugins/status.test.ts @@ -437,7 +437,7 @@ describe("plugin status reports", () => { enabled: true, subagent: { allowModelOverride: true, - allowedModels: ["openai/gpt-5.4"], + allowedModels: ["openai/gpt-5.5"], hasAllowedModelsConfig: true, }, }, @@ -467,7 +467,7 @@ describe("plugin status reports", () => { expectInspectPolicy(inspect!, { allowPromptInjection: undefined, allowModelOverride: true, - allowedModels: ["openai/gpt-5.4"], + allowedModels: ["openai/gpt-5.5"], hasAllowedModelsConfig: true, }); expectPluginLoaderCall({ loadModules: true }); @@ -586,7 +586,7 @@ describe("plugin status reports", () => { hooks: { allowPromptInjection: false }, subagent: { allowModelOverride: true, - allowedModels: ["openai/gpt-5.4"], + allowedModels: ["openai/gpt-5.5"], }, }, }, @@ -624,7 +624,7 @@ describe("plugin status reports", () => { expectInspectPolicy(inspect!, { allowPromptInjection: false, allowModelOverride: true, - allowedModels: ["openai/gpt-5.4"], + allowedModels: ["openai/gpt-5.5"], hasAllowedModelsConfig: true, }); expect(inspect?.diagnostics).toEqual([ diff --git a/test/helpers/auto-reply/trigger-handling-test-harness.ts b/test/helpers/auto-reply/trigger-handling-test-harness.ts index 7f3c451cd1c..2058acdef94 100644 --- a/test/helpers/auto-reply/trigger-handling-test-harness.ts +++ b/test/helpers/auto-reply/trigger-handling-test-harness.ts @@ -99,8 +99,8 @@ const modelCatalogMocks = getSharedMocks("openclaw.trigger-handling.model-catalo contextWindow: 200000, }, { provider: "openai", id: "gpt-4.1-mini", name: "GPT-4.1 mini" }, - { provider: "openai", id: "gpt-5.4", name: "GPT-5.2" }, - { provider: "openai-codex", id: "gpt-5.4", name: "GPT-5.2 (Codex)" }, + { provider: "openai", id: "gpt-5.5", name: "GPT-5.5" }, + { provider: "openai-codex", id: "gpt-5.5", name: "GPT-5.5 (Codex)" }, { provider: "minimax", id: "MiniMax-M2.7", name: "MiniMax M2.7" }, ]), resetModelCatalogCacheForTest: vi.fn(), diff --git a/test/helpers/plugins/plugin-runtime-mock.ts b/test/helpers/plugins/plugin-runtime-mock.ts index 1b0451559e3..d0c7cb83a9f 100644 --- a/test/helpers/plugins/plugin-runtime-mock.ts +++ b/test/helpers/plugins/plugin-runtime-mock.ts @@ -10,7 +10,7 @@ import { import type { PluginRuntime } from "../../../src/plugins/runtime/types.js"; const DEFAULT_PROVIDER = "openai"; -const DEFAULT_MODEL = "gpt-5.4"; +const DEFAULT_MODEL = "gpt-5.5"; type DeepPartial = { [K in keyof T]?: T[K] extends (...args: never[]) => unknown diff --git a/test/helpers/plugins/provider-auth-contract.ts b/test/helpers/plugins/provider-auth-contract.ts index d38f9e407ff..666c9e7715c 100644 --- a/test/helpers/plugins/provider-auth-contract.ts +++ b/test/helpers/plugins/provider-auth-contract.ts @@ -119,12 +119,12 @@ function buildOpenAICodexOAuthResult(params: { agents: { defaults: { models: { - "openai-codex/gpt-5.4": {}, + "openai-codex/gpt-5.5": {}, }, }, }, }, - defaultModel: "openai-codex/gpt-5.4", + defaultModel: "openai-codex/gpt-5.5", notes: undefined, }; } diff --git a/test/helpers/plugins/provider-catalog.ts b/test/helpers/plugins/provider-catalog.ts index 44b56109515..454a3bb669f 100644 --- a/test/helpers/plugins/provider-catalog.ts +++ b/test/helpers/plugins/provider-catalog.ts @@ -1,5 +1,6 @@ export { expectAugmentedCodexCatalog, + expectedAugmentedOpenaiCodexCatalogEntriesWithGpt55, expectCodexBuiltInSuppression, expectCodexMissingAuthHint, } from "../../../src/plugins/provider-runtime.test-support.js"; diff --git a/test/helpers/plugins/provider-runtime-contract.ts b/test/helpers/plugins/provider-runtime-contract.ts index 152d8a9c891..756a8404934 100644 --- a/test/helpers/plugins/provider-runtime-contract.ts +++ b/test/helpers/plugins/provider-runtime-contract.ts @@ -445,6 +445,34 @@ export function describeOpenAIProviderRuntimeContract(load: ProviderRuntimeContr }); }); + it("owns openai gpt-5.5 forward-compat resolution", () => { + const provider = requireProviderContractProvider("openai"); + const model = provider.resolveDynamicModel?.({ + provider: "openai", + modelId: "gpt-5.5", + modelRegistry: { + find: (_provider: string, id: string) => + id === "gpt-5.4" + ? createModel({ + id, + provider: "openai", + baseUrl: "https://api.openai.com/v1", + input: ["text", "image"], + }) + : null, + } as never, + }); + + expect(model).toMatchObject({ + id: "gpt-5.5", + provider: "openai", + api: "openai-responses", + baseUrl: "https://api.openai.com/v1", + contextWindow: 1_000_000, + maxTokens: 128_000, + }); + }); + it("owns openai gpt-5.4 mini forward-compat resolution", () => { const provider = requireProviderContractProvider("openai"); const model = provider.resolveDynamicModel?.({ @@ -542,6 +570,34 @@ export function describeOpenAIProviderRuntimeContract(load: ProviderRuntimeContr }); }); + it("owns forward-compat codex gpt-5.5 models", () => { + const provider = requireProviderContractProvider("openai-codex"); + const model = provider.resolveDynamicModel?.({ + provider: "openai-codex", + modelId: "gpt-5.5", + modelRegistry: { + find: (_provider: string, id: string) => + id === "gpt-5.4" + ? createModel({ + id, + api: "openai-codex-responses", + provider: "openai-codex", + baseUrl: "https://chatgpt.com/backend-api", + }) + : null, + } as never, + }); + + expect(model).toMatchObject({ + id: "gpt-5.5", + provider: "openai-codex", + api: "openai-codex-responses", + contextWindow: 1_000_000, + contextTokens: 272_000, + maxTokens: 128_000, + }); + }); + it("owns forward-compat codex mini models", () => { const provider = requireProviderContractProvider("openai-codex"); const model = provider.resolveDynamicModel?.({ diff --git a/ui/src/ui/views/agents-utils.test.ts b/ui/src/ui/views/agents-utils.test.ts index 7ef10c38ef0..300f297e25f 100644 --- a/ui/src/ui/views/agents-utils.test.ts +++ b/ui/src/ui/views/agents-utils.test.ts @@ -183,7 +183,7 @@ describe("buildAgentContext", () => { id: "main", workspace: "/tmp/agent-workspace", model: { - primary: "openai/gpt-5.4", + primary: "openai/gpt-5.5", fallbacks: ["openai-codex/gpt-5.2-codex"], }, }, @@ -194,7 +194,7 @@ describe("buildAgentContext", () => { ); expect(context.workspace).toBe("/tmp/agent-workspace"); - expect(context.model).toBe("openai/gpt-5.4 (+1 fallback)"); + expect(context.model).toBe("openai/gpt-5.5 (+1 fallback)"); expect(context.isDefault).toBe(true); }); @@ -206,7 +206,7 @@ describe("buildAgentContext", () => { defaults: { workspace: "/tmp/default-workspace", model: { - primary: "openai/gpt-5.4", + primary: "openai/gpt-5.5", fallbacks: ["openai-codex/gpt-5.2-codex"], }, }, @@ -219,6 +219,6 @@ describe("buildAgentContext", () => { ); expect(context.workspace).toBe("/tmp/default-workspace"); - expect(context.model).toBe("openai/gpt-5.4 (+1 fallback)"); + expect(context.model).toBe("openai/gpt-5.5 (+1 fallback)"); }); }); diff --git a/ui/src/ui/views/config-quick.test.ts b/ui/src/ui/views/config-quick.test.ts index bb73e96f27e..3b6f708559a 100644 --- a/ui/src/ui/views/config-quick.test.ts +++ b/ui/src/ui/views/config-quick.test.ts @@ -6,7 +6,7 @@ import { renderQuickSettings, type QuickSettingsProps } from "./config-quick.ts" function createProps(overrides: Partial = {}): QuickSettingsProps { return { - currentModel: "gpt-5.4", + currentModel: "gpt-5.5", thinkingLevel: "off", fastMode: false, onModelChange: vi.fn(),