From fca80d2ee23d59d10d02a77deeca4fa205366d57 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 4 Apr 2026 07:00:16 +0100 Subject: [PATCH] refactor(thinking): move provider thinking fallback out of core --- src/auto-reply/thinking.shared.ts | 62 +++---------------------------- src/auto-reply/thinking.test.ts | 11 +++--- src/auto-reply/thinking.ts | 16 ++------ 3 files changed, 16 insertions(+), 73 deletions(-) diff --git a/src/auto-reply/thinking.shared.ts b/src/auto-reply/thinking.shared.ts index c788334064d..4013ddf8e55 100644 --- a/src/auto-reply/thinking.shared.ts +++ b/src/auto-reply/thinking.shared.ts @@ -1,5 +1,3 @@ -import { matchesExactOrPrefix } from "../plugins/provider-model-helpers.js"; - export type ThinkLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "adaptive"; export type VerboseLevel = "off" | "on" | "full"; export type NoticeLevel = "off" | "on" | "full"; @@ -14,59 +12,19 @@ export type ThinkingCatalogEntry = { }; const BASE_THINKING_LEVELS: ThinkLevel[] = ["off", "minimal", "low", "medium", "high", "adaptive"]; -const ANTHROPIC_CLAUDE_46_MODEL_RE = /^claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i; -const AMAZON_BEDROCK_CLAUDE_46_MODEL_RE = /claude-(?:opus|sonnet)-4(?:\.|-)6(?:$|[-.])/i; -const OPENAI_XHIGH_MODEL_IDS = [ - "gpt-5.4", - "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.4", - "gpt-5.3-codex-spark", - "gpt-5.2-codex", - "gpt-5.1-codex", -] as const; -const GITHUB_COPILOT_XHIGH_MODEL_IDS = ["gpt-5.2", "gpt-5.2-codex"] as const; - -export function normalizeProviderId(provider?: string | null): string { - if (!provider) { - return ""; - } - const normalized = provider.trim().toLowerCase(); - if (normalized === "z.ai" || normalized === "z-ai") { - return "zai"; - } - if (normalized === "bedrock" || normalized === "aws-bedrock") { - return "amazon-bedrock"; - } - return normalized; -} +const NO_THINKING_LEVELS: ThinkLevel[] = [...BASE_THINKING_LEVELS]; export function isBinaryThinkingProvider(provider?: string | null): boolean { - return normalizeProviderId(provider) === "zai"; + void provider; + return false; } export function supportsBuiltInXHighThinking( provider?: string | null, model?: string | null, ): boolean { - const providerId = normalizeProviderId(provider); - const modelId = model?.trim().toLowerCase(); - if (!providerId || !modelId) { - return false; - } - if (providerId === "openai") { - return matchesExactOrPrefix(modelId, OPENAI_XHIGH_MODEL_IDS); - } - if (providerId === "openai-codex") { - return matchesExactOrPrefix(modelId, OPENAI_CODEX_XHIGH_MODEL_IDS); - } - if (providerId === "github-copilot") { - return GITHUB_COPILOT_XHIGH_MODEL_IDS.includes(modelId as never); - } + void provider; + void model; return false; } @@ -113,7 +71,7 @@ export function listThinkingLevels( _provider?: string | null, _model?: string | null, ): ThinkLevel[] { - return [...BASE_THINKING_LEVELS]; + return [...NO_THINKING_LEVELS]; } export function listThinkingLevelLabels(provider?: string | null, model?: string | null): string[] { @@ -140,14 +98,6 @@ export function resolveThinkingDefaultForModel(params: { model: string; catalog?: ThinkingCatalogEntry[]; }): ThinkLevel { - const normalizedProvider = normalizeProviderId(params.provider); - const modelId = params.model.trim(); - if (normalizedProvider === "anthropic" && ANTHROPIC_CLAUDE_46_MODEL_RE.test(modelId)) { - return "adaptive"; - } - if (normalizedProvider === "amazon-bedrock" && AMAZON_BEDROCK_CLAUDE_46_MODEL_RE.test(modelId)) { - return "adaptive"; - } const candidate = params.catalog?.find( (entry) => entry.provider === params.provider && entry.id === params.model, ); diff --git a/src/auto-reply/thinking.test.ts b/src/auto-reply/thinking.test.ts index 3f642a79f9f..7edbdbb9066 100644 --- a/src/auto-reply/thinking.test.ts +++ b/src/auto-reply/thinking.test.ts @@ -127,8 +127,9 @@ describe("listThinkingLevelLabels", () => { expect(listThinkingLevelLabels("zai", "glm-4.7")).toEqual(["off", "on"]); }); - it("keeps built-in binary thinking fallback without provider runtime", () => { - expect(listThinkingLevelLabels("zai", "glm-4.7")).toEqual(["off", "on"]); + it("does not assume binary thinking without provider runtime", () => { + expect(listThinkingLevelLabels("zai", "glm-4.7")).toContain("low"); + expect(listThinkingLevelLabels("zai", "glm-4.7")).not.toContain("on"); }); it("returns full levels for non-ZAI", () => { @@ -170,13 +171,13 @@ describe("resolveThinkingDefaultForModel", () => { ).toBe("adaptive"); }); - it("keeps built-in adaptive defaults without provider runtime", () => { + it("does not assume adaptive defaults without provider runtime", () => { expect( resolveThinkingDefaultForModel({ provider: "anthropic", model: "claude-opus-4-6" }), - ).toBe("adaptive"); + ).toBe("off"); expect( resolveThinkingDefaultForModel({ provider: "aws-bedrock", model: "claude-sonnet-4-6" }), - ).toBe("adaptive"); + ).toBe("off"); }); it("defaults reasoning-capable catalog models to low", () => { diff --git a/src/auto-reply/thinking.ts b/src/auto-reply/thinking.ts index be4293742d1..a254804f2e4 100644 --- a/src/auto-reply/thinking.ts +++ b/src/auto-reply/thinking.ts @@ -1,11 +1,9 @@ +import { normalizeProviderId } from "../agents/provider-id.js"; import { formatThinkingLevels as formatThinkingLevelsFallback, - isBinaryThinkingProvider as isBinaryThinkingProviderFallback, listThinkingLevelLabels as listThinkingLevelLabelsFallback, listThinkingLevels as listThinkingLevelsFallback, - normalizeProviderId, resolveThinkingDefaultForModel as resolveThinkingDefaultForModelFallback, - supportsBuiltInXHighThinking, } from "./thinking.shared.js"; import type { ThinkLevel, ThinkingCatalogEntry } from "./thinking.shared.js"; export { @@ -37,10 +35,7 @@ import { } from "../plugins/provider-thinking.js"; export function isBinaryThinkingProvider(provider?: string | null, model?: string | null): boolean { - if (isBinaryThinkingProviderFallback(provider)) { - return true; - } - const normalizedProvider = normalizeProviderId(provider); + const normalizedProvider = provider?.trim() ? normalizeProviderId(provider) : ""; if (!normalizedProvider) { return false; } @@ -55,7 +50,7 @@ export function isBinaryThinkingProvider(provider?: string | null, model?: strin if (typeof pluginDecision === "boolean") { return pluginDecision; } - return isBinaryThinkingProviderFallback(provider); + return false; } export function supportsXHighThinking(provider?: string | null, model?: string | null): boolean { @@ -63,10 +58,7 @@ export function supportsXHighThinking(provider?: string | null, model?: string | if (!modelKey) { return false; } - if (supportsBuiltInXHighThinking(provider, modelKey)) { - return true; - } - const providerKey = normalizeProviderId(provider); + const providerKey = provider?.trim() ? normalizeProviderId(provider) : ""; if (providerKey) { const pluginDecision = resolveProviderXHighThinking({ provider: providerKey,