From 9f52e48e8fe26c1fa3c60bb6427fda328172ab6a Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 14 Feb 2026 14:03:32 +0900 Subject: [PATCH] fix(think-mode): disable thinking parameter for Z.ai GLM models Z.ai GLM models don't support thinking/reasoning parameters. Ensure these are omitted entirely to prevent empty responses. Fixes #980 Community-reported-by: @iserifith --- src/hooks/think-mode/hook.ts | 48 ++++++++++++++++++++++++++- src/hooks/think-mode/index.test.ts | 19 +++++++++++ src/hooks/think-mode/switcher.test.ts | 11 +++--- src/hooks/think-mode/switcher.ts | 3 +- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/src/hooks/think-mode/hook.ts b/src/hooks/think-mode/hook.ts index 83a55d3fd..17cd17f79 100644 --- a/src/hooks/think-mode/hook.ts +++ b/src/hooks/think-mode/hook.ts @@ -10,6 +10,45 @@ export function clearThinkModeState(sessionID: string): void { } export function createThinkModeHook() { + function isDisabledThinkingConfig(config: Record): boolean { + const thinkingConfig = config.thinking + if ( + typeof thinkingConfig === "object" && + thinkingConfig !== null && + "type" in thinkingConfig && + (thinkingConfig as { type?: string }).type === "disabled" + ) { + return true + } + + const providerOptions = config.providerOptions + if (typeof providerOptions !== "object" || providerOptions === null) { + return false + } + + return Object.values(providerOptions as Record).some( + (providerConfig) => { + if (typeof providerConfig !== "object" || providerConfig === null) { + return false + } + + const providerConfigMap = providerConfig as Record + const extraBody = providerConfigMap.extra_body + if (typeof extraBody !== "object" || extraBody === null) { + return false + } + + const extraBodyMap = extraBody as Record + const extraThinking = extraBodyMap.thinking + return ( + typeof extraThinking === "object" && + extraThinking !== null && + (extraThinking as { type?: string }).type === "disabled" + ) + } + ) + } + return { "chat.params": async (output: ThinkModeInput, sessionID: string): Promise => { const promptText = extractPromptText(output.parts) @@ -75,7 +114,9 @@ export function createThinkModeHook() { sessionID, provider: currentModel.providerID, }) - } else { + } else if ( + !isDisabledThinkingConfig(thinkingConfig as Record) + ) { Object.assign(output.message, thinkingConfig) state.thinkingConfigInjected = true log("Think mode: thinking config injected", { @@ -83,6 +124,11 @@ export function createThinkModeHook() { provider: currentModel.providerID, config: thinkingConfig, }) + } else { + log("Think mode: skipping disabled thinking config", { + sessionID, + provider: currentModel.providerID, + }) } } diff --git a/src/hooks/think-mode/index.test.ts b/src/hooks/think-mode/index.test.ts index 29e9a36a9..5641eb40e 100644 --- a/src/hooks/think-mode/index.test.ts +++ b/src/hooks/think-mode/index.test.ts @@ -352,6 +352,25 @@ describe("createThinkModeHook integration", () => { }) describe("Agent-level thinking configuration respect", () => { + it("should omit Z.ai GLM disabled thinking config", async () => { + //#given a Z.ai GLM model with think prompt + const hook = createThinkModeHook() + const input = createMockInput( + "zai-coding-plan", + "glm-4.7", + "ultrathink mode" + ) + + //#when think mode resolves Z.ai thinking configuration + await hook["chat.params"](input, sessionID) + + //#then thinking config should be omitted from request + const message = input.message as MessageWithInjectedProps + expect(input.message.model?.modelID).toBe("glm-4.7") + expect(message.thinking).toBeUndefined() + expect(message.providerOptions).toBeUndefined() + }) + it("should NOT inject thinking config when agent has thinking disabled", async () => { // given agent with thinking explicitly disabled const hook = createThinkModeHook() diff --git a/src/hooks/think-mode/switcher.test.ts b/src/hooks/think-mode/switcher.test.ts index 9451fcb13..dc968dbfc 100644 --- a/src/hooks/think-mode/switcher.test.ts +++ b/src/hooks/think-mode/switcher.test.ts @@ -470,10 +470,12 @@ describe("think-mode switcher", () => { describe("Z.AI GLM-4.7 provider support", () => { describe("getThinkingConfig for zai-coding-plan", () => { it("should return thinking config for glm-4.7", () => { - // given zai-coding-plan provider with glm-4.7 model + //#given a Z.ai GLM model const config = getThinkingConfig("zai-coding-plan", "glm-4.7") - // then should return zai-coding-plan thinking config + //#when thinking config is resolved + + //#then thinking type is "disabled" expect(config).not.toBeNull() expect(config?.providerOptions).toBeDefined() const zaiOptions = (config?.providerOptions as Record)?.[ @@ -482,8 +484,7 @@ describe("think-mode switcher", () => { expect(zaiOptions?.extra_body).toBeDefined() const extraBody = zaiOptions?.extra_body as Record expect(extraBody?.thinking).toBeDefined() - expect((extraBody?.thinking as Record)?.type).toBe("enabled") - expect((extraBody?.thinking as Record)?.clear_thinking).toBe(false) + expect((extraBody?.thinking as Record)?.type).toBe("disabled") }) it("should return thinking config for glm-4.6v (multimodal)", () => { @@ -505,7 +506,7 @@ describe("think-mode switcher", () => { }) describe("HIGH_VARIANT_MAP for GLM", () => { - it("should NOT have high variant for glm-4.7 (thinking enabled by default)", () => { + it("should NOT have high variant for glm-4.7", () => { // given glm-4.7 model const variant = getHighVariant("glm-4.7") diff --git a/src/hooks/think-mode/switcher.ts b/src/hooks/think-mode/switcher.ts index 677c28b35..b17fddec3 100644 --- a/src/hooks/think-mode/switcher.ts +++ b/src/hooks/think-mode/switcher.ts @@ -154,8 +154,7 @@ export const THINKING_CONFIGS = { "zai-coding-plan": { extra_body: { thinking: { - type: "enabled", - clear_thinking: false, + type: "disabled", }, }, },