diff --git a/lib/api/__tests__/chat-stream-helpers-fallback.test.ts b/lib/api/__tests__/chat-stream-helpers-fallback.test.ts index 6cb507a45..e4ab62e81 100644 --- a/lib/api/__tests__/chat-stream-helpers-fallback.test.ts +++ b/lib/api/__tests__/chat-stream-helpers-fallback.test.ts @@ -41,7 +41,6 @@ const DEEPSEEK_V4_PRO_0813_SLUG = "deepseek/deepseek-v4-pro-0813"; const HIGH_REASONING_ROUTES = [ "ask-model", "agent-model", - "agent-model-free", "model-grok-4.5-pro", "model-grok-4.6", "model-grok-4.6-pro", @@ -51,7 +50,6 @@ const HIGH_REASONING_ROUTES = [ "model-opus-4.6", "model-glm-5.2", "model-glm-5.3", - "model-glm-5.3-flash-agent", "model-kimi-k3", "fallback-agent-model", "fallback-ask-model", @@ -175,12 +173,12 @@ describe("buildProviderOptions fallback chain", () => { }); it.each([ - ["model-glm-5.3-flash", "low"], + ["model-glm-5.3-flash", "high"], ["model-glm-5.3-flash-pro", "high"], ] as const)( - "routes %s directly with %s reasoning and DeepSeek Vision fallback", + "routes Ask %s directly with %s reasoning and DeepSeek Vision fallback", (modelName, effort) => { - const opts = buildProviderOptions(true, "user-1", modelName, "agent"); + const opts = buildProviderOptions(false, "user-1", modelName, "ask"); expect(opts.openrouter).toMatchObject({ reasoning: { enabled: true, effort }, models: [DEEPSEEK_VISION_SLUG], @@ -281,7 +279,7 @@ describe("buildProviderOptions fallback chain", () => { expect(opts.openrouter.models).toHaveLength(3); }); - it("runs free Agent on GLM Flash high and falls back through DeepSeek Flash, Pro 0813, and GLM 5.3", () => { + it("runs free Agent on the GLM Flash default and falls back through DeepSeek Flash, Pro 0813, and GLM 5.3", () => { const opts = buildProviderOptions( true, "user-1", @@ -289,14 +287,14 @@ describe("buildProviderOptions fallback chain", () => { "agent", ); expect(opts.openrouter).toMatchObject({ - reasoning: { enabled: true, effort: "high" }, provider: { sort: "latency", data_collection: "deny" }, models: [DEEPSEEK_FLASH_SLUG, DEEPSEEK_V4_PRO_0813_SLUG, GLM_SLUG], user: "user-1", }); + expect(opts.openrouter).not.toHaveProperty("reasoning"); }); - it("uses the same high-reasoning fallback route for the paid GLM Agent treatment", () => { + it("uses provider-default reasoning for the paid GLM Agent route", () => { const opts = buildProviderOptions( true, "user-1", @@ -304,13 +302,29 @@ describe("buildProviderOptions fallback chain", () => { "agent", ); expect(opts.openrouter).toMatchObject({ - reasoning: { enabled: true, effort: "high" }, provider: { sort: "latency", data_collection: "deny" }, models: [DEEPSEEK_FLASH_SLUG, DEEPSEEK_V4_PRO_0813_SLUG, GLM_SLUG], user: "user-1", }); + expect(opts.openrouter).not.toHaveProperty("reasoning"); }); + it.each([ + "agent-model-free", + "model-glm-5.3-flash-agent", + "model-glm-5.3-flash", + "model-glm-5.3-flash-pro", + ] as const)( + "keeps Agent %s on provider-default reasoning even when an override is supplied", + (modelName) => { + const opts = buildProviderOptions(true, "user-1", modelName, "agent", { + reasoningOverride: { enabled: true, effort: "high" }, + }); + + expect(opts.openrouter).not.toHaveProperty("reasoning"); + }, + ); + it("falls back from explicit DeepSeek Pro ask model through GLM 5.3 then Kimi K3", () => { const opts = buildProviderOptions( false, diff --git a/lib/api/chat-stream-helpers.ts b/lib/api/chat-stream-helpers.ts index 4da378cff..b8ff66fa0 100644 --- a/lib/api/chat-stream-helpers.ts +++ b/lib/api/chat-stream-helpers.ts @@ -685,7 +685,6 @@ export function isExplicitDeepSeekProSelectionForRetry({ } const HIGH_REASONING_MODELS = [ - "agent-model-free", "model-grok-4.5-pro", "model-grok-4.6", "model-grok-4.6-pro", @@ -694,7 +693,6 @@ const HIGH_REASONING_MODELS = [ "model-glm-5.2", "model-glm-5.3", "model-glm-5.3-flash-pro", - "model-glm-5.3-flash-agent", "model-opus-4.6", ] as const satisfies readonly ModelName[]; @@ -971,10 +969,13 @@ export function buildProviderOptions( }) : fallbackSlugs; // OpenRouter applies one reasoning configuration to both the primary model - // and every provider fallback. Standard GLM vision uses low, legacy Standard - // Grok vision uses medium, and Pro/full reasoning routes remain high. + // and every provider fallback. Ask GLM vision uses high, legacy Standard Grok + // vision uses medium, and Pro/full reasoning routes remain high. Agent GLM + // Flash routes omit this option so each provider model uses its default. const isMediumGrok45Vision = modelName === "model-grok-4.5" && isGrok45; const isStandardGlmFlashVision = modelName === "model-glm-5.3-flash"; + const usesDefaultGlmFlashAgentReasoning = + mode === "agent" && modelId === GLM_5_3_FLASH_SLUG; const routesThroughHighReasoningModel = isGrok45 || isGrok46 || @@ -987,7 +988,7 @@ export function buildProviderOptions( const reasoning = isStandardGlmFlashVision ? { enabled: true, - effort: "low", + effort: "high", } : isMediumGrok45Vision ? { @@ -1016,7 +1017,7 @@ export function buildProviderOptions( return { openrouter: { - reasoning, + ...(!usesDefaultGlmFlashAgentReasoning && { reasoning }), ...(options.hasPdfAttachments && isDeepSeekV4 ? { plugins: [