Skip to content

Commit cdf481c

Browse files
feat: add GLM-5 model support to Z.ai provider (#11440)
1 parent 897c372 commit cdf481c

3 files changed

Lines changed: 132 additions & 2 deletions

File tree

packages/types/src/providers/zai.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,21 @@ export const internationalZAiModels = {
120120
description:
121121
"GLM-4.7 is Zhipu's latest model with built-in thinking capabilities enabled by default. It provides enhanced reasoning for complex tasks while maintaining fast response times.",
122122
},
123+
"glm-5": {
124+
maxTokens: 16_384,
125+
contextWindow: 202_752,
126+
supportsImages: false,
127+
supportsPromptCache: true,
128+
supportsReasoningEffort: ["disable", "medium"],
129+
reasoningEffort: "medium",
130+
preserveReasoning: true,
131+
inputPrice: 0.6,
132+
outputPrice: 2.2,
133+
cacheWritesPrice: 0,
134+
cacheReadsPrice: 0.11,
135+
description:
136+
"GLM-5 is Zhipu's next-generation model with a 202k context window and built-in thinking capabilities. It delivers state-of-the-art reasoning, coding, and agentic performance.",
137+
},
123138
"glm-4.7-flash": {
124139
maxTokens: 16_384,
125140
contextWindow: 200_000,
@@ -281,6 +296,21 @@ export const mainlandZAiModels = {
281296
description:
282297
"GLM-4.7 is Zhipu's latest model with built-in thinking capabilities enabled by default. It provides enhanced reasoning for complex tasks while maintaining fast response times.",
283298
},
299+
"glm-5": {
300+
maxTokens: 16_384,
301+
contextWindow: 202_752,
302+
supportsImages: false,
303+
supportsPromptCache: true,
304+
supportsReasoningEffort: ["disable", "medium"],
305+
reasoningEffort: "medium",
306+
preserveReasoning: true,
307+
inputPrice: 0.29,
308+
outputPrice: 1.14,
309+
cacheWritesPrice: 0,
310+
cacheReadsPrice: 0.057,
311+
description:
312+
"GLM-5 is Zhipu's next-generation model with a 202k context window and built-in thinking capabilities. It delivers state-of-the-art reasoning, coding, and agentic performance.",
313+
},
284314
"glm-4.7-flash": {
285315
maxTokens: 16_384,
286316
contextWindow: 204_800,

src/api/providers/__tests__/zai.spec.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,22 @@ describe("ZAiHandler", () => {
121121
expect(model.info.preserveReasoning).toBe(true)
122122
})
123123

124+
it("should return GLM-5 international model with thinking support", () => {
125+
const testModelId: InternationalZAiModelId = "glm-5"
126+
const handlerWithModel = new ZAiHandler({
127+
apiModelId: testModelId,
128+
zaiApiKey: "test-zai-api-key",
129+
zaiApiLine: "international_coding",
130+
})
131+
const model = handlerWithModel.getModel()
132+
expect(model.id).toBe(testModelId)
133+
expect(model.info).toEqual(internationalZAiModels[testModelId])
134+
expect(model.info.contextWindow).toBe(202_752)
135+
expect(model.info.supportsReasoningEffort).toEqual(["disable", "medium"])
136+
expect(model.info.reasoningEffort).toBe("medium")
137+
expect(model.info.preserveReasoning).toBe(true)
138+
})
139+
124140
it("should return GLM-4.5v international model with vision support", () => {
125141
const testModelId: InternationalZAiModelId = "glm-4.5v"
126142
const handlerWithModel = new ZAiHandler({
@@ -203,6 +219,22 @@ describe("ZAiHandler", () => {
203219
expect(model.info.reasoningEffort).toBe("medium")
204220
expect(model.info.preserveReasoning).toBe(true)
205221
})
222+
223+
it("should return GLM-5 China model with thinking support", () => {
224+
const testModelId: MainlandZAiModelId = "glm-5"
225+
const handlerWithModel = new ZAiHandler({
226+
apiModelId: testModelId,
227+
zaiApiKey: "test-zai-api-key",
228+
zaiApiLine: "china_coding",
229+
})
230+
const model = handlerWithModel.getModel()
231+
expect(model.id).toBe(testModelId)
232+
expect(model.info).toEqual(mainlandZAiModels[testModelId])
233+
expect(model.info.contextWindow).toBe(202_752)
234+
expect(model.info.supportsReasoningEffort).toEqual(["disable", "medium"])
235+
expect(model.info.reasoningEffort).toBe("medium")
236+
expect(model.info.preserveReasoning).toBe(true)
237+
})
206238
})
207239

208240
describe("International API", () => {
@@ -508,6 +540,74 @@ describe("ZAiHandler", () => {
508540
})
509541
})
510542

543+
describe("GLM-5 Thinking Mode", () => {
544+
it("should enable thinking by default for GLM-5 (default reasoningEffort is medium)", async () => {
545+
const handlerWithModel = new ZAiHandler({
546+
apiModelId: "glm-5",
547+
zaiApiKey: "test-zai-api-key",
548+
zaiApiLine: "international_coding",
549+
})
550+
551+
async function* mockFullStream() {
552+
yield { type: "text-delta", text: "response" }
553+
}
554+
555+
mockStreamText.mockReturnValue({
556+
fullStream: mockFullStream(),
557+
usage: Promise.resolve({ inputTokens: 0, outputTokens: 0 }),
558+
})
559+
560+
const stream = handlerWithModel.createMessage("system prompt", [])
561+
for await (const _chunk of stream) {
562+
// drain
563+
}
564+
565+
expect(mockStreamText).toHaveBeenCalledWith(
566+
expect.objectContaining({
567+
providerOptions: {
568+
zhipu: {
569+
thinking: { type: "enabled" },
570+
},
571+
},
572+
}),
573+
)
574+
})
575+
576+
it("should disable thinking for GLM-5 when reasoningEffort is set to disable", async () => {
577+
const handlerWithModel = new ZAiHandler({
578+
apiModelId: "glm-5",
579+
zaiApiKey: "test-zai-api-key",
580+
zaiApiLine: "international_coding",
581+
enableReasoningEffort: true,
582+
reasoningEffort: "disable",
583+
})
584+
585+
async function* mockFullStream() {
586+
yield { type: "text-delta", text: "response" }
587+
}
588+
589+
mockStreamText.mockReturnValue({
590+
fullStream: mockFullStream(),
591+
usage: Promise.resolve({ inputTokens: 0, outputTokens: 0 }),
592+
})
593+
594+
const stream = handlerWithModel.createMessage("system prompt", [])
595+
for await (const _chunk of stream) {
596+
// drain
597+
}
598+
599+
expect(mockStreamText).toHaveBeenCalledWith(
600+
expect.objectContaining({
601+
providerOptions: {
602+
zhipu: {
603+
thinking: { type: "disabled" },
604+
},
605+
},
606+
}),
607+
)
608+
})
609+
})
610+
511611
describe("completePrompt", () => {
512612
it("should complete a prompt using generateText", async () => {
513613
mockGenerateText.mockResolvedValue({

src/api/providers/zai.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ export class ZAiHandler extends BaseProvider implements SingleCompletionHandler
115115
toolChoice: mapToolChoice(metadata?.tool_choice),
116116
}
117117

118-
// GLM-4.7 thinking mode: pass thinking parameter via providerOptions
119-
const isThinkingModel = modelId === "glm-4.7" && Array.isArray(info.supportsReasoningEffort)
118+
// Thinking mode: pass thinking parameter via providerOptions for models that support it (e.g. GLM-4.7, GLM-5)
119+
const isThinkingModel = Array.isArray(info.supportsReasoningEffort)
120120

121121
if (isThinkingModel) {
122122
const useReasoning = shouldUseReasoningEffort({ model: info, settings: this.options })

0 commit comments

Comments
 (0)