diff --git a/src/utils/provider-utils.test.ts b/src/utils/provider-utils.test.ts new file mode 100644 index 0000000000..9514897f26 --- /dev/null +++ b/src/utils/provider-utils.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from "vitest"; +import { isReasoningTagProvider } from "./provider-utils.js"; + +describe("isReasoningTagProvider", () => { + it("returns false for ollama — native reasoning field, no tags needed (#2279)", () => { + expect(isReasoningTagProvider("ollama")).toBe(false); + expect(isReasoningTagProvider("Ollama")).toBe(false); + }); + + it("returns true for google-gemini-cli", () => { + expect(isReasoningTagProvider("google-gemini-cli")).toBe(true); + }); + + it("returns true for google-generative-ai", () => { + expect(isReasoningTagProvider("google-generative-ai")).toBe(true); + }); + + it("returns true for google-antigravity", () => { + expect(isReasoningTagProvider("google-antigravity")).toBe(true); + expect(isReasoningTagProvider("google-antigravity/gemini-3")).toBe(true); + }); + + it("returns true for minimax", () => { + expect(isReasoningTagProvider("minimax")).toBe(true); + expect(isReasoningTagProvider("minimax-cn")).toBe(true); + }); + + it("returns false for null/undefined/empty", () => { + expect(isReasoningTagProvider(null)).toBe(false); + expect(isReasoningTagProvider(undefined)).toBe(false); + expect(isReasoningTagProvider("")).toBe(false); + }); + + it("returns false for standard providers", () => { + expect(isReasoningTagProvider("anthropic")).toBe(false); + expect(isReasoningTagProvider("openai")).toBe(false); + expect(isReasoningTagProvider("openrouter")).toBe(false); + }); +}); diff --git a/src/utils/provider-utils.ts b/src/utils/provider-utils.ts index 046a23c78a..7bd3ba49e6 100644 --- a/src/utils/provider-utils.ts +++ b/src/utils/provider-utils.ts @@ -13,12 +13,12 @@ export function isReasoningTagProvider(provider: string | undefined | null): boo } const normalized = provider.trim().toLowerCase(); - // Check for exact matches or known prefixes/substrings for reasoning providers - if ( - normalized === "ollama" || - normalized === "google-gemini-cli" || - normalized === "google-generative-ai" - ) { + // Check for exact matches or known prefixes/substrings for reasoning providers. + // Note: Ollama is intentionally excluded — its OpenAI-compatible endpoint + // handles reasoning natively via the `reasoning` field in streaming chunks, + // so tag-based enforcement is unnecessary and causes all output to be + // discarded as "(no output)" (#2279). + if (normalized === "google-gemini-cli" || normalized === "google-generative-ai") { return true; }