From c8652ca212221f086bb19cf48ff395de1a1490a2 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Sat, 15 Aug 2026 14:27:45 +0900 Subject: [PATCH] feat(ai): add Z.AI GLM-5.3 --- packages/ai/changes.md | 33 +++++++++- packages/ai/scripts/generate-models.ts | 38 ++++++++++-- packages/ai/src/providers/data/.manifest.json | 2 +- .../ai/src/providers/data/zai-coding-cn.json | 2 +- packages/ai/src/providers/data/zai.json | 2 +- .../openai-completions-tool-choice.test.ts | 62 ++++++++++++++++++- packages/coding-agent/changes.md | 15 +++++ .../coding-agent/src/core/model-resolver.ts | 4 +- .../coding-agent/test/model-resolver.test.ts | 6 +- 9 files changed, 149 insertions(+), 15 deletions(-) diff --git a/packages/ai/changes.md b/packages/ai/changes.md index 71bad7110d..7cc40ee1c9 100644 --- a/packages/ai/changes.md +++ b/packages/ai/changes.md @@ -1,5 +1,35 @@ # changes.md — ai +## Add GLM-5.3 to the Z.AI Coding Plan catalog (2026-08-15) + +### What changed + +- `scripts/generate-models.ts`: added reviewed `glm-5.3` fallback metadata that live `models.dev` values can override, including the official 1M-token context, 128K-token output limit, and low/high/max reasoning-effort mapping. +- `src/providers/data/{zai,zai-coding-cn}.json`: regenerated the committed Z.AI snapshots and added `glm-5.3` to the global and China Coding Plan catalogs. +- `test/openai-completions-tool-choice.test.ts`: covers the generated catalog values and the exact `reasoning_effort` payload mapping. + +### Why + +- Z.AI released GLM-5.3 to every Coding Plan tier before adding it to `models.dev`; without a stable fallback, strict generation omits a model that the provider endpoint already serves. +- Z.AI documents the general GLM-5.3 API as coming soon. Coding Plan therefore retains zero metered cost metadata rather than borrowing unannounced API pricing. + +### Why this cannot be expressed as an extension + +- Built-in model IDs, provider request metadata, and their generated TypeScript types are fixed before coding-agent extensions load. + +### Modified upstream files + +- `scripts/generate-models.ts` +- `src/providers/data/.manifest.json` +- `src/providers/data/zai.json` +- `src/providers/data/zai-coding-cn.json` +- `test/openai-completions-tool-choice.test.ts` + +### Expected merge conflict zones + +- MEDIUM: the Z.AI branch in `loadModelsDevData()` when `models.dev` begins publishing GLM-5.3. +- MEDIUM: generated Z.AI provider JSON whenever its live catalog changes. + ## Follow Groq Qwen catalog replacement during generation (2026-08-04) ### What changed @@ -153,7 +183,6 @@ an import + re-export. If upstream edits those predicates, port the edit into `src/utils/prompt-cache-ttl.ts` so the resolver and the adapters stay in agreement. - ## Cover Claude Opus 5 in Anthropic adaptive-thinking metadata (2026-07-25) ### What changed @@ -164,7 +193,7 @@ `mapThinkingLevelToEffort` maps Opus 5 `xhigh`/`max` to native efforts instead of collapsing them to `high`. - `src/providers/data/*.json`: regenerated so every provider that serves Opus 5 (anthropic, github-copilot, opencode, vercel-ai-gateway, openrouter, amazon-bedrock) carries `forceAdaptiveThinking`, `supportsTemperature: - false`, and the `xhigh`/`max` thinking level map. +false`, and the `xhigh`/`max` thinking level map. ### Why diff --git a/packages/ai/scripts/generate-models.ts b/packages/ai/scripts/generate-models.ts index 5772bd1b06..6432a57107 100644 --- a/packages/ai/scripts/generate-models.ts +++ b/packages/ai/scripts/generate-models.ts @@ -237,6 +237,17 @@ const NVIDIA_NIM_UNSUPPORTED_MODELS = new Set([ "upstage/solar-10.7b-instruct", ]); const ZAI_TOOL_STREAM_UNSUPPORTED_MODELS = new Set(["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v"]); +const ZAI_CODING_STABLE_MODELS = { + "glm-5.3": { + id: "glm-5.3", + name: "GLM-5.3", + tool_call: true, + reasoning: true, + reasoning_options: [{ type: "effort", values: ["low", "high", "max"] }], + limit: { context: 1_000_000, output: 131_072 }, + modalities: { input: ["text"] }, + }, +} satisfies Record; const ZAI_GLM52_THINKING_LEVEL_MAP = { minimal: null, low: "high", @@ -244,6 +255,15 @@ const ZAI_GLM52_THINKING_LEVEL_MAP = { high: "high", max: "max", } as const; +const ZAI_GLM53_THINKING_LEVEL_MAP = { + off: "low", + minimal: "low", + low: "low", + medium: "high", + high: "high", + xhigh: "max", + max: "max", +} as const; const OPENCODE_GO_GLM52_THINKING_LEVEL_MAP = { off: null, minimal: null, @@ -1513,13 +1533,23 @@ async function loadModelsDevData(): Promise[]> { ] as const; if (data["zai-coding-plan"]?.models) { + const liveZaiModels = data["zai-coding-plan"].models as Record; + const zaiModels: Record = { + ...ZAI_CODING_STABLE_MODELS, + ...liveZaiModels, + }; for (const { provider, baseUrl } of zaiCodingPlanVariants) { - for (const [modelId, model] of Object.entries(data["zai-coding-plan"].models)) { + for (const [modelId, model] of Object.entries(zaiModels)) { const m = model as ModelsDevModel; if (m.tool_call !== true) continue; const supportsImage = m.modalities?.input?.includes("image"); - const isGlm52 = modelId === "glm-5.2"; + const thinkingLevelMap = + modelId === "glm-5.2" + ? ZAI_GLM52_THINKING_LEVEL_MAP + : modelId === "glm-5.3" + ? ZAI_GLM53_THINKING_LEVEL_MAP + : undefined; models.push({ id: modelId, @@ -1528,7 +1558,7 @@ async function loadModelsDevData(): Promise[]> { provider, baseUrl, reasoning: m.reasoning === true, - ...(isGlm52 ? { thinkingLevelMap: ZAI_GLM52_THINKING_LEVEL_MAP } : {}), + ...(thinkingLevelMap ? { thinkingLevelMap } : {}), input: supportsImage ? ["text", "image"] : ["text"], cost: { input: m.cost?.input || 0, @@ -1539,7 +1569,7 @@ async function loadModelsDevData(): Promise[]> { compat: { supportsDeveloperRole: false, thinkingFormat: "zai", - ...(isGlm52 ? { supportsReasoningEffort: true } : {}), + ...(thinkingLevelMap ? { supportsReasoningEffort: true } : {}), ...(!ZAI_TOOL_STREAM_UNSUPPORTED_MODELS.has(modelId) ? { zaiToolStream: true } : {}), }, contextWindow: m.limit?.context || 4096, diff --git a/packages/ai/src/providers/data/.manifest.json b/packages/ai/src/providers/data/.manifest.json index a8bab74390..d502226f79 100644 --- a/packages/ai/src/providers/data/.manifest.json +++ b/packages/ai/src/providers/data/.manifest.json @@ -1 +1 @@ -{"schemaVersion":3,"generatedAt":"2026-08-06T02:49:06.410Z","structureHash":"650ad7731abd79483e6ec6647ab8618aac3394e65a082a49a42a66d6e729ef88","files":{"alibaba-token-plan.json":"e84668baa90b6ea64fbd9a5192bd3945c5011bc79ac2b4f3e7b3b58467d4403d","amazon-bedrock.json":"d0a215122f81e4497ef45a5f65fd8df067fd22103f10049ad77f4e2f4f10edb4","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"5bf1deecb96805ccba8ec004680e54b1c73ac29a8bfbbf4adaf7c5e66c1ceef2","azure-openai-responses.json":"5315b6a2299fefbdbb6cc13a720544077c9498132ad5e3a7d76a8c1daa8e9335","cerebras.json":"3fd3e19b83ab4be07d27817e25e5be0ffe4158b1394f0311d6a22d9f03847728","cloudflare-ai-gateway.json":"cd050aa8cf61b73b13d532341639e1d0f22fd29d8a889ca669d412cd4b477d45","cloudflare-workers-ai.json":"03b19d69433c843512e953390d51d4578e9b91f19098a9b14ff820c001623598","deepseek.json":"0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b","fireworks.json":"0e10df29511e70b6987cbe27d8d1222c2c5f63b6ddb66c2401a2990a61a5999e","github-copilot.json":"08fd4f44d648f812ea4eeb2aed3e5fbbe08f482afbb51ef64eac1c8ee414f2f9","google-vertex.json":"99d0b89ac9d8dc460ed922236abffbe88c9381af4d35046d2ad3a8f08fa2560c","google.json":"bcf8a8d59ccbb75bc6fb4a261a37ac4b7c806f40ee7313b4411178964be5fa37","groq.json":"f1eb899453e70b5e4479fe6eb78869ee99121fa6d4a019a5a05ab42d2ada8992","huggingface.json":"c5e6e5a9a273f3829160b66ca41d7b400e1bd9e75b44364040962c69f38ba1e2","kimi-coding.json":"9d73ca15313628bb8cf80c21e6466164e350d68471e2d7205b5e21bcd2c141f3","minimax-cn.json":"8ccd71ff838f4b78bb88809babb0dc32a4fcfaec2bc4f4083841000428df4f77","minimax.json":"253edd4c910a41c8bb252400ba099f3a4de0a8900ce154319288ab091b372987","mistral.json":"4f9d84bf1ba10cb14ff2c9e23e77d63441756ef3500375dd4ad10094614b215b","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"33c498ab62940fe9ca659826c35cc922a77938a5f7edbe4443c10d9133323e87","openai-codex.json":"4a73818291987693fcb53e9e61b4be3429ffd78b3f64ea877a34c5f9928c89e1","openai.json":"2c5d2354c55a80671f20f555844986ab381fee93da26e03c0e42cbae77b519a5","opencode-go.json":"5e6d8256e3b3db2ee3f6783763b8e72b415612f1aa4acf6a305cea51888dde85","opencode.json":"6307dcd0b5167bcb8ad364d98b70ed1a6e22a42328e838c2693c7ef76025d96e","openrouter.json":"d9764c031e634b6ce95e0300d913ea85eef5030f350913a8ea63e221da4a7fa2","qwen-token-plan-cn.json":"cc345d44c31b0ba3b1b244f8b56342ede6657584653f3af176026bf8dbb37cd5","qwen-token-plan.json":"12c43b2b8032e1b64222616588daf400156f3819be4de3124fc997a69eccbda8","together.json":"c01b9a0790a0d4bc442953a9e66d733a5a058cc7b82826aa58a2946a7012d416","vercel-ai-gateway.json":"eada6738e094247dd9dded694f1a7baac96fbc85c8a2c8dc6d5bfae2555b84d4","xai.json":"4cbdbfbbf915246369b9bacbc6f1feeb56accdac9f3444456343f750547f2f38","xiaomi-token-plan-ams.json":"b1886b741867c90a838c377e86ad64b26ca6b0e349f1a75bc5fd4ed99df03c21","xiaomi-token-plan-cn.json":"11f459b794eddd64a9d9d102f2799c364732b7f0d562e22573f4995a5d1e1a30","xiaomi-token-plan-sgp.json":"0b9953d03b75260aba0ad604cc76d7ed26d6841448819e8c7488bf0d90948d2c","xiaomi.json":"edf39e0edd9dcae23e669635ea782e5870c0b9663d4b918b8ff9bd307cfe35f8","zai-coding-cn.json":"c2d1e137238b6f248b5f620f76b64520aa2ba1543e991dd0d14b708e50c8cd66","zai.json":"cb48b354442f1e49919cd93b928216d5d881d2f98a55349ad592a8e68bb8e6c3"}} +{"schemaVersion":3,"generatedAt":"2026-08-15T05:28:30.012Z","structureHash":"5778e96dc4083e50adb9c4a1ebc53934e92074598f3bfcc6b4e677a434bf0afd","files":{"alibaba-token-plan.json":"e84668baa90b6ea64fbd9a5192bd3945c5011bc79ac2b4f3e7b3b58467d4403d","amazon-bedrock.json":"d0a215122f81e4497ef45a5f65fd8df067fd22103f10049ad77f4e2f4f10edb4","ant-ling.json":"4979fe79d99ed97382d7ce40170c6132e932e77906de1eb54464c042e7d63633","anthropic.json":"5bf1deecb96805ccba8ec004680e54b1c73ac29a8bfbbf4adaf7c5e66c1ceef2","azure-openai-responses.json":"5315b6a2299fefbdbb6cc13a720544077c9498132ad5e3a7d76a8c1daa8e9335","cerebras.json":"3fd3e19b83ab4be07d27817e25e5be0ffe4158b1394f0311d6a22d9f03847728","cloudflare-ai-gateway.json":"cd050aa8cf61b73b13d532341639e1d0f22fd29d8a889ca669d412cd4b477d45","cloudflare-workers-ai.json":"03b19d69433c843512e953390d51d4578e9b91f19098a9b14ff820c001623598","deepseek.json":"0dcc807a4e5827b488c6ceac87884ff6e735e01cf4f2ddfec9dd812e6fde041b","fireworks.json":"0e10df29511e70b6987cbe27d8d1222c2c5f63b6ddb66c2401a2990a61a5999e","github-copilot.json":"08fd4f44d648f812ea4eeb2aed3e5fbbe08f482afbb51ef64eac1c8ee414f2f9","google-vertex.json":"99d0b89ac9d8dc460ed922236abffbe88c9381af4d35046d2ad3a8f08fa2560c","google.json":"bcf8a8d59ccbb75bc6fb4a261a37ac4b7c806f40ee7313b4411178964be5fa37","groq.json":"f1eb899453e70b5e4479fe6eb78869ee99121fa6d4a019a5a05ab42d2ada8992","huggingface.json":"c5e6e5a9a273f3829160b66ca41d7b400e1bd9e75b44364040962c69f38ba1e2","kimi-coding.json":"9d73ca15313628bb8cf80c21e6466164e350d68471e2d7205b5e21bcd2c141f3","minimax-cn.json":"8ccd71ff838f4b78bb88809babb0dc32a4fcfaec2bc4f4083841000428df4f77","minimax.json":"253edd4c910a41c8bb252400ba099f3a4de0a8900ce154319288ab091b372987","mistral.json":"4f9d84bf1ba10cb14ff2c9e23e77d63441756ef3500375dd4ad10094614b215b","moonshotai-cn.json":"1e6146ff3477883636448c0f44222f0a52b3c4562ef8f4eecf7e941cdd59d12e","moonshotai.json":"d8d5209873058ddccd37c1f026833e2ea3f9476c3dc9628b4a940d407acc0b2e","nvidia.json":"33c498ab62940fe9ca659826c35cc922a77938a5f7edbe4443c10d9133323e87","openai-codex.json":"4a73818291987693fcb53e9e61b4be3429ffd78b3f64ea877a34c5f9928c89e1","openai.json":"2c5d2354c55a80671f20f555844986ab381fee93da26e03c0e42cbae77b519a5","opencode-go.json":"5e6d8256e3b3db2ee3f6783763b8e72b415612f1aa4acf6a305cea51888dde85","opencode.json":"6307dcd0b5167bcb8ad364d98b70ed1a6e22a42328e838c2693c7ef76025d96e","openrouter.json":"d9764c031e634b6ce95e0300d913ea85eef5030f350913a8ea63e221da4a7fa2","qwen-token-plan-cn.json":"cc345d44c31b0ba3b1b244f8b56342ede6657584653f3af176026bf8dbb37cd5","qwen-token-plan.json":"12c43b2b8032e1b64222616588daf400156f3819be4de3124fc997a69eccbda8","together.json":"c01b9a0790a0d4bc442953a9e66d733a5a058cc7b82826aa58a2946a7012d416","vercel-ai-gateway.json":"eada6738e094247dd9dded694f1a7baac96fbc85c8a2c8dc6d5bfae2555b84d4","xai.json":"4cbdbfbbf915246369b9bacbc6f1feeb56accdac9f3444456343f750547f2f38","xiaomi-token-plan-ams.json":"b1886b741867c90a838c377e86ad64b26ca6b0e349f1a75bc5fd4ed99df03c21","xiaomi-token-plan-cn.json":"11f459b794eddd64a9d9d102f2799c364732b7f0d562e22573f4995a5d1e1a30","xiaomi-token-plan-sgp.json":"0b9953d03b75260aba0ad604cc76d7ed26d6841448819e8c7488bf0d90948d2c","xiaomi.json":"edf39e0edd9dcae23e669635ea782e5870c0b9663d4b918b8ff9bd307cfe35f8","zai-coding-cn.json":"ce947350fde7e6b8cda77cc9301027c54801b3aec6d15ea945fa9ad075921730","zai.json":"05026fc8e0c7bdae51fdaf8e4757d8a7d34f09c763b63dd3237f8f559e8453b6"}} diff --git a/packages/ai/src/providers/data/zai-coding-cn.json b/packages/ai/src/providers/data/zai-coding-cn.json index dfd0289f04..babf5a3f67 100644 --- a/packages/ai/src/providers/data/zai-coding-cn.json +++ b/packages/ai/src/providers/data/zai-coding-cn.json @@ -1 +1 @@ -{"openai-completions":{"glm-4.7":{"id":"glm-4.7","name":"GLM-4.7","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":204800,"maxTokens":131072},"glm-5-turbo":{"id":"glm-5-turbo","name":"GLM-5-Turbo","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":200000,"maxTokens":131072},"glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.2-highspeed":{"id":"glm-5.2-highspeed","name":"GLM-5.2 Highspeed","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072}}} +{"openai-completions":{"glm-4.7":{"id":"glm-4.7","name":"GLM-4.7","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":204800,"maxTokens":131072},"glm-5-turbo":{"id":"glm-5-turbo","name":"GLM-5-Turbo","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":200000,"maxTokens":131072},"glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.2-highspeed":{"id":"glm-5.2-highspeed","name":"GLM-5.2 Highspeed","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.3":{"id":"glm-5.3","name":"GLM-5.3","api":"openai-completions","provider":"zai-coding-cn","baseUrl":"https://open.bigmodel.cn/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"off":"low","minimal":"low","low":"low","medium":"high","high":"high","xhigh":"max","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072}}} diff --git a/packages/ai/src/providers/data/zai.json b/packages/ai/src/providers/data/zai.json index e9fccd27d8..2ad9a7721f 100644 --- a/packages/ai/src/providers/data/zai.json +++ b/packages/ai/src/providers/data/zai.json @@ -1 +1 @@ -{"openai-completions":{"glm-4.7":{"id":"glm-4.7","name":"GLM-4.7","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":204800,"maxTokens":131072},"glm-5-turbo":{"id":"glm-5-turbo","name":"GLM-5-Turbo","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":200000,"maxTokens":131072},"glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.2-highspeed":{"id":"glm-5.2-highspeed","name":"GLM-5.2 Highspeed","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072}}} +{"openai-completions":{"glm-4.7":{"id":"glm-4.7","name":"GLM-4.7","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":204800,"maxTokens":131072},"glm-5-turbo":{"id":"glm-5-turbo","name":"GLM-5-Turbo","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":200000,"maxTokens":131072},"glm-5.2":{"id":"glm-5.2","name":"GLM-5.2","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"minimal":null,"low":"high","medium":"high","high":"high","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.2-highspeed":{"id":"glm-5.2-highspeed","name":"GLM-5.2 Highspeed","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":false,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072},"glm-5.3":{"id":"glm-5.3","name":"GLM-5.3","api":"openai-completions","provider":"zai","baseUrl":"https://api.z.ai/api/coding/paas/v4","reasoning":true,"thinkingLevelMap":{"off":"low","minimal":"low","low":"low","medium":"high","high":"high","xhigh":"max","max":"max"},"input":["text"],"cost":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0},"compat":{"supportsStore":false,"supportsDeveloperRole":false,"supportsReasoningEffort":true,"maxTokensField":"max_tokens","thinkingFormat":"zai","zaiToolStream":true},"contextWindow":1000000,"maxTokens":131072}}} diff --git a/packages/ai/test/openai-completions-tool-choice.test.ts b/packages/ai/test/openai-completions-tool-choice.test.ts index 380c2f8458..4aa88f38b8 100644 --- a/packages/ai/test/openai-completions-tool-choice.test.ts +++ b/packages/ai/test/openai-completions-tool-choice.test.ts @@ -372,6 +372,7 @@ describe("openai-completions tool_choice", () => { expect(getModel("zai", "glm-4.7")?.compat?.zaiToolStream).toBe(true); expect(getModel("zai", "glm-5-turbo")?.compat?.zaiToolStream).toBe(true); expect(getModel("zai", "glm-5.2")?.compat?.zaiToolStream).toBe(true); + expect(getModel("zai", "glm-5.3")?.compat?.zaiToolStream).toBe(true); }); it("stores z.ai GLM-5.2 effort metadata", () => { @@ -387,6 +388,61 @@ describe("openai-completions tool_choice", () => { }); } }); + it("stores z.ai GLM-5.3 catalog and effort metadata", () => { + for (const provider of ["zai", "zai-coding-cn"] as const) { + const model = getModel(provider, "glm-5.3")!; + expect(model).toMatchObject({ + name: "GLM-5.3", + reasoning: true, + input: ["text"], + contextWindow: 1_000_000, + maxTokens: 131_072, + }); + expect(model.compat?.supportsReasoningEffort).toBe(true); + expect(model.thinkingLevelMap).toEqual({ + off: "low", + minimal: "low", + low: "low", + medium: "high", + high: "high", + xhigh: "max", + max: "max", + }); + } + }); + + it("maps z.ai GLM-5.3 thinking levels to reasoning_effort", async () => { + const model = getModel("zai", "glm-5.3")!; + const cases = [ + { reasoning: "low", effort: "low" }, + { reasoning: "medium", effort: "high" }, + { reasoning: "high", effort: "high" }, + { reasoning: "xhigh", effort: "max" }, + { reasoning: "max", effort: "max" }, + ] as const; + + for (const testCase of cases) { + let payload: unknown; + + await streamSimple( + model, + { + messages: [{ role: "user", content: "Hi", timestamp: Date.now() }], + }, + { + apiKey: "test", + reasoning: testCase.reasoning, + onPayload: (params: unknown) => { + payload = params; + }, + }, + ).result(); + + const params = (payload ?? mockState.lastParams) as { thinking?: unknown; reasoning_effort?: string }; + expect(params.thinking).toEqual({ type: "enabled", clear_thinking: false }); + expect(params.reasoning_effort).toBe(testCase.effort); + } + }); it("maps z.ai GLM-5.2 thinking levels to reasoning_effort", async () => { const model = getModel("zai", "glm-5.2")!; @@ -1555,7 +1611,11 @@ describe("openai-completions tool_choice", () => { }); it("sends max_tokens for Z.AI completions models", async () => { - const cases = [getModel("zai", "glm-5-turbo")!, getModel("zai", "glm-5.2")!] as const; + const cases = [ + getModel("zai", "glm-5-turbo")!, + getModel("zai", "glm-5.2")!, + getModel("zai", "glm-5.3")!, + ] as const; for (const model of cases) { expect(model.compat?.maxTokensField).toBe("max_tokens"); diff --git a/packages/coding-agent/changes.md b/packages/coding-agent/changes.md index 126dbc64b3..6b23da9a14 100644 --- a/packages/coding-agent/changes.md +++ b/packages/coding-agent/changes.md @@ -1,5 +1,20 @@ # Local fork changes +## 2026-08-15 — Track GLM-5.3 as the Z.AI default + +### What changed + +- Updated the global and China Z.AI provider defaults from `glm-5.2` to the newly bundled `glm-5.3`. +- Updated default-resolution coverage to require the selected model to exist in each generated catalog. + +### Why this lives in the fork + +- Senpi owns initial provider-model selection; the AI package only supplies the catalog. + +### Merge notes + +- LOW: `src/core/model-resolver.ts` conflicts only when upstream changes provider defaults. + ## 2026-08-03 — Keep Bun off unpublished workspace identities ### What changed diff --git a/packages/coding-agent/src/core/model-resolver.ts b/packages/coding-agent/src/core/model-resolver.ts index 2e50a543bd..3d9481064f 100644 --- a/packages/coding-agent/src/core/model-resolver.ts +++ b/packages/coding-agent/src/core/model-resolver.ts @@ -44,8 +44,8 @@ export const defaultModelPerProvider: Record = { xai: "grok-4.5", groq: "openai/gpt-oss-120b", cerebras: "zai-glm-4.7", - zai: "glm-5.2", - "zai-coding-cn": "glm-5.2", + zai: "glm-5.3", + "zai-coding-cn": "glm-5.3", mistral: "devstral-medium-latest", minimax: "MiniMax-M2.7", "minimax-cn": "MiniMax-M2.7", diff --git a/packages/coding-agent/test/model-resolver.test.ts b/packages/coding-agent/test/model-resolver.test.ts index 688129873a..d0f842731a 100644 --- a/packages/coding-agent/test/model-resolver.test.ts +++ b/packages/coding-agent/test/model-resolver.test.ts @@ -643,8 +643,8 @@ describe("default model selection", () => { }); test("zai, minimax, cerebras, and ant-ling defaults track current models", () => { - expect(defaultModelPerProvider.zai).toBe("glm-5.2"); - expect(defaultModelPerProvider["zai-coding-cn"]).toBe("glm-5.2"); + expect(defaultModelPerProvider.zai).toBe("glm-5.3"); + expect(defaultModelPerProvider["zai-coding-cn"]).toBe("glm-5.3"); expect(defaultModelPerProvider.minimax).toBe("MiniMax-M2.7"); expect(defaultModelPerProvider["minimax-cn"]).toBe("MiniMax-M2.7"); expect(defaultModelPerProvider.cerebras).toBe("zai-glm-4.7"); @@ -730,7 +730,7 @@ describe("default model selection", () => { expect(result.provenance).toBe("provider-default"); expect(result.model?.provider).toBe("zai"); - expect(result.model?.id).toBe("glm-5.2"); + expect(result.model?.id).toBe("glm-5.3"); }); test("findInitialModel ignores an unauthenticated saved default", async () => {