diff --git a/CHANGELOG.md b/CHANGELOG.md index 2515fd9040f9..ba1a8d00ad01 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,7 +54,7 @@ Docs: https://docs.openclaw.ai ### Fixes -- Models: prune retired GitHub Copilot model rows and old Claude catalog entries below 4.6, with doctor migration to upgrade existing configs to current Claude/Copilot refs. +- Models: prune retired Groq, GitHub Copilot, OpenAI, xAI, and old Claude catalog entries, with doctor migration to upgrade existing configs to current provider refs. - Doctor/update: recognize junction-backed source checkouts as git installs by comparing canonical paths before showing package-manager update guidance. Fixes #82215. Thanks @igormf. - CLI/skills: show an all-ready note with next-step commands when skill setup has no missing dependencies to install. (#85032) Thanks @aniruddhaadak80. - Microsoft Foundry: route DeepSeek V4 Pro and Flash models through the Foundry Responses API while keeping older DeepSeek models on their existing path. (#85549) Thanks @roslinmahmud. diff --git a/docs/cli/infer.md b/docs/cli/infer.md index 98f8b5b905e6..58d11d49922c 100644 --- a/docs/cli/infer.md +++ b/docs/cli/infer.md @@ -163,7 +163,7 @@ openclaw infer model run --local --model google/gemini-2.5-flash --prompt "Reply openclaw infer model run --local --model groq/llama-3.1-8b-instant --prompt "Reply with exactly: pong" --json openclaw infer model run --local --model mistral/mistral-medium-3-5 --prompt "Reply with exactly: pong" --json openclaw infer model run --local --model mistral/mistral-small-latest --prompt "Reply with exactly: pong" --json -openclaw infer model run --local --model openai/gpt-4.1 --prompt "Reply with exactly: pong" --json +openclaw infer model run --local --model openai/gpt-5.5 --prompt "Reply with exactly: pong" --json openclaw infer model run --local --model ollama/qwen2.5vl:7b --prompt "Describe this image." --file ./photo.jpg --json ``` @@ -196,7 +196,7 @@ openclaw infer image describe --file ./photo.jpg --json openclaw infer image describe --file https://example.com/photo.png --json openclaw infer image describe --file ./receipt.jpg --prompt "Extract the merchant, date, and total" --json openclaw infer image describe-many --file ./before.png --file ./after.png --prompt "Compare the screenshots and list visible UI changes" --json -openclaw infer image describe --file ./ui-screenshot.png --model openai/gpt-4.1-mini --json +openclaw infer image describe --file ./ui-screenshot.png --model openai/gpt-5.4-mini --json openclaw infer image describe --file ./photo.jpg --model ollama/qwen2.5vl:7b --prompt "Describe the image in one sentence" --timeout-ms 300000 --json ``` @@ -272,7 +272,7 @@ Use `video` for generation and description. openclaw infer video generate --prompt "cinematic sunset over the ocean" --json openclaw infer video generate --prompt "slow drone shot over a forest lake" --resolution 768P --duration 6 --json openclaw infer video describe --file ./clip.mp4 --json -openclaw infer video describe --file ./clip.mp4 --model openai/gpt-4.1-mini --json +openclaw infer video describe --file ./clip.mp4 --model openai/gpt-5.4-mini --json ``` Notes: diff --git a/docs/gateway/config-agents.md b/docs/gateway/config-agents.md index 7eca7de5eb38..2ae97cf09af5 100644 --- a/docs/gateway/config-agents.md +++ b/docs/gateway/config-agents.md @@ -1397,7 +1397,7 @@ Batches rapid text-only messages from the same sender into a single agent turn. auto: "always", // off | always | inbound | tagged mode: "final", // final | all provider: "elevenlabs", - summaryModel: "openai/gpt-4.1-mini", + summaryModel: "openai/gpt-5.4-mini", modelOverrides: { enabled: true }, maxTextLength: 4000, timeoutMs: 30000, diff --git a/docs/gateway/config-channels.md b/docs/gateway/config-channels.md index 39cee68bac65..4aef409143f6 100644 --- a/docs/gateway/config-channels.md +++ b/docs/gateway/config-channels.md @@ -53,10 +53,10 @@ Use `channels.modelByChannel` to pin specific channel IDs to a model. Values acc "123456789012345678": "anthropic/claude-opus-4-6", }, slack: { - C1234567890: "openai/gpt-4.1", + C1234567890: "openai/gpt-5.5", }, telegram: { - "-1001234567890": "openai/gpt-4.1-mini", + "-1001234567890": "openai/gpt-5.4-mini", "-1001234567890:topic:99": "anthropic/claude-sonnet-4-6", }, }, diff --git a/docs/providers/github-copilot.md b/docs/providers/github-copilot.md index fb9f9ac14809..e0beb60fad34 100644 --- a/docs/providers/github-copilot.md +++ b/docs/providers/github-copilot.md @@ -99,7 +99,7 @@ back to `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, then `GITHUB_TOKEN`. Use Copilot model availability depends on your GitHub plan. If a model is - rejected, try another ID (for example `github-copilot/gpt-4.1`). See + rejected, try another ID (for example `github-copilot/gpt-5.5`). See GitHub's [supported models per Copilot plan](https://docs.github.com/en/copilot/reference/ai-models/supported-models#supported-ai-models-per-copilot-plan) for the current model list. diff --git a/docs/providers/groq.md b/docs/providers/groq.md index 2019058753f2..99dbd8287a5f 100644 --- a/docs/providers/groq.md +++ b/docs/providers/groq.md @@ -75,26 +75,17 @@ export GROQ_API_KEY=gsk_... OpenClaw ships a manifest-backed Groq catalog with both reasoning and non-reasoning entries. Run `openclaw models list --provider groq` to see the bundled rows for your installed version, or check [console.groq.com/docs/models](https://console.groq.com/docs/models) for Groq's authoritative list. -| Model ref | Name | Reasoning | Input | Context | -| ---------------------------------------------------- | ----------------------------- | --------- | ------------ | ------- | -| `groq/llama-3.3-70b-versatile` | Llama 3.3 70B Versatile | no | text | 131,072 | -| `groq/llama-3.1-8b-instant` | Llama 3.1 8B Instant | no | text | 131,072 | -| `groq/meta-llama/llama-4-maverick-17b-128e-instruct` | Llama 4 Maverick 17B | no | text + image | 131,072 | -| `groq/meta-llama/llama-4-scout-17b-16e-instruct` | Llama 4 Scout 17B | no | text + image | 131,072 | -| `groq/llama3-70b-8192` | Llama 3 70B | no | text | 8,192 | -| `groq/llama3-8b-8192` | Llama 3 8B | no | text | 8,192 | -| `groq/gemma2-9b-it` | Gemma 2 9B | no | text | 8,192 | -| `groq/mistral-saba-24b` | Mistral Saba 24B | no | text | 32,768 | -| `groq/moonshotai/kimi-k2-instruct` | Kimi K2 Instruct | no | text | 131,072 | -| `groq/moonshotai/kimi-k2-instruct-0905` | Kimi K2 Instruct 0905 | no | text | 262,144 | -| `groq/openai/gpt-oss-120b` | GPT OSS 120B | yes | text | 131,072 | -| `groq/openai/gpt-oss-20b` | GPT OSS 20B | yes | text | 131,072 | -| `groq/openai/gpt-oss-safeguard-20b` | Safety GPT OSS 20B | yes | text | 131,072 | -| `groq/qwen-qwq-32b` | Qwen QwQ 32B | yes | text | 131,072 | -| `groq/qwen/qwen3-32b` | Qwen3 32B | yes | text | 131,072 | -| `groq/deepseek-r1-distill-llama-70b` | DeepSeek R1 Distill Llama 70B | yes | text | 131,072 | -| `groq/groq/compound` | Compound | yes | text | 131,072 | -| `groq/groq/compound-mini` | Compound Mini | yes | text | 131,072 | +| Model ref | Name | Reasoning | Input | Context | +| ------------------------------------------------ | ----------------------- | --------- | ------------ | ------- | +| `groq/llama-3.3-70b-versatile` | Llama 3.3 70B Versatile | no | text | 131,072 | +| `groq/llama-3.1-8b-instant` | Llama 3.1 8B Instant | no | text | 131,072 | +| `groq/meta-llama/llama-4-scout-17b-16e-instruct` | Llama 4 Scout 17B | no | text + image | 131,072 | +| `groq/openai/gpt-oss-120b` | GPT OSS 120B | yes | text | 131,072 | +| `groq/openai/gpt-oss-20b` | GPT OSS 20B | yes | text | 131,072 | +| `groq/openai/gpt-oss-safeguard-20b` | Safety GPT OSS 20B | yes | text | 131,072 | +| `groq/qwen/qwen3-32b` | Qwen3 32B | yes | text | 131,072 | +| `groq/groq/compound` | Compound | yes | text | 131,072 | +| `groq/groq/compound-mini` | Compound Mini | yes | text | 131,072 | The catalog evolves with each OpenClaw release. `openclaw models list --provider groq` shows the rows known to your installed version; cross-check with [console.groq.com/docs/models](https://console.groq.com/docs/models) for newly-added or deprecated models. diff --git a/extensions/codex/provider-catalog.ts b/extensions/codex/provider-catalog.ts index 76a4ac4df2bc..b24f134befa4 100644 --- a/extensions/codex/provider-catalog.ts +++ b/extensions/codex/provider-catalog.ts @@ -29,13 +29,6 @@ export const FALLBACK_CODEX_MODELS = [ inputModalities: ["text", "image"], supportedReasoningEfforts: ["low", "medium", "high", "xhigh"], }, - { - id: "gpt-5.2", - model: "gpt-5.2", - displayName: "gpt-5.2", - inputModalities: ["text", "image"], - supportedReasoningEfforts: ["low", "medium", "high", "xhigh"], - }, ] satisfies CodexAppServerModel[]; export function buildCodexModelDefinition(model: { diff --git a/extensions/codex/provider.test.ts b/extensions/codex/provider.test.ts index fc48d7b4677b..8a2788004dc6 100644 --- a/extensions/codex/provider.test.ts +++ b/extensions/codex/provider.test.ts @@ -16,11 +16,7 @@ afterEach(() => { function expectStaticFallbackCatalog( result: Awaited>, ) { - expect(result.provider.models.map((model) => model.id)).toEqual([ - "gpt-5.5", - "gpt-5.4-mini", - "gpt-5.2", - ]); + expect(result.provider.models.map((model) => model.id)).toEqual(["gpt-5.5", "gpt-5.4-mini"]); } function createFakeCodexClient(): CodexAppServerClient { @@ -170,8 +166,8 @@ describe("codex provider", () => { .mockResolvedValueOnce({ models: [ { - id: "gpt-5.2", - model: "gpt-5.2", + id: "gpt-5.5", + model: "gpt-5.5", hidden: false, inputModalities: ["text"], supportedReasoningEfforts: [], @@ -194,7 +190,7 @@ describe("codex provider", () => { limit: 100, sharedClient: false, }); - expect(result.provider.models.map((model) => model.id)).toEqual(["gpt-5.4", "gpt-5.2"]); + expect(result.provider.models.map((model) => model.id)).toEqual(["gpt-5.4", "gpt-5.5"]); }); it("reports discovery failures before using the fallback catalog", async () => { @@ -353,7 +349,7 @@ describe("codex provider", () => { expect( result && "provider" in result ? result.provider.models.map((model) => model.id) : [], - ).toEqual(["gpt-5.5", "gpt-5.4-mini", "gpt-5.2"]); + ).toEqual(["gpt-5.5", "gpt-5.4-mini"]); }); it("adds the GPT-5 prompt overlay to Codex provider runs", () => { diff --git a/extensions/codex/provider.ts b/extensions/codex/provider.ts index 231a35f5d7bd..f79147663c4f 100644 --- a/extensions/codex/provider.ts +++ b/extensions/codex/provider.ts @@ -237,7 +237,5 @@ function isKnownXHighCodexModel(modelId: string): boolean { // CLI default. (#71946) export function isModernCodexModel(modelId: string): boolean { const lower = modelId.trim().toLowerCase(); - return ( - lower === "gpt-5.5" || lower === "gpt-5.4" || lower === "gpt-5.4-mini" || lower === "gpt-5.2" - ); + return lower === "gpt-5.5" || lower === "gpt-5.4" || lower === "gpt-5.4-mini"; } diff --git a/extensions/codex/src/app-server/models.test.ts b/extensions/codex/src/app-server/models.test.ts index 229a2a00a7a2..0c1f785f9f41 100644 --- a/extensions/codex/src/app-server/models.test.ts +++ b/extensions/codex/src/app-server/models.test.ts @@ -172,13 +172,13 @@ describe("listCodexAppServerModels", () => { result: { data: [ { - id: "gpt-5.2", - model: "gpt-5.2", + id: "gpt-5.5", + model: "gpt-5.5", upgrade: null, upgradeInfo: null, availabilityNux: null, - displayName: "gpt-5.2", - description: "GPT-5.2", + displayName: "gpt-5.5", + description: "GPT-5.5", hidden: false, inputModalities: ["text", "image"], supportedReasoningEfforts: [], @@ -193,7 +193,7 @@ describe("listCodexAppServerModels", () => { }); const list = await listPromise; - expect(list.models.map((model) => model.id)).toEqual(["gpt-5.4", "gpt-5.2"]); + expect(list.models.map((model) => model.id)).toEqual(["gpt-5.4", "gpt-5.5"]); harness.client.close(); startSpy.mockRestore(); }); diff --git a/extensions/codex/src/app-server/thread-lifecycle.test.ts b/extensions/codex/src/app-server/thread-lifecycle.test.ts index c74d826443de..80dff338e5a9 100644 --- a/extensions/codex/src/app-server/thread-lifecycle.test.ts +++ b/extensions/codex/src/app-server/thread-lifecycle.test.ts @@ -421,14 +421,14 @@ describe("Codex app-server model provider selection", () => { describe("resolveReasoningEffort (#71946)", () => { describe("modern Codex models (none/low/medium/high/xhigh enum)", () => { - it.each(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.2"] as const)( + it.each(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"] as const)( "translates 'minimal' -> 'low' for %s so the first request is accepted", (modelId) => { expect(resolveReasoningEffort("minimal", modelId)).toBe("low"); }, ); - it.each(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.2"] as const)( + it.each(["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"] as const)( "passes 'low' / 'medium' / 'high' / 'xhigh' through unchanged for %s", (modelId) => { expect(resolveReasoningEffort("low", modelId)).toBe("low"); diff --git a/extensions/codex/src/app-server/thread-lifecycle.ts b/extensions/codex/src/app-server/thread-lifecycle.ts index 5481af8af55c..5833bf11efe7 100644 --- a/extensions/codex/src/app-server/thread-lifecycle.ts +++ b/extensions/codex/src/app-server/thread-lifecycle.ts @@ -979,7 +979,7 @@ export function resolveCodexAppServerModelProvider(params: { return normalizedLower === "openai-codex" ? "openai" : normalized; } -// Modern Codex models (gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.2) use the +// Modern Codex models (gpt-5.5, gpt-5.4, gpt-5.4-mini) use the // none/low/medium/high/xhigh effort enum and reject "minimal". The CLI // defaults thinkLevel to "minimal", so without translation EVERY agent turn // on those models pays a wasted first request + retry-with-low fallback in diff --git a/extensions/github-copilot/index.ts b/extensions/github-copilot/index.ts index da1bd97fab19..902959f8f432 100644 --- a/extensions/github-copilot/index.ts +++ b/extensions/github-copilot/index.ts @@ -34,7 +34,7 @@ import { wrapCopilotProviderStream } from "./stream.js"; const COPILOT_ENV_VARS = ["COPILOT_GITHUB_TOKEN", "GH_TOKEN", "GITHUB_TOKEN"]; const DEFAULT_COPILOT_MODEL = "github-copilot/claude-opus-4.7"; const DEFAULT_COPILOT_PROFILE_ID = "github-copilot:github"; -const COPILOT_XHIGH_MODEL_IDS = ["gpt-5.4", "gpt-5.3-codex", "gpt-5.2", "gpt-5.2-codex"] as const; +const COPILOT_XHIGH_MODEL_IDS = ["gpt-5.4", "gpt-5.3-codex"] as const; type GithubCopilotPluginConfig = { discovery?: { diff --git a/extensions/github-copilot/models-defaults.ts b/extensions/github-copilot/models-defaults.ts index 6adeecab90e1..6b082beb3b20 100644 --- a/extensions/github-copilot/models-defaults.ts +++ b/extensions/github-copilot/models-defaults.ts @@ -18,10 +18,6 @@ const DEFAULT_MODEL_IDS = [ "gemini-2.5-pro", "gemini-3-flash", "gemini-3.1-pro", - "gpt-4.1", - "gpt-5-mini", - "gpt-5.2", - "gpt-5.2-codex", "gpt-5.3-codex", "gpt-5.4", "gpt-5.4-mini", diff --git a/extensions/github-copilot/models.test.ts b/extensions/github-copilot/models.test.ts index afd2298a0104..651ed06cb42f 100644 --- a/extensions/github-copilot/models.test.ts +++ b/extensions/github-copilot/models.test.ts @@ -148,17 +148,17 @@ describe("resolveCopilotForwardCompatModel", () => { expect(resolveCopilotForwardCompatModel(ctx)).toBeUndefined(); }); - it("clones gpt-5.2-codex template for gpt-5.4", () => { + it("clones gpt-5.3-codex template for gpt-5.4", () => { const template = { - id: "gpt-5.2-codex", - name: "gpt-5.2-codex", + id: "gpt-5.3-codex", + name: "gpt-5.3-codex", provider: "github-copilot", api: "openai-responses", reasoning: true, contextWindow: 200_000, }; const ctx = createMockCtx("gpt-5.4", { - "github-copilot/gpt-5.2-codex": template, + "github-copilot/gpt-5.3-codex": template, }); const result = requireResolvedModel(ctx); expect(result.id).toBe("gpt-5.4"); @@ -166,25 +166,15 @@ describe("resolveCopilotForwardCompatModel", () => { expect((result as unknown as Record).reasoning).toBe(true); }); - it("clones gpt-5.3-codex template for gpt-5.3-codex when not in registry", () => { - const template = { - id: "gpt-5.2-codex", - name: "gpt-5.2-codex", - provider: "github-copilot", - api: "openai-responses", - reasoning: true, - contextWindow: 200_000, - }; - const ctx = createMockCtx("gpt-5.3-codex", { - "github-copilot/gpt-5.2-codex": template, - }); + it("uses static metadata for gpt-5.3-codex when not in registry", () => { + const ctx = createMockCtx("gpt-5.3-codex"); const result = requireResolvedModel(ctx); expect(result.id).toBe("gpt-5.3-codex"); expect(result.name).toBe("gpt-5.3-codex"); expect((result as unknown as Record).reasoning).toBe(true); }); - it("prefers gpt-5.3-codex as template source over gpt-5.2-codex for gpt-5.4", () => { + it("uses gpt-5.3-codex as the template source for gpt-5.4", () => { const template53 = { id: "gpt-5.3-codex", name: "gpt-5.3-codex", @@ -193,17 +183,8 @@ describe("resolveCopilotForwardCompatModel", () => { reasoning: true, contextWindow: 300_000, }; - const template52 = { - id: "gpt-5.2-codex", - name: "gpt-5.2-codex", - provider: "github-copilot", - api: "openai-responses", - reasoning: true, - contextWindow: 200_000, - }; const ctx = createMockCtx("gpt-5.4", { "github-copilot/gpt-5.3-codex": template53, - "github-copilot/gpt-5.2-codex": template52, }); const result = requireResolvedModel(ctx); expect(result.id).toBe("gpt-5.4"); diff --git a/extensions/github-copilot/models.ts b/extensions/github-copilot/models.ts index 8dc6bf72337e..de35b7f17bc2 100644 --- a/extensions/github-copilot/models.ts +++ b/extensions/github-copilot/models.ts @@ -17,7 +17,7 @@ export const PROVIDER_ID = "github-copilot"; const CODEX_FORWARD_COMPAT_TARGET_IDS = new Set(["gpt-5.4", "gpt-5.3-codex"]); // gpt-5.3-codex is only a useful template when gpt-5.4 is the target; it is // always a registry miss (and therefore skipped) when it is the target itself. -const CODEX_TEMPLATE_MODEL_IDS = ["gpt-5.3-codex", "gpt-5.2-codex"] as const; +const CODEX_TEMPLATE_MODEL_IDS = ["gpt-5.3-codex"] as const; const DEFAULT_CONTEXT_WINDOW = 128_000; const DEFAULT_MAX_TOKENS = 8192; diff --git a/extensions/github-copilot/openclaw.plugin.json b/extensions/github-copilot/openclaw.plugin.json index 8282f5abf0e8..812962b42b84 100644 --- a/extensions/github-copilot/openclaw.plugin.json +++ b/extensions/github-copilot/openclaw.plugin.json @@ -75,41 +75,6 @@ "maxTokens": 8192, "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } }, - { - "id": "gpt-4.1", - "name": "GPT-4.1", - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 8192, - "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } - }, - { - "id": "gpt-5-mini", - "name": "GPT-5 mini", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 8192, - "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } - }, - { - "id": "gpt-5.2", - "name": "GPT-5.2", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 8192, - "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } - }, - { - "id": "gpt-5.2-codex", - "name": "GPT-5.2-Codex", - "reasoning": true, - "input": ["text"], - "contextWindow": 128000, - "maxTokens": 8192, - "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 } - }, { "id": "gpt-5.3-codex", "name": "GPT-5.3-Codex", diff --git a/extensions/groq/openclaw.plugin.json b/extensions/groq/openclaw.plugin.json index c1723b9771b0..1e4ec2ab5845 100644 --- a/extensions/groq/openclaw.plugin.json +++ b/extensions/groq/openclaw.plugin.json @@ -33,34 +33,6 @@ "baseUrl": "https://api.groq.com/openai/v1", "api": "openai-completions", "models": [ - { - "id": "deepseek-r1-distill-llama-70b", - "name": "DeepSeek R1 Distill Llama 70B", - "reasoning": true, - "input": ["text"], - "contextWindow": 131072, - "maxTokens": 8192, - "cost": { - "input": 0.75, - "output": 0.99, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "gemma2-9b-it", - "name": "Gemma 2 9B", - "reasoning": false, - "input": ["text"], - "contextWindow": 8192, - "maxTokens": 8192, - "cost": { - "input": 0.2, - "output": 0.2, - "cacheRead": 0, - "cacheWrite": 0 - } - }, { "id": "groq/compound", "name": "Compound", @@ -117,48 +89,6 @@ "cacheWrite": 0 } }, - { - "id": "llama3-70b-8192", - "name": "Llama 3 70B", - "reasoning": false, - "input": ["text"], - "contextWindow": 8192, - "maxTokens": 8192, - "cost": { - "input": 0.59, - "output": 0.79, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "llama3-8b-8192", - "name": "Llama 3 8B", - "reasoning": false, - "input": ["text"], - "contextWindow": 8192, - "maxTokens": 8192, - "cost": { - "input": 0.05, - "output": 0.08, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "meta-llama/llama-4-maverick-17b-128e-instruct", - "name": "Llama 4 Maverick 17B", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 131072, - "maxTokens": 8192, - "cost": { - "input": 0.2, - "output": 0.6, - "cacheRead": 0, - "cacheWrite": 0 - } - }, { "id": "meta-llama/llama-4-scout-17b-16e-instruct", "name": "Llama 4 Scout 17B", @@ -173,48 +103,6 @@ "cacheWrite": 0 } }, - { - "id": "mistral-saba-24b", - "name": "Mistral Saba 24B", - "reasoning": false, - "input": ["text"], - "contextWindow": 32768, - "maxTokens": 32768, - "cost": { - "input": 0.79, - "output": 0.79, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "moonshotai/kimi-k2-instruct", - "name": "Kimi K2 Instruct", - "reasoning": false, - "input": ["text"], - "contextWindow": 131072, - "maxTokens": 16384, - "cost": { - "input": 1, - "output": 3, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "moonshotai/kimi-k2-instruct-0905", - "name": "Kimi K2 Instruct 0905", - "reasoning": false, - "input": ["text"], - "contextWindow": 262144, - "maxTokens": 16384, - "cost": { - "input": 1, - "output": 3, - "cacheRead": 0, - "cacheWrite": 0 - } - }, { "id": "openai/gpt-oss-120b", "name": "GPT OSS 120B", @@ -257,20 +145,6 @@ "cacheWrite": 0 } }, - { - "id": "qwen-qwq-32b", - "name": "Qwen QwQ 32B", - "reasoning": true, - "input": ["text"], - "contextWindow": 131072, - "maxTokens": 16384, - "cost": { - "input": 0.29, - "output": 0.39, - "cacheRead": 0, - "cacheWrite": 0 - } - }, { "id": "qwen/qwen3-32b", "name": "Qwen3 32B", diff --git a/extensions/openai/openai-codex-provider.ts b/extensions/openai/openai-codex-provider.ts index 58db80eed1be..f13384c2e2d9 100644 --- a/extensions/openai/openai-codex-provider.ts +++ b/extensions/openai/openai-codex-provider.ts @@ -95,7 +95,7 @@ const OPENAI_CODEX_GPT_54_MINI_COST = { cacheRead: 0.075, cacheWrite: 0, } as const; -const OPENAI_CODEX_GPT_54_TEMPLATE_MODEL_IDS = ["gpt-5.3-codex", "gpt-5.2-codex"] as const; +const OPENAI_CODEX_GPT_54_TEMPLATE_MODEL_IDS = ["gpt-5.3-codex"] as const; /** Legacy codex rows first; fall back to catalog `gpt-5.4` when the API omits 5.3/5.2. */ const OPENAI_CODEX_GPT_54_CATALOG_SYNTH_TEMPLATE_MODEL_IDS = [ ...OPENAI_CODEX_GPT_54_TEMPLATE_MODEL_IDS, diff --git a/extensions/openai/openai-provider.test.ts b/extensions/openai/openai-provider.test.ts index 44bdb9de73f3..0029df49e4d3 100644 --- a/extensions/openai/openai-provider.test.ts +++ b/extensions/openai/openai-provider.test.ts @@ -435,7 +435,7 @@ describe("buildOpenAIProvider", () => { expectNoCatalogEntry(entries, "chat-latest"); }); - it("keeps modern live selection on OpenAI 5.2+ and current Codex models", () => { + it("keeps modern live selection on current OpenAI and Codex models", () => { const provider = buildOpenAIProvider(); const codexProvider = buildOpenAICodexProviderPlugin(); @@ -450,7 +450,7 @@ describe("buildOpenAIProvider", () => { provider: "openai", modelId: "gpt-5.2", } as never), - ).toBe(true); + ).toBe(false); expect( provider.isModernModelRef?.({ provider: "openai", diff --git a/extensions/openai/openai-provider.ts b/extensions/openai/openai-provider.ts index 214c4544557b..85358483c62f 100644 --- a/extensions/openai/openai-provider.ts +++ b/extensions/openai/openai-provider.ts @@ -55,17 +55,14 @@ const OPENAI_GPT_54_NANO_COST = { const OPENAI_GPT_55_PRO_TEMPLATE_MODEL_IDS = [ OPENAI_GPT_54_PRO_MODEL_ID, OPENAI_GPT_54_MODEL_ID, - "gpt-5.2-pro", - "gpt-5.2", ] as const; -const OPENAI_GPT_54_TEMPLATE_MODEL_IDS = ["gpt-5.2"] as const; -const OPENAI_GPT_54_PRO_TEMPLATE_MODEL_IDS = ["gpt-5.2-pro", "gpt-5.2"] as const; +const OPENAI_GPT_54_TEMPLATE_MODEL_IDS = [OPENAI_GPT_55_MODEL_ID] as const; +const OPENAI_GPT_54_PRO_TEMPLATE_MODEL_IDS = [OPENAI_GPT_55_PRO_MODEL_ID] as const; const OPENAI_GPT_54_MINI_TEMPLATE_MODEL_IDS = ["gpt-5-mini"] as const; const OPENAI_GPT_54_NANO_TEMPLATE_MODEL_IDS = ["gpt-5-nano", "gpt-5-mini"] as const; const OPENAI_CHAT_LATEST_TEMPLATE_MODEL_IDS = [ OPENAI_GPT_55_MODEL_ID, OPENAI_GPT_54_MODEL_ID, - "gpt-5.2", ] as const; const OPENAI_MODERN_MODEL_IDS = [ OPENAI_CHAT_LATEST_MODEL_ID, @@ -75,7 +72,6 @@ const OPENAI_MODERN_MODEL_IDS = [ OPENAI_GPT_54_PRO_MODEL_ID, OPENAI_GPT_54_MINI_MODEL_ID, OPENAI_GPT_54_NANO_MODEL_ID, - "gpt-5.2", ] as const; function shouldUseOpenAIResponsesTransport(params: { diff --git a/extensions/openai/openclaw.plugin.json b/extensions/openai/openclaw.plugin.json index bf9d53c16b35..0d1e7fa618a5 100644 --- a/extensions/openai/openclaw.plugin.json +++ b/extensions/openai/openclaw.plugin.json @@ -50,356 +50,6 @@ "baseUrl": "https://api.openai.com/v1", "api": "openai-responses", "models": [ - { - "id": "gpt-4", - "name": "GPT-4", - "reasoning": false, - "input": ["text"], - "contextWindow": 8192, - "maxTokens": 8192, - "cost": { - "input": 30, - "output": 60, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4-turbo", - "name": "GPT-4 Turbo", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 4096, - "cost": { - "input": 10, - "output": 30, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4.1", - "name": "GPT-4.1", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 1047576, - "maxTokens": 32768, - "cost": { - "input": 2, - "output": 8, - "cacheRead": 0.5, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4.1-mini", - "name": "GPT-4.1 mini", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 1047576, - "maxTokens": 32768, - "cost": { - "input": 0.4, - "output": 1.6, - "cacheRead": 0.1, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4.1-nano", - "name": "GPT-4.1 nano", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 1047576, - "maxTokens": 32768, - "cost": { - "input": 0.1, - "output": 0.4, - "cacheRead": 0.03, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4o", - "name": "GPT-4o", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 2.5, - "output": 10, - "cacheRead": 1.25, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4o-2024-05-13", - "name": "GPT-4o (2024-05-13)", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 4096, - "cost": { - "input": 5, - "output": 15, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4o-2024-08-06", - "name": "GPT-4o (2024-08-06)", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 2.5, - "output": 10, - "cacheRead": 1.25, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4o-2024-11-20", - "name": "GPT-4o (2024-11-20)", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 2.5, - "output": 10, - "cacheRead": 1.25, - "cacheWrite": 0 - } - }, - { - "id": "gpt-4o-mini", - "name": "GPT-4o mini", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 0.15, - "output": 0.6, - "cacheRead": 0.08, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5", - "name": "GPT-5", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5-chat-latest", - "name": "GPT-5 Chat Latest", - "reasoning": false, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5-codex", - "name": "GPT-5-Codex", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5-mini", - "name": "GPT-5 Mini", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 0.25, - "output": 2, - "cacheRead": 0.025, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5-nano", - "name": "GPT-5 Nano", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 0.05, - "output": 0.4, - "cacheRead": 0.005, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5-pro", - "name": "GPT-5 Pro", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 272000, - "cost": { - "input": 15, - "output": 120, - "cacheRead": 0, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.1", - "name": "GPT-5.1", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.13, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.1-chat-latest", - "name": "GPT-5.1 Chat", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.1-codex", - "name": "GPT-5.1 Codex", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.1-codex-max", - "name": "GPT-5.1 Codex Max", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.25, - "output": 10, - "cacheRead": 0.125, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.1-codex-mini", - "name": "GPT-5.1 Codex mini", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 0.25, - "output": 2, - "cacheRead": 0.025, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.2", - "name": "GPT-5.2", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.75, - "output": 14, - "cacheRead": 0.175, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.2-chat-latest", - "name": "GPT-5.2 Chat", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 128000, - "maxTokens": 16384, - "cost": { - "input": 1.75, - "output": 14, - "cacheRead": 0.175, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.2-codex", - "name": "GPT-5.2 Codex", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 1.75, - "output": 14, - "cacheRead": 0.175, - "cacheWrite": 0 - } - }, - { - "id": "gpt-5.2-pro", - "name": "GPT-5.2 Pro", - "reasoning": true, - "input": ["text", "image"], - "contextWindow": 400000, - "maxTokens": 128000, - "cost": { - "input": 21, - "output": 168, - "cacheRead": 0, - "cacheWrite": 0 - } - }, { "id": "gpt-5.3-chat-latest", "name": "GPT-5.3 Chat (latest)", @@ -407,12 +57,7 @@ "input": ["text", "image"], "contextWindow": 128000, "maxTokens": 16384, - "cost": { - "input": 1.75, - "output": 14, - "cacheRead": 0.175, - "cacheWrite": 0 - } + "cost": { "input": 1.75, "output": 14, "cacheRead": 0.175, "cacheWrite": 0 } }, { "id": "gpt-5.3-codex", @@ -421,12 +66,7 @@ "input": ["text", "image"], "contextWindow": 400000, "maxTokens": 128000, - "cost": { - "input": 1.75, - "output": 14, - "cacheRead": 0.175, - "cacheWrite": 0 - } + "cost": { "input": 1.75, "output": 14, "cacheRead": 0.175, "cacheWrite": 0 } }, { "id": "gpt-5.4", @@ -435,12 +75,7 @@ "input": ["text", "image"], "contextWindow": 272000, "maxTokens": 128000, - "cost": { - "input": 2.5, - "output": 15, - "cacheRead": 0.25, - "cacheWrite": 0 - } + "cost": { "input": 2.5, "output": 15, "cacheRead": 0.25, "cacheWrite": 0 } }, { "id": "gpt-5.4-mini", @@ -449,12 +84,7 @@ "input": ["text", "image"], "contextWindow": 400000, "maxTokens": 128000, - "cost": { - "input": 0.75, - "output": 4.5, - "cacheRead": 0.075, - "cacheWrite": 0 - } + "cost": { "input": 0.75, "output": 4.5, "cacheRead": 0.075, "cacheWrite": 0 } }, { "id": "gpt-5.4-nano", @@ -463,12 +93,7 @@ "input": ["text", "image"], "contextWindow": 400000, "maxTokens": 128000, - "cost": { - "input": 0.2, - "output": 1.25, - "cacheRead": 0.02, - "cacheWrite": 0 - } + "cost": { "input": 0.2, "output": 1.25, "cacheRead": 0.02, "cacheWrite": 0 } }, { "id": "gpt-5.4-pro", @@ -477,12 +102,7 @@ "input": ["text", "image"], "contextWindow": 1050000, "maxTokens": 128000, - "cost": { - "input": 30, - "output": 180, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 30, "output": 180, "cacheRead": 0, "cacheWrite": 0 } }, { "id": "gpt-5.5", @@ -491,12 +111,7 @@ "input": ["text", "image"], "contextWindow": 272000, "maxTokens": 128000, - "cost": { - "input": 5, - "output": 30, - "cacheRead": 0.5, - "cacheWrite": 0 - } + "cost": { "input": 5, "output": 30, "cacheRead": 0.5, "cacheWrite": 0 } }, { "id": "o1", @@ -505,12 +120,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 15, - "output": 60, - "cacheRead": 7.5, - "cacheWrite": 0 - } + "cost": { "input": 15, "output": 60, "cacheRead": 7.5, "cacheWrite": 0 } }, { "id": "o1-pro", @@ -519,12 +129,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 150, - "output": 600, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 150, "output": 600, "cacheRead": 0, "cacheWrite": 0 } }, { "id": "o3", @@ -533,12 +138,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 2, - "output": 8, - "cacheRead": 0.5, - "cacheWrite": 0 - } + "cost": { "input": 2, "output": 8, "cacheRead": 0.5, "cacheWrite": 0 } }, { "id": "o3-deep-research", @@ -547,12 +147,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 10, - "output": 40, - "cacheRead": 2.5, - "cacheWrite": 0 - } + "cost": { "input": 10, "output": 40, "cacheRead": 2.5, "cacheWrite": 0 } }, { "id": "o3-mini", @@ -561,12 +156,7 @@ "input": ["text"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 1.1, - "output": 4.4, - "cacheRead": 0.55, - "cacheWrite": 0 - } + "cost": { "input": 1.1, "output": 4.4, "cacheRead": 0.55, "cacheWrite": 0 } }, { "id": "o3-pro", @@ -575,12 +165,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 20, - "output": 80, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 20, "output": 80, "cacheRead": 0, "cacheWrite": 0 } }, { "id": "o4-mini", @@ -589,12 +174,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 1.1, - "output": 4.4, - "cacheRead": 0.28, - "cacheWrite": 0 - } + "cost": { "input": 1.1, "output": 4.4, "cacheRead": 0.28, "cacheWrite": 0 } }, { "id": "o4-mini-deep-research", @@ -603,12 +183,7 @@ "input": ["text", "image"], "contextWindow": 200000, "maxTokens": 100000, - "cost": { - "input": 2, - "output": 8, - "cacheRead": 0.5, - "cacheWrite": 0 - } + "cost": { "input": 2, "output": 8, "cacheRead": 0.5, "cacheWrite": 0 } }, { "id": "gpt-5.5-pro", @@ -617,12 +192,7 @@ "input": ["text", "image"], "contextWindow": 1000000, "maxTokens": 128000, - "cost": { - "input": 30, - "output": 180, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 30, "output": 180, "cacheRead": 0, "cacheWrite": 0 } } ] }, @@ -638,12 +208,7 @@ "contextWindow": 400000, "contextTokens": 272000, "maxTokens": 128000, - "cost": { - "input": 5, - "output": 30, - "cacheRead": 0.5, - "cacheWrite": 0 - } + "cost": { "input": 5, "output": 30, "cacheRead": 0.5, "cacheWrite": 0 } }, { "id": "gpt-5.4", @@ -653,12 +218,7 @@ "contextWindow": 1050000, "contextTokens": 272000, "maxTokens": 128000, - "cost": { - "input": 2.5, - "output": 15, - "cacheRead": 0.25, - "cacheWrite": 0 - } + "cost": { "input": 2.5, "output": 15, "cacheRead": 0.25, "cacheWrite": 0 } }, { "id": "gpt-5.4-pro", @@ -668,12 +228,7 @@ "contextWindow": 1050000, "contextTokens": 272000, "maxTokens": 128000, - "cost": { - "input": 30, - "output": 180, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 30, "output": 180, "cacheRead": 0, "cacheWrite": 0 } }, { "id": "gpt-5.4-mini", @@ -683,12 +238,7 @@ "contextWindow": 400000, "contextTokens": 272000, "maxTokens": 128000, - "cost": { - "input": 0.75, - "output": 4.5, - "cacheRead": 0.075, - "cacheWrite": 0 - } + "cost": { "input": 0.75, "output": 4.5, "cacheRead": 0.075, "cacheWrite": 0 } }, { "id": "gpt-5.5-pro", @@ -698,12 +248,7 @@ "contextWindow": 1000000, "contextTokens": 272000, "maxTokens": 128000, - "cost": { - "input": 30, - "output": 180, - "cacheRead": 0, - "cacheWrite": 0 - } + "cost": { "input": 30, "output": 180, "cacheRead": 0, "cacheWrite": 0 } } ] } diff --git a/extensions/openai/thinking-policy.ts b/extensions/openai/thinking-policy.ts index 1bd8259c99f8..a27606e0905e 100644 --- a/extensions/openai/thinking-policy.ts +++ b/extensions/openai/thinking-policy.ts @@ -15,7 +15,6 @@ const OPENAI_XHIGH_MODEL_IDS = [ "gpt-5.4-pro", "gpt-5.4-mini", "gpt-5.4-nano", - "gpt-5.2", ] as const; const OPENAI_CODEX_XHIGH_MODEL_IDS = ["gpt-5.5", "gpt-5.5-pro", "gpt-5.4", "gpt-5.4-pro"] as const; diff --git a/extensions/xai/openclaw.plugin.json b/extensions/xai/openclaw.plugin.json index 0a5d6bf37a4a..97ad5176798c 100644 --- a/extensions/xai/openclaw.plugin.json +++ b/extensions/xai/openclaw.plugin.json @@ -10,11 +10,6 @@ "providers": { "xai": { "aliases": { - "grok-code-fast-1": "grok-build-0.1", - "grok-code-fast": "grok-build-0.1", - "grok-code-fast-1-0825": "grok-build-0.1", - "grok-4-fast-reasoning": "grok-4-fast", - "grok-4-1-fast-reasoning": "grok-4-1-fast", "grok-4.20-experimental-beta-0304-reasoning": "grok-4.20-beta-latest-reasoning", "grok-4.20-experimental-beta-0304-non-reasoning": "grok-4.20-beta-latest-non-reasoning", "grok-4.20-reasoning": "grok-4.20-beta-latest-reasoning", diff --git a/src/commands/doctor/shared/legacy-config-migrate.test.ts b/src/commands/doctor/shared/legacy-config-migrate.test.ts index 0f6bca4750f7..09cf18812305 100644 --- a/src/commands/doctor/shared/legacy-config-migrate.test.ts +++ b/src/commands/doctor/shared/legacy-config-migrate.test.ts @@ -1142,7 +1142,7 @@ describe("legacy migrate controlUi.allowedOrigins seed (issue #29385)", () => { }); describe("legacy model compat migrate", () => { - it("upgrades retired Claude and Copilot model refs", () => { + it("upgrades retired model refs", () => { const res = migrateLegacyConfigForTest({ agents: { defaults: { @@ -1169,13 +1169,30 @@ describe("legacy model compat migrate", () => { "kilocode/anthropic/claude-sonnet-4", "amazon-bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0", "openai/gpt-5.5", + "openai/gpt-4o", + "openai/gpt-4.1-mini", + "openai/gpt-5.1-codex-mini", + "openai/gpt-5.2-codex", + "openai-codex/gpt-5.2", + "openai-codex/gpt-5.1-codex-mini", + "github-copilot/gpt-4.1", + "github-copilot/gpt-5.2", + "github-copilot/gpt-5.2-codex", + "groq/llama3-70b-8192", + "groq/gemma2-9b-it", + "groq/moonshotai/kimi-k2-instruct-0905", + "xai/grok-code-fast-1", + "xai/grok-4-fast-reasoning", + "openai/gpt-4o-transcribe", + "openai/gpt-4o-mini-tts", ], }, models: { "anthropic/claude-haiku-4-5": { alias: "haiku" }, "anthropic/claude-sonnet-4-6": { alias: "current-sonnet" }, "github-copilot/claude-opus-4.5": { alias: "copilot-opus" }, - "github-copilot/gpt-5-mini": { alias: "mini" }, + "openai/gpt-5.2-pro": { alias: "old-pro" }, + "github-copilot/gpt-5-mini": { alias: "old-mini" }, }, }, }, @@ -1204,7 +1221,7 @@ describe("legacy model compat migrate", () => { expect(res.config?.agents?.defaults?.imageModel).toBe("anthropic/claude-sonnet-4-6"); expect(res.config?.agents?.defaults?.imageGenerationModel).toEqual({ primary: "github-copilot/claude-sonnet-4.6", - fallbacks: ["github-copilot/gpt-5-mini"], + fallbacks: ["github-copilot/gpt-5.4-mini"], }); expect(res.config?.agents?.defaults?.musicGenerationModel).toBe( "vercel-ai-gateway/anthropic/claude-opus-4-6", @@ -1216,7 +1233,7 @@ describe("legacy model compat migrate", () => { fallbacks: [ "anthropic/claude-sonnet-4-6", "github-copilot/claude-sonnet-4.6", - "github-copilot/gpt-5-mini@github:work", + "github-copilot/gpt-5.4-mini@github:work", "venice/claude-opus-4-6", "vercel-ai-gateway/anthropic/claude-opus-4-6", "anthropic/claude-opus-5-0", @@ -1225,13 +1242,30 @@ describe("legacy model compat migrate", () => { "kilocode/anthropic/claude-sonnet-4", "amazon-bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0", "openai/gpt-5.5", + "openai/gpt-5.5", + "openai/gpt-5.4-mini", + "openai/gpt-5.4-mini", + "openai/gpt-5.3-codex", + "openai-codex/gpt-5.5", + "openai-codex/gpt-5.4-mini", + "github-copilot/gpt-5.5", + "github-copilot/gpt-5.5", + "github-copilot/gpt-5.3-codex", + "groq/llama-3.3-70b-versatile", + "groq/llama-3.1-8b-instant", + "groq/openai/gpt-oss-120b", + "xai/grok-build-0.1", + "xai/grok-4.3", + "openai/gpt-4o-transcribe", + "openai/gpt-4o-mini-tts", ], }); expect(res.config?.agents?.defaults?.workspace).toBe("/tmp/claude-3-sonnet"); expect(res.config?.agents?.defaults?.models).toEqual({ "anthropic/claude-sonnet-4-6": { alias: "current-sonnet" }, "github-copilot/claude-opus-4.7": { alias: "copilot-opus" }, - "github-copilot/gpt-5-mini": { alias: "mini" }, + "openai/gpt-5.5-pro": { alias: "old-pro" }, + "github-copilot/gpt-5.4-mini": { alias: "old-mini" }, }); expect( (res.config?.plugins?.entries?.["lossless-claw"] as { config?: { summaryModel?: string } }) @@ -1252,14 +1286,30 @@ describe("legacy model compat migrate", () => { expectMigrationChangesToIncludeFragments(res.changes, [ 'config.agents.defaults.imageModel from "anthropic/claude-haiku-4-5" to "anthropic/claude-sonnet-4-6"', 'config.agents.defaults.imageGenerationModel.primary from "github-copilot/claude-sonnet-4" to "github-copilot/claude-sonnet-4.6"', - 'config.agents.defaults.imageGenerationModel.fallbacks.0 from "github-copilot/grok-code-fast-1" to "github-copilot/gpt-5-mini"', + 'config.agents.defaults.imageGenerationModel.fallbacks.0 from "github-copilot/grok-code-fast-1" to "github-copilot/gpt-5.4-mini"', 'config.agents.defaults.musicGenerationModel from "vercel-ai-gateway/anthropic/claude-opus-4-5" to "vercel-ai-gateway/anthropic/claude-opus-4-6"', 'config.agents.defaults.pdfModel from "anthropic/claude-3-5-sonnet" to "anthropic/claude-sonnet-4-6"', 'config.agents.defaults.model.primary from "anthropic/claude-opus-4-5@anthropic:work" to "anthropic/claude-opus-4-7@anthropic:work"', - 'config.agents.defaults.model.fallbacks.2 from "github-copilot/grok-code-fast-1@github:work" to "github-copilot/gpt-5-mini@github:work"', + 'config.agents.defaults.model.fallbacks.2 from "github-copilot/grok-code-fast-1@github:work" to "github-copilot/gpt-5.4-mini@github:work"', 'config.agents.defaults.model.fallbacks.3 from "venice/claude-opus-4-5" to "venice/claude-opus-4-6"', 'config.agents.defaults.model.fallbacks.4 from "vercel-ai-gateway/anthropic/claude-opus-4-5" to "vercel-ai-gateway/anthropic/claude-opus-4-6"', + 'config.agents.defaults.model.fallbacks.11 from "openai/gpt-4o" to "openai/gpt-5.5"', + 'config.agents.defaults.model.fallbacks.12 from "openai/gpt-4.1-mini" to "openai/gpt-5.4-mini"', + 'config.agents.defaults.model.fallbacks.13 from "openai/gpt-5.1-codex-mini" to "openai/gpt-5.4-mini"', + 'config.agents.defaults.model.fallbacks.14 from "openai/gpt-5.2-codex" to "openai/gpt-5.3-codex"', + 'config.agents.defaults.model.fallbacks.15 from "openai-codex/gpt-5.2" to "openai-codex/gpt-5.5"', + 'config.agents.defaults.model.fallbacks.16 from "openai-codex/gpt-5.1-codex-mini" to "openai-codex/gpt-5.4-mini"', + 'config.agents.defaults.model.fallbacks.17 from "github-copilot/gpt-4.1" to "github-copilot/gpt-5.5"', + 'config.agents.defaults.model.fallbacks.18 from "github-copilot/gpt-5.2" to "github-copilot/gpt-5.5"', + 'config.agents.defaults.model.fallbacks.19 from "github-copilot/gpt-5.2-codex" to "github-copilot/gpt-5.3-codex"', + 'config.agents.defaults.model.fallbacks.20 from "groq/llama3-70b-8192" to "groq/llama-3.3-70b-versatile"', + 'config.agents.defaults.model.fallbacks.21 from "groq/gemma2-9b-it" to "groq/llama-3.1-8b-instant"', + 'config.agents.defaults.model.fallbacks.22 from "groq/moonshotai/kimi-k2-instruct-0905" to "groq/openai/gpt-oss-120b"', + 'config.agents.defaults.model.fallbacks.23 from "xai/grok-code-fast-1" to "xai/grok-build-0.1"', + 'config.agents.defaults.model.fallbacks.24 from "xai/grok-4-fast-reasoning" to "xai/grok-4.3"', 'config.agents.defaults.models key from "github-copilot/claude-opus-4.5" to "github-copilot/claude-opus-4.7"', + 'config.agents.defaults.models key from "openai/gpt-5.2-pro" to "openai/gpt-5.5-pro"', + 'config.agents.defaults.models key from "github-copilot/gpt-5-mini" to "github-copilot/gpt-5.4-mini"', 'config.plugins.entries.lossless-claw.config.summaryModel from "anthropic/claude-3-5-sonnet" to "anthropic/claude-sonnet-4-6"', 'config.plugins.entries.lossless-claw.subagent.allowedModels.0 from "anthropic/claude-haiku-4-5" to "anthropic/claude-sonnet-4-6"', 'config.channels.modelByChannel.telegram.* from "anthropic/claude-opus-4-5" to "anthropic/claude-opus-4-7"', diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts index e53390fecb57..3ce448e3363a 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts @@ -67,6 +67,94 @@ function shouldUpgradeClaudeProvider(provider: string | undefined): boolean { ); } +function upgradeRetiredGroqModelId(model: string): string | null { + const normalized = normalizeString(model); + switch (normalized) { + case "deepseek-r1-distill-llama-70b": + return "llama-3.3-70b-versatile"; + case "gemma2-9b-it": + case "llama3-8b-8192": + return "llama-3.1-8b-instant"; + case "llama3-70b-8192": + return "llama-3.3-70b-versatile"; + case "meta-llama/llama-4-maverick-17b-128e-instruct": + case "moonshotai/kimi-k2-instruct": + case "moonshotai/kimi-k2-instruct-0905": + return "openai/gpt-oss-120b"; + case "mistral-saba-24b": + case "qwen-qwq-32b": + return "qwen/qwen3-32b"; + default: + return null; + } +} + +function upgradeRetiredXaiModelId(model: string): string | null { + const normalized = normalizeString(model); + switch (normalized) { + case "grok-code-fast": + case "grok-code-fast-1": + case "grok-code-fast-1-0825": + return "grok-build-0.1"; + case "grok-4-fast-reasoning": + case "grok-4-1-fast-reasoning": + return "grok-4.3"; + default: + return null; + } +} + +function upgradeRetiredOpenAiModelId(model: string, provider?: string): string | null { + const normalized = normalizeString(model); + const codexProvider = provider === "openai-codex"; + if (codexProvider && normalized === "gpt-5.2") { + return "gpt-5.5"; + } + if ( + normalized === "gpt-5.2-codex" || + normalized === "gpt-5.1-codex" || + normalized === "gpt-5-codex" + ) { + return codexProvider ? "gpt-5.5" : "gpt-5.3-codex"; + } + if (normalized === "gpt-5-pro" || normalized === "gpt-5.2-pro") { + return "gpt-5.5-pro"; + } + if (normalized === "gpt-4.1-nano" || normalized === "gpt-5-nano") { + if (codexProvider) { + return "gpt-5.4-mini"; + } + return "gpt-5.4-nano"; + } + if ( + normalized === "gpt-4.1-mini" || + normalized === "gpt-4o-mini" || + normalized === "gpt-5.1-codex-mini" || + normalized === "gpt-5-mini" + ) { + return "gpt-5.4-mini"; + } + if ( + normalized === "gpt-4" || + normalized === "gpt-4-turbo" || + normalized === "gpt-4.1" || + normalized === "gpt-4o" || + normalized === "gpt-4o-2024-05-13" || + normalized === "gpt-4o-2024-08-06" || + normalized === "gpt-4o-2024-11-20" || + normalized === "gpt-5" || + normalized === "gpt-5-chat-latest" || + normalized === "gpt-5.1" || + normalized === "gpt-5.1-chat-latest" || + normalized === "gpt-5.1-codex-max" || + normalized === "gpt-5.2" || + normalized === "gpt-5.2-chat-latest" + ) { + return "gpt-5.5"; + } + return null; +} + function hasRetiredVersionPrefix(normalized: string, prefix: string): boolean { if (normalized === prefix) { return true; @@ -217,11 +305,25 @@ function upgradeRetiredModelRef(value: string): string | null { const normalizedProvider = normalizeString(provider); const normalizedModel = normalizeString(model); + const retiredOwnerModel = + normalizedProvider === "groq" + ? upgradeRetiredGroqModelId(model) + : normalizedProvider === "xai" + ? upgradeRetiredXaiModelId(model) + : normalizedProvider === "openai" || + normalizedProvider === "openai-codex" || + normalizedProvider === "github-copilot" + ? upgradeRetiredOpenAiModelId(model, normalizedProvider) + : undefined; + if (retiredOwnerModel) { + return `${provider}/${retiredOwnerModel}${split.profile ? `@${split.profile}` : ""}`; + } + if ( (normalizedProvider === "github-copilot" || normalizedProvider === "copilot-proxy") && normalizedModel === "grok-code-fast-1" ) { - return `${provider}/gpt-5-mini${split.profile ? `@${split.profile}` : ""}`; + return `${provider}/gpt-5.4-mini${split.profile ? `@${split.profile}` : ""}`; } if (!shouldUpgradeClaudeProvider(normalizedProvider || undefined)) { return null; @@ -372,7 +474,7 @@ function rewriteKnownModelRefs( } const RETIRED_MODEL_REF_MESSAGE = - 'Configured Claude models older than 4.6 or retired Copilot model refs are no longer in the bundled catalogs; run "openclaw doctor --fix" to upgrade them.'; + 'Configured retired model refs are no longer in the bundled catalogs; run "openclaw doctor --fix" to upgrade them.'; const RETIRED_MODEL_REF_RULES: LegacyConfigRule[] = [ "agents", "plugins", @@ -389,8 +491,8 @@ const RETIRED_MODEL_REF_RULES: LegacyConfigRule[] = [ export const LEGACY_CONFIG_MIGRATIONS_RUNTIME_MODELS: LegacyConfigMigrationSpec[] = [ defineLegacyConfigMigration({ - id: "models.retired-claude-and-copilot-refs", - describe: "Upgrade retired Claude/Copilot model refs to current catalog entries", + id: "models.retired-model-refs", + describe: "Upgrade retired model refs to current catalog entries", legacyRules: RETIRED_MODEL_REF_RULES, apply: (raw, changes) => { const rewritten = rewriteKnownModelRefs(raw, "config", changes);