From 9464792cfc11d5e67036b2f23a64f7073c6cae5a Mon Sep 17 00:00:00 2001 From: PhuongDoan <95doanphuong@gmail.com> Date: Tue, 25 Aug 2026 03:23:58 +0700 Subject: [PATCH] feat(sse): add glm-5.3-max explicit effort tier (#11415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Validado em lote combinado (batch-0824g) contra o tip de release/v3.8.50: typecheck:core limpo, gates estáticos OK, 62/62 testes focados passando (23/23 do PR entre glm-5.3-catalog-and-effort-tiers.test.ts e zai-catalog-glm52.test.ts). Aditivo, espelha exatamente o padrão já existente glm-5.2-max. Obrigado pela contribuição, primeira PR bem-vinda! --- open-sse/config/glmProvider.ts | 11 ++++++++++ open-sse/executors/glm.ts | 2 ++ src/shared/constants/modelSpecs.ts | 8 ++++++++ src/shared/constants/pricing/shared-tiers.ts | 7 +++++++ .../glm-5.3-catalog-and-effort-tiers.test.ts | 20 ++++++++++++++++--- 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/open-sse/config/glmProvider.ts b/open-sse/config/glmProvider.ts index 8668de2c63..c11e5d14e5 100644 --- a/open-sse/config/glmProvider.ts +++ b/open-sse/config/glmProvider.ts @@ -48,6 +48,17 @@ export const GLM_SHARED_MODELS = Object.freeze([ supportsReasoning: true, supportedThinkingEfforts: ["low"], }, + { + // Explicit alias for the upstream default (max) — pins reasoning_effort so + // the tier survives an upstream default change, and mirrors glm-5.2-max UX. + id: "glm-5.3-max", + name: "GLM 5.3 Max", + contextLength: 1000000, + maxOutputTokens: 131072, + toolCalling: true, + supportsReasoning: true, + supportedThinkingEfforts: ["max"], + }, { // GLM-5.2 has two positive effective tiers: low/medium map to high and xhigh // maps to max; disabling thinking remains the separate thinking toggle. diff --git a/open-sse/executors/glm.ts b/open-sse/executors/glm.ts index eda8296255..194c8a952b 100644 --- a/open-sse/executors/glm.ts +++ b/open-sse/executors/glm.ts @@ -85,6 +85,8 @@ function parseGlmEffortTier(model: string): GlmEffortTier | null { return { baseModel: "glm-5.3", effort: "high", transport: "openai" }; case "glm-5.3-low": return { baseModel: "glm-5.3", effort: "low", transport: "openai" }; + case "glm-5.3-max": + return { baseModel: "glm-5.3", effort: "max", transport: "openai" }; default: return null; } diff --git a/src/shared/constants/modelSpecs.ts b/src/shared/constants/modelSpecs.ts index 8428284627..a8c238f080 100644 --- a/src/shared/constants/modelSpecs.ts +++ b/src/shared/constants/modelSpecs.ts @@ -70,6 +70,7 @@ const AUTHORITATIVE_CONTEXT_WINDOW_MODEL_IDS = new Set([ "glm-5.3", "glm-5.3-high", "glm-5.3-low", + "glm-5.3-max", "glm-5.2", "glm-5.2-high", "glm-5.2-max", @@ -573,6 +574,13 @@ export const MODEL_SPECS: Record = { supportsThinking: true, supportsTools: true, }, + "glm-5.3-max": { + maxOutputTokens: 131072, + contextWindow: 1000000, + thinkingBudgetCap: 38912, + supportsThinking: true, + supportsTools: true, + }, // ── Z.AI GLM-5.2 (1M context, 128K max output, effort tiers) ──── "glm-5.2": { diff --git a/src/shared/constants/pricing/shared-tiers.ts b/src/shared/constants/pricing/shared-tiers.ts index 8bd2e4ae4f..8004e43a47 100644 --- a/src/shared/constants/pricing/shared-tiers.ts +++ b/src/shared/constants/pricing/shared-tiers.ts @@ -135,6 +135,13 @@ export const GLM_PRICING = { reasoning: 5, cache_creation: 1.2, }, + "glm-5.3-max": { + input: 1.2, + output: 5, + cached: 0.3, + reasoning: 5, + cache_creation: 1.2, + }, "glm-5.2": { input: 1.2, output: 5, diff --git a/tests/unit/glm-5.3-catalog-and-effort-tiers.test.ts b/tests/unit/glm-5.3-catalog-and-effort-tiers.test.ts index 5d927de02a..ffe975d71d 100644 --- a/tests/unit/glm-5.3-catalog-and-effort-tiers.test.ts +++ b/tests/unit/glm-5.3-catalog-and-effort-tiers.test.ts @@ -22,7 +22,7 @@ const metadataRegistry = await import("../../src/lib/modelMetadataRegistry.ts"); const { shouldExposeSyncedEffortVariants, SYNCED_EFFORT_SKIP_PROVIDERS } = await import("../../open-sse/utils/syncedEffortVariants.ts"); -const GLM_5_3_IDS = ["glm-5.3", "glm-5.3-high", "glm-5.3-low"] as const; +const GLM_5_3_IDS = ["glm-5.3", "glm-5.3-high", "glm-5.3-low", "glm-5.3-max"] as const; // transformForTransport returns an opaque body; surface only the fields asserted below. type TransformedRequest = { @@ -99,6 +99,7 @@ test("catalog exposes only GLM effort tiers that each provider can route", () => ["glm-5.3", ["low", "high", "max"]], ["glm-5.3-high", ["high"]], ["glm-5.3-low", ["low"]], + ["glm-5.3-max", ["max"]], ["glm-5.2", ["high", "max"]], ["glm-5.2-high", ["high"]], ["glm-5.2-max", ["max"]], @@ -119,7 +120,6 @@ test("catalog exposes only GLM effort tiers that each provider can route", () => } } }); - for (const provider of ["glm", "glm-cn", "glmt"]) { test(`${provider} advertises the GLM-5.3 base model and effort tiers (GLM_SHARED_MODELS)`, () => { const ids = modelIds(provider); @@ -142,7 +142,7 @@ for (const provider of ["glm", "glm-cn", "glmt"]) { test("zai advertises the GLM-5.3 base model only (DefaultExecutor sends ids verbatim)", () => { const ids = modelIds("zai"); assert.ok(ids.includes("glm-5.3"), `zai should advertise glm-5.3; got ${ids.join(", ")}`); - for (const alias of ["glm-5.3-high", "glm-5.3-low"]) { + for (const alias of ["glm-5.3-high", "glm-5.3-low", "glm-5.3-max"]) { assert.ok( !ids.includes(alias), `zai must not list ${alias}: GlmExecutor-only alias, unknown upstream on the Anthropic endpoint` @@ -200,6 +200,20 @@ test("GlmExecutor resolves glm-5.3-low to reasoning_effort=low with thinking ena assert.equal(transformed.thinking?.type, "enabled"); }); +test("GlmExecutor resolves glm-5.3-max to an explicit reasoning_effort=max (pins the tier even if the upstream default changes)", () => { + const executor = new GlmExecutor("glm"); + const transformed = executor.transformForTransport( + "glm-5.3-max", + { messages: [{ role: "user", content: "hi" }] }, + false, + { apiKey: "glm-key" }, + "openai" + ) as TransformedRequest; + + assert.equal(transformed.model, "glm-5.3"); + assert.equal(transformed.reasoning_effort, "max"); + assert.equal(transformed.thinking?.type, "enabled"); +}); test("GlmExecutor leaves base glm-5.3 without an injected reasoning_effort (upstream default = max)", () => { const executor = new GlmExecutor("glm"); const transformed = executor.transformForTransport(