From de6f4b2c91ceaea33b536612273754508ecf181d Mon Sep 17 00:00:00 2001 From: sisyphus-dev-ai Date: Sat, 24 Jan 2026 07:20:46 +0000 Subject: [PATCH] feat(think-mode): add GLM-4.7 thinking mode support Add thinking mode support for Z.AI's GLM-4.7 model via the zai-coding-plan provider. Changes: - Add zai-coding-plan to THINKING_CONFIGS with extra_body.thinking config - Add glm pattern to THINKING_CAPABLE_MODELS - Add comprehensive tests for GLM thinking mode GLM-4.7 uses OpenAI-compatible API with extra_body wrapper for thinking: - thinking.type: 'enabled' or 'disabled' - thinking.clear_thinking: false (Preserved Thinking mode) Closes #1030 --- src/hooks/think-mode/switcher.test.ts | 67 +++++++++++++++++++++++++++ src/hooks/think-mode/switcher.ts | 13 ++++++ 2 files changed, 80 insertions(+) diff --git a/src/hooks/think-mode/switcher.test.ts b/src/hooks/think-mode/switcher.test.ts index 40b66d0c3..facc3cdfb 100644 --- a/src/hooks/think-mode/switcher.test.ts +++ b/src/hooks/think-mode/switcher.test.ts @@ -458,4 +458,71 @@ 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 + const config = getThinkingConfig("zai-coding-plan", "glm-4.7") + + // #then should return zai-coding-plan thinking config + expect(config).not.toBeNull() + expect(config?.providerOptions).toBeDefined() + const zaiOptions = (config?.providerOptions as Record)?.[ + "zai-coding-plan" + ] as Record + 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) + }) + + it("should return thinking config for glm-4.6v (multimodal)", () => { + // #given zai-coding-plan provider with glm-4.6v model + const config = getThinkingConfig("zai-coding-plan", "glm-4.6v") + + // #then should return zai-coding-plan thinking config + expect(config).not.toBeNull() + expect(config?.providerOptions).toBeDefined() + }) + + it("should return null for non-GLM models on zai-coding-plan", () => { + // #given zai-coding-plan provider with unknown model + const config = getThinkingConfig("zai-coding-plan", "some-other-model") + + // #then should return null + expect(config).toBeNull() + }) + }) + + describe("HIGH_VARIANT_MAP for GLM", () => { + it("should NOT have high variant for glm-4.7 (thinking enabled by default)", () => { + // #given glm-4.7 model + const variant = getHighVariant("glm-4.7") + + // #then should return null (no high variant needed) + expect(variant).toBeNull() + }) + + it("should NOT have high variant for glm-4.6v", () => { + // #given glm-4.6v model + const variant = getHighVariant("glm-4.6v") + + // #then should return null + expect(variant).toBeNull() + }) + }) + }) + + describe("THINKING_CONFIGS structure for zai-coding-plan", () => { + it("should have correct structure for zai-coding-plan", () => { + const config = THINKING_CONFIGS["zai-coding-plan"] + expect(config.providerOptions).toBeDefined() + const zaiOptions = (config.providerOptions as Record)?.[ + "zai-coding-plan" + ] as Record + expect(zaiOptions?.extra_body).toBeDefined() + }) + }) }) diff --git a/src/hooks/think-mode/switcher.ts b/src/hooks/think-mode/switcher.ts index 2add6b9e9..78616af3e 100644 --- a/src/hooks/think-mode/switcher.ts +++ b/src/hooks/think-mode/switcher.ts @@ -149,6 +149,18 @@ export const THINKING_CONFIGS = { openai: { reasoning_effort: "high", }, + "zai-coding-plan": { + providerOptions: { + "zai-coding-plan": { + extra_body: { + thinking: { + type: "enabled", + clear_thinking: false, + }, + }, + }, + }, + }, } as const satisfies Record> const THINKING_CAPABLE_MODELS = { @@ -157,6 +169,7 @@ const THINKING_CAPABLE_MODELS = { google: ["gemini-2", "gemini-3"], "google-vertex": ["gemini-2", "gemini-3"], openai: ["gpt-5", "o1", "o3"], + "zai-coding-plan": ["glm"], } as const satisfies Record export function getHighVariant(modelID: string): string | null {