From 74193ff754fc86ec76d5bad49ec5ff172dfc3a25 Mon Sep 17 00:00:00 2001 From: Glucksberg Date: Sat, 14 Feb 2026 12:49:01 +0000 Subject: [PATCH] fix(ollama): remove Ollama from isReasoningTagProvider (#2279) Ollama's OpenAI-compatible endpoint handles reasoning natively via the `reasoning` field in streaming chunks. Treating Ollama as a reasoning-tag provider incorrectly forces / tag enforcement, which causes stripBlockTags() to discard all output (since Ollama models don't emit tags), resulting in '(no output)' for every Ollama model. This fix removes 'ollama' from the isReasoningTagProvider() check, allowing Ollama models to work correctly through the standard content/reasoning field separation. --- src/utils/provider-utils.test.ts | 39 ++++++++++++++++++++++++++++++++ src/utils/provider-utils.ts | 12 +++++----- 2 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 src/utils/provider-utils.test.ts 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; }