From fc5a4defaf627fe058295754c0e871ccff85fdd9 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 9 Jul 2026 11:07:50 +0100 Subject: [PATCH] feat(cohere): add current Command models (#102563) * feat(cohere): add current Command models * docs: keep release notes out of PR --- docs/concepts/model-providers.md | 4 +- docs/help/testing-live.md | 11 ++- docs/providers/cohere.md | 19 +++-- extensions/cohere/README.md | 5 +- extensions/cohere/index.test.ts | 71 +++++++++++++++- extensions/cohere/index.ts | 2 + extensions/cohere/models.ts | 14 ++++ extensions/cohere/onboard.test.ts | 7 +- extensions/cohere/onboard.ts | 11 ++- extensions/cohere/openclaw.plugin.json | 84 +++++++++++++++++++ src/agents/live-model-filter.ts | 6 +- src/agents/model-compat.test.ts | 15 +++- .../gateway-models.profiles.live.test.ts | 2 +- 13 files changed, 223 insertions(+), 28 deletions(-) diff --git a/docs/concepts/model-providers.md b/docs/concepts/model-providers.md index 15d9275aef5..3ace9e037a5 100644 --- a/docs/concepts/model-providers.md +++ b/docs/concepts/model-providers.md @@ -205,7 +205,7 @@ Claude CLI reuse (`claude -p`) is a sanctioned OpenClaw integration path. Anthro - Provider: `google` - Auth: `GEMINI_API_KEY` - Optional rotation: `GEMINI_API_KEYS`, `GEMINI_API_KEY_1`, `GEMINI_API_KEY_2`, `GOOGLE_API_KEY` fallback, and `OPENCLAW_LIVE_GEMINI_KEY` (single override) -- Example models: `google/gemini-3.1-pro-preview`, `google/gemini-3-flash-preview` +- Example models: `google/gemini-3.1-pro-preview`, `google/gemini-3.5-flash` - Compatibility: legacy OpenClaw config using `google/gemini-3.1-flash-preview` is normalized to `google/gemini-3-flash-preview` - Alias: `google/gemini-3.1-pro` is accepted and normalized to Google's live Gemini API id, `google/gemini-3.1-pro-preview` - CLI: `openclaw onboard --auth-choice gemini-api-key` @@ -285,7 +285,7 @@ messages and normalizes `stats.cached` into `cacheRead`; legacy | Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` | | Chutes | `chutes` | `CHUTES_API_KEY` or `CHUTES_OAUTH_TOKEN` | `chutes/zai-org/GLM-4.7-TEE` | | ClawRouter | `clawrouter` | `CLAWROUTER_API_KEY` | `clawrouter/anthropic/claude-sonnet-4-6` | -| Cohere | `cohere` | `COHERE_API_KEY` | `cohere/command-a-03-2025` | +| Cohere | `cohere` | `COHERE_API_KEY` | `cohere/command-a-plus-05-2026` | | DeepInfra | `deepinfra` | `DEEPINFRA_API_KEY` | `deepinfra/deepseek-ai/DeepSeek-V4-Flash` | | DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` | | Featherless AI | `featherless` | `FEATHERLESS_API_KEY` | `featherless/Qwen/Qwen3-32B` | diff --git a/docs/help/testing-live.md b/docs/help/testing-live.md index 5af807521af..36d7a69a35a 100644 --- a/docs/help/testing-live.md +++ b/docs/help/testing-live.md @@ -360,13 +360,13 @@ Narrow, explicit allowlists are fastest and least flaky: - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Tool calling across several providers: - - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` + - `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.5-flash,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Z.AI Coding Plan GLM-5.2 direct smoke: - `ZAI_CODING_LIVE_TEST=1 pnpm test:live src/agents/zai.live.test.ts` - Google focus (Gemini API key + Antigravity): - - Gemini (API key): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` + - Gemini (API key): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3.5-flash" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Antigravity (OAuth): `OPENCLAW_LIVE_GATEWAY_MODELS="google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-pro-high" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts` - Google adaptive thinking smoke (`qa manual` from the private QA CLI - requires `OPENCLAW_ENABLE_PRIVATE_QA_CLI=1` and a source checkout; see [QA overview](/concepts/qa-e2e-automation)): @@ -389,10 +389,12 @@ Live is opt-in, so there is no fixed "CI model list." `OPENCLAW_LIVE_MODELS=mode | Provider/model | Notes | | --------------------------------------------- | ---------- | | `anthropic/claude-opus-4-8` | | +| `anthropic/claude-sonnet-5` | | | `anthropic/claude-sonnet-4-6` | | | `anthropic/claude-opus-4-7` | | | `google/gemini-3.1-pro-preview` | Gemini API | -| `google/gemini-3-flash-preview` | Gemini API | +| `google/gemini-3.5-flash` | Gemini API | +| `cohere/command-a-plus-05-2026` | | | `moonshot/kimi-k2.7-code` | | | `anthropic/claude-opus-4-6` | | | `deepseek/deepseek-v4-flash` | | @@ -404,6 +406,7 @@ Live is opt-in, so there is no fixed "CI model list." `OPENCLAW_LIVE_MODELS=mode | `opencode-go/glm-5` | | | `openrouter/ai21/jamba-large-1.7` | | | `xai/grok-4.5` | | +| `xai/grok-4.20-0309-reasoning` | | | `zai/glm-5.1` | | | `fireworks/accounts/fireworks/models/glm-5p1` | | | `minimax-portal/minimax-m3` | | @@ -430,7 +433,7 @@ Notes on the modern list: Run gateway smoke with tools + image across a hand-picked cross-provider set: ```bash -OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts +OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3.5-flash,google-antigravity/claude-opus-4-6-thinking,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M3" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts ``` Optional additional coverage outside the curated lists (nice to have, pick a "tools"-capable model you have enabled): diff --git a/docs/providers/cohere.md b/docs/providers/cohere.md index b3d78e961be..0d238570471 100644 --- a/docs/providers/cohere.md +++ b/docs/providers/cohere.md @@ -17,17 +17,20 @@ read_when: | Direct CLI flag | `--cohere-api-key ` | | API | OpenAI-compatible (`openai-completions`) | | Base URL | `https://api.cohere.ai/compatibility/v1` | -| Default model | `cohere/command-a-03-2025` | -| Context window | 256,000 tokens | +| Default model | `cohere/command-a-plus-05-2026` | +| Context window | 128,000 tokens | ## Built-in catalog -| Model ref | Input | Context | Max output | Notes | -| ---------------------------- | ----------- | ------- | ---------- | -------------------------------------- | -| `cohere/command-a-03-2025` | text | 256,000 | 8,000 | Default model | -| `cohere/north-mini-code-1-0` | text, image | 256,000 | 64,000 | Agentic coding; reasoning; free limits | +| Model ref | Input | Context | Max output | Notes | +| ------------------------------------ | ----------- | ------- | ---------- | --------------------------------------------- | +| `cohere/command-a-plus-05-2026` | text, image | 128,000 | 64,000 | Default; flagship agentic and reasoning model | +| `cohere/command-a-03-2025` | text | 256,000 | 8,000 | Previous Command A model | +| `cohere/command-a-reasoning-08-2025` | text | 256,000 | 32,000 | Agentic reasoning and tool use | +| `cohere/command-a-vision-07-2025` | text, image | 128,000 | 8,000 | Vision and document analysis; no tool use | +| `cohere/north-mini-code-1-0` | text, image | 256,000 | 64,000 | Agentic coding; reasoning; free limits | -North Mini Code supports Cohere's two Compatibility API reasoning modes. OpenClaw maps **off** to `none` and every enabled thinking level to `high`. +Reasoning-capable Cohere models support two Compatibility API reasoning modes. OpenClaw maps **off** to `none` and every enabled thinking level to `high`. Command A Vision does not support tool use, so OpenClaw keeps agent tools disabled for that model. ## Get started @@ -63,7 +66,7 @@ Make `COHERE_API_KEY` available to the Gateway process, then select the Cohere m { agents: { defaults: { - model: { primary: "cohere/command-a-03-2025" }, + model: { primary: "cohere/command-a-plus-05-2026" }, }, }, } diff --git a/extensions/cohere/README.md b/extensions/cohere/README.md index 951077386b1..19f69153e19 100644 --- a/extensions/cohere/README.md +++ b/extensions/cohere/README.md @@ -10,5 +10,6 @@ openclaw plugins install @openclaw/cohere-provider openclaw gateway restart ``` -Configure a Cohere API key, then select `cohere/command-a-03-2025` or -`cohere/north-mini-code-1-0`. +Configure a Cohere API key, then select `cohere/command-a-plus-05-2026`, +`cohere/command-a-reasoning-08-2025`, `cohere/command-a-vision-07-2025`, +`cohere/command-a-03-2025`, or `cohere/north-mini-code-1-0`. diff --git a/extensions/cohere/index.test.ts b/extensions/cohere/index.test.ts index ca7fab6fc31..04cff6ced64 100644 --- a/extensions/cohere/index.test.ts +++ b/extensions/cohere/index.test.ts @@ -5,7 +5,12 @@ import { registerSingleProviderPlugin } from "openclaw/plugin-sdk/plugin-test-ru import { buildOpenAICompletionsParams } from "openclaw/plugin-sdk/provider-transport-runtime"; import { describe, expect, it } from "vitest"; import plugin from "./index.js"; -import { COHERE_NORTH_MINI_CODE_MODEL_ID } from "./models.js"; +import { + COHERE_COMMAND_A_PLUS_MODEL_ID, + COHERE_COMMAND_A_REASONING_MODEL_ID, + COHERE_COMMAND_A_VISION_MODEL_ID, + COHERE_NORTH_MINI_CODE_MODEL_ID, +} from "./models.js"; import { buildCohereProvider } from "./provider-catalog.js"; import { createCohereCompletionsWrapper } from "./stream.js"; @@ -16,7 +21,7 @@ function readManifest() { }; } -function requireCohereModel(modelId = "command-a-03-2025"): Model<"openai-completions"> { +function requireCohereModel(modelId = COHERE_COMMAND_A_PLUS_MODEL_ID): Model<"openai-completions"> { const provider = buildCohereProvider(); const model = provider.models?.find((candidate) => candidate.id === modelId); if (!model) { @@ -91,6 +96,17 @@ describe("Cohere provider plugin", () => { baseUrl: "https://api.cohere.ai/compatibility/v1", api: "openai-completions", models: [ + expect.objectContaining({ + id: COHERE_COMMAND_A_PLUS_MODEL_ID, + reasoning: true, + input: ["text", "image"], + contextWindow: 128000, + maxTokens: 64000, + compat: expect.objectContaining({ + supportsReasoningEffort: true, + supportedReasoningEfforts: ["none", "high"], + }), + }), expect.objectContaining({ id: "command-a-03-2025", compat: { @@ -99,6 +115,21 @@ describe("Cohere provider plugin", () => { maxTokensField: "max_tokens", }, }), + expect.objectContaining({ + id: COHERE_COMMAND_A_REASONING_MODEL_ID, + reasoning: true, + input: ["text"], + contextWindow: 256000, + maxTokens: 32000, + }), + expect.objectContaining({ + id: COHERE_COMMAND_A_VISION_MODEL_ID, + reasoning: false, + input: ["text", "image"], + contextWindow: 128000, + maxTokens: 8000, + compat: expect.objectContaining({ supportsTools: false }), + }), expect.objectContaining({ id: "north-mini-code-1-0", reasoning: true, @@ -171,4 +202,40 @@ describe("Cohere provider plugin", () => { }).reasoning_effort, ).toBe("high"); }); + + it("maps Command A+ and Command A Reasoning to Cohere's supported reasoning efforts", () => { + const context = { messages: [] } as Context; + + for (const modelId of [COHERE_COMMAND_A_PLUS_MODEL_ID, COHERE_COMMAND_A_REASONING_MODEL_ID]) { + expect(captureCoherePayload(context, { modelId, reasoning: "off" }).reasoning_effort).toBe( + "none", + ); + expect(captureCoherePayload(context, { modelId, reasoning: "medium" }).reasoning_effort).toBe( + "high", + ); + } + }); + + it("advertises only tool-capable current Cohere models to modern live sweeps", async () => { + const provider = await registerSingleProviderPlugin(plugin); + + expect( + provider.isModernModelRef?.({ provider: "cohere", modelId: COHERE_COMMAND_A_PLUS_MODEL_ID }), + ).toBe(true); + expect( + provider.isModernModelRef?.({ + provider: "cohere", + modelId: COHERE_COMMAND_A_REASONING_MODEL_ID, + }), + ).toBe(true); + expect(provider.isModernModelRef?.({ provider: "cohere", modelId: "command-a-03-2025" })).toBe( + false, + ); + expect( + provider.isModernModelRef?.({ + provider: "cohere", + modelId: COHERE_COMMAND_A_VISION_MODEL_ID, + }), + ).toBe(false); + }); }); diff --git a/extensions/cohere/index.ts b/extensions/cohere/index.ts index ce853e7d29d..0e693027469 100644 --- a/extensions/cohere/index.ts +++ b/extensions/cohere/index.ts @@ -1,4 +1,5 @@ import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry"; +import { isModernCohereModelId } from "./models.js"; import { applyCohereConfig, COHERE_DEFAULT_MODEL_REF } from "./onboard.js"; import { buildCohereProvider } from "./provider-catalog.js"; import { createCohereCompletionsWrapper } from "./stream.js"; @@ -33,5 +34,6 @@ export default defineSingleProviderPluginEntry({ }, wrapStreamFn: (ctx) => createCohereCompletionsWrapper(ctx.streamFn), wrapSimpleCompletionStreamFn: (ctx) => createCohereCompletionsWrapper(ctx.streamFn), + isModernModelRef: ({ modelId }) => isModernCohereModelId(modelId), }, }); diff --git a/extensions/cohere/models.ts b/extensions/cohere/models.ts index 01cc197138c..ef7efe84719 100644 --- a/extensions/cohere/models.ts +++ b/extensions/cohere/models.ts @@ -9,8 +9,22 @@ const COHERE_MANIFEST_CATALOG = manifest.modelCatalog.providers.cohere; export const COHERE_BASE_URL = COHERE_MANIFEST_CATALOG.baseUrl; export const COHERE_MODEL_CATALOG = COHERE_MANIFEST_CATALOG.models; +export const COHERE_COMMAND_A_PLUS_MODEL_ID = "command-a-plus-05-2026"; +export const COHERE_COMMAND_A_REASONING_MODEL_ID = "command-a-reasoning-08-2025"; +export const COHERE_COMMAND_A_VISION_MODEL_ID = "command-a-vision-07-2025"; export const COHERE_NORTH_MINI_CODE_MODEL_ID = "north-mini-code-1-0"; +const COHERE_MODERN_MODEL_IDS = new Set([ + COHERE_COMMAND_A_PLUS_MODEL_ID, + COHERE_COMMAND_A_REASONING_MODEL_ID, + // Modern sweeps require agent tool use; Vision explicitly does not support tools. + COHERE_NORTH_MINI_CODE_MODEL_ID, +]); + +export function isModernCohereModelId(modelId: string): boolean { + return COHERE_MODERN_MODEL_IDS.has(modelId.trim().toLowerCase()); +} + export function buildCohereCatalogModels(): ModelDefinitionConfig[] { return buildManifestModelProviderConfig({ providerId: "cohere", diff --git a/extensions/cohere/onboard.test.ts b/extensions/cohere/onboard.test.ts index 2a1084f2808..ea1d5145b57 100644 --- a/extensions/cohere/onboard.test.ts +++ b/extensions/cohere/onboard.test.ts @@ -4,6 +4,8 @@ import { describe, expect, it } from "vitest"; import { buildCohereCatalogModels, COHERE_BASE_URL, + COHERE_COMMAND_A_REASONING_MODEL_ID, + COHERE_COMMAND_A_VISION_MODEL_ID, COHERE_MODEL_CATALOG, COHERE_NORTH_MINI_CODE_MODEL_ID, } from "./models.js"; @@ -20,6 +22,9 @@ describe("Cohere onboarding", () => { }); expect(provider?.models?.map((model) => model.id)).toEqual([ COHERE_DEFAULT_MODEL_ID, + "command-a-03-2025", + COHERE_COMMAND_A_REASONING_MODEL_ID, + COHERE_COMMAND_A_VISION_MODEL_ID, COHERE_NORTH_MINI_CODE_MODEL_ID, ]); expect(buildCohereCatalogModels()).toHaveLength(COHERE_MODEL_CATALOG.length); @@ -38,7 +43,7 @@ describe("Cohere onboarding", () => { expect(resolveAgentModelPrimaryValue(result.agents?.defaults?.model)).toBe("openai/gpt-5.5"); expect(result.agents?.defaults?.models?.[COHERE_DEFAULT_MODEL_REF]).toEqual({ - alias: "Cohere Command A", + alias: "Cohere Command A+", }); }); diff --git a/extensions/cohere/onboard.ts b/extensions/cohere/onboard.ts index 77e48d545f9..521655b79c0 100644 --- a/extensions/cohere/onboard.ts +++ b/extensions/cohere/onboard.ts @@ -2,9 +2,14 @@ import { createModelCatalogPresetAppliers, type OpenClawConfig, } from "openclaw/plugin-sdk/provider-onboard"; -import { buildCohereModelDefinition, COHERE_BASE_URL, COHERE_MODEL_CATALOG } from "./models.js"; +import { + buildCohereModelDefinition, + COHERE_BASE_URL, + COHERE_COMMAND_A_PLUS_MODEL_ID, + COHERE_MODEL_CATALOG, +} from "./models.js"; -export const COHERE_DEFAULT_MODEL_ID = "command-a-03-2025"; +export const COHERE_DEFAULT_MODEL_ID = COHERE_COMMAND_A_PLUS_MODEL_ID; export const COHERE_DEFAULT_MODEL_REF = `cohere/${COHERE_DEFAULT_MODEL_ID}`; const coherePresetAppliers = createModelCatalogPresetAppliers({ @@ -14,7 +19,7 @@ const coherePresetAppliers = createModelCatalogPresetAppliers({ api: "openai-completions", baseUrl: COHERE_BASE_URL, catalogModels: COHERE_MODEL_CATALOG.map(buildCohereModelDefinition), - aliases: [{ modelRef: COHERE_DEFAULT_MODEL_REF, alias: "Cohere Command A" }], + aliases: [{ modelRef: COHERE_DEFAULT_MODEL_REF, alias: "Cohere Command A+" }], }), }); diff --git a/extensions/cohere/openclaw.plugin.json b/extensions/cohere/openclaw.plugin.json index 472bca03021..65ec924aaea 100644 --- a/extensions/cohere/openclaw.plugin.json +++ b/extensions/cohere/openclaw.plugin.json @@ -13,6 +13,38 @@ "baseUrl": "https://api.cohere.ai/compatibility/v1", "api": "openai-completions", "models": [ + { + "id": "command-a-plus-05-2026", + "name": "Command A+", + "reasoning": true, + "input": ["text", "image"], + "contextWindow": 128000, + "maxTokens": 64000, + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "compat": { + "supportsStore": false, + "supportsUsageInStreaming": false, + "supportsReasoningEffort": true, + "supportedReasoningEfforts": ["none", "high"], + "reasoningEffortMap": { + "off": "none", + "none": "none", + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "high", + "adaptive": "high", + "max": "high" + }, + "maxTokensField": "max_tokens" + } + }, { "id": "command-a-03-2025", "name": "Command A", @@ -31,6 +63,58 @@ "maxTokensField": "max_tokens" } }, + { + "id": "command-a-reasoning-08-2025", + "name": "Command A Reasoning", + "reasoning": true, + "input": ["text"], + "contextWindow": 256000, + "maxTokens": 32000, + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "compat": { + "supportsStore": false, + "supportsUsageInStreaming": false, + "supportsReasoningEffort": true, + "supportedReasoningEfforts": ["none", "high"], + "reasoningEffortMap": { + "off": "none", + "none": "none", + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "high", + "adaptive": "high", + "max": "high" + }, + "maxTokensField": "max_tokens" + } + }, + { + "id": "command-a-vision-07-2025", + "name": "Command A Vision", + "reasoning": false, + "input": ["text", "image"], + "contextWindow": 128000, + "maxTokens": 8000, + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "compat": { + "supportsStore": false, + "supportsUsageInStreaming": false, + "supportsTools": false, + "maxTokensField": "max_tokens" + } + }, { "id": "north-mini-code-1-0", "name": "North Mini Code 1.0", diff --git a/src/agents/live-model-filter.ts b/src/agents/live-model-filter.ts index 13b824b3404..5235133af2c 100644 --- a/src/agents/live-model-filter.ts +++ b/src/agents/live-model-filter.ts @@ -21,7 +21,8 @@ const HIGH_SIGNAL_LIVE_MODEL_PRIORITY = [ "anthropic/claude-sonnet-4-6", "anthropic/claude-opus-4-7", "google/gemini-3.1-pro-preview", - "google/gemini-3-flash-preview", + "google/gemini-3.5-flash", + "cohere/command-a-plus-05-2026", "moonshot/kimi-k2.7-code", "anthropic/claude-opus-4-6", "deepseek/deepseek-v4-flash", @@ -33,6 +34,7 @@ const HIGH_SIGNAL_LIVE_MODEL_PRIORITY = [ "opencode-go/glm-5", "openrouter/ai21/jamba-large-1.7", "xai/grok-4.5", + "xai/grok-4.20-0309-reasoning", "zai/glm-5.1", "fireworks/accounts/fireworks/models/glm-5p1", "minimax-portal/minimax-m3", @@ -128,7 +130,7 @@ function isPreGemini3ModelId(id: string): boolean { function isMutableLatestAliasLiveModelRef(id: string): boolean { const modelName = normalizeLowercaseStringOrEmpty(id).split("/").pop() ?? ""; - return modelName.endsWith("-latest"); + return /(?:^|-)latest(?:-|$)/.test(modelName); } function isOpenAiFamilyLiveModel(provider: string, id: string): boolean { diff --git a/src/agents/model-compat.test.ts b/src/agents/model-compat.test.ts index feecdd8abad..ac8ccdb343e 100644 --- a/src/agents/model-compat.test.ts +++ b/src/agents/model-compat.test.ts @@ -478,8 +478,9 @@ describe("isHighSignalLiveModelRef", () => { expect(isHighSignalLiveModelRef({ provider: "openrouter", id: "google/gemini-2.5-pro" })).toBe( false, ); + expect(isHighSignalLiveModelRef({ provider: "google", id: "gemini-3.5-flash" })).toBe(true); expect(isHighSignalLiveModelRef({ provider: "google", id: "gemini-3-flash-preview" })).toBe( - true, + false, ); expect(isHighSignalLiveModelRef({ provider: "google", id: "gemini-3-pro-preview" })).toBe( false, @@ -619,6 +620,12 @@ describe("isHighSignalLiveModelRef", () => { it("keeps only curated xAI routes in the default live matrix", () => { providerRuntimeMocks.resolveProviderModernModelRef.mockReturnValue(true); + expect( + isHighSignalLiveModelRef({ provider: "xai", id: "grok-4.20-beta-latest-reasoning" }), + ).toBe(false); + expect(isHighSignalLiveModelRef({ provider: "xai", id: "grok-4.20-0309-reasoning" })).toBe( + true, + ); expect(isHighSignalLiveModelRef({ provider: "xai", id: "grok-4.5" })).toBe(true); expect(isHighSignalLiveModelRef({ provider: "xai", id: "grok-4.3" })).toBe(false); expect(isHighSignalLiveModelRef({ provider: "xai", id: "grok-3" })).toBe(false); @@ -666,7 +673,8 @@ describe("isPrioritizedHighSignalLiveModelRef", () => { { provider: "anthropic", id: "claude-sonnet-4-6" }, { provider: "anthropic", id: "claude-opus-4-7" }, { provider: "google", id: "gemini-3.1-pro-preview" }, - { provider: "google", id: "gemini-3-flash-preview" }, + { provider: "google", id: "gemini-3.5-flash" }, + { provider: "cohere", id: "command-a-plus-05-2026" }, { provider: "moonshot", id: "kimi-k2.7-code" }, { provider: "anthropic", id: "claude-opus-4-6" }, { provider: "deepseek", id: "deepseek-v4-flash" }, @@ -678,6 +686,7 @@ describe("isPrioritizedHighSignalLiveModelRef", () => { { provider: "opencode-go", id: "glm-5" }, { provider: "openrouter", id: "ai21/jamba-large-1.7" }, { provider: "xai", id: "grok-4.5" }, + { provider: "xai", id: "grok-4.20-0309-reasoning" }, { provider: "zai", id: "glm-5.1" }, { provider: "fireworks", id: "accounts/fireworks/models/glm-5p1" }, { provider: "minimax-portal", id: "minimax-m3" }, @@ -719,7 +728,7 @@ describe("selectHighSignalLiveItems", () => { { provider: "anthropic", id: "claude-opus-4-7" }, { provider: "anthropic", id: "claude-opus-4-6" }, { provider: "google", id: "gemini-3.1-pro-preview" }, - { provider: "google", id: "gemini-3-flash-preview" }, + { provider: "google", id: "gemini-3.5-flash" }, { provider: "deepseek", id: "deepseek-v4-flash" }, { provider: "openai", id: "gpt-5.5" }, { provider: "opencode", id: "big-pickle" }, diff --git a/src/gateway/gateway-models.profiles.live.test.ts b/src/gateway/gateway-models.profiles.live.test.ts index 0df1c8c3d30..0626011349e 100644 --- a/src/gateway/gateway-models.profiles.live.test.ts +++ b/src/gateway/gateway-models.profiles.live.test.ts @@ -2322,7 +2322,7 @@ describe("getHighSignalLiveModelPriorityIndex", () => { getHighSignalLiveModelPriorityIndex({ provider: "google", id: "gemini-3.1-pro-preview" }), ).toBe(4); expect( - getHighSignalLiveModelPriorityIndex({ provider: "google", id: "gemini-3-flash-preview" }), + getHighSignalLiveModelPriorityIndex({ provider: "google", id: "gemini-3.5-flash" }), ).toBe(5); expect(getHighSignalLiveModelPriorityIndex({ provider: "opencode", id: "big-pickle" })).toBe( null,