feat(pricing): add GLM-5.3-Flash pricing, model specs, and catalog registration (#11830)

Adiciona GLM-5.3-Flash ao catálogo com pricing/specs e teste próprio. Validado no worktree combinado (typecheck limpo, teste focado verde). Obrigado!
This commit is contained in:
Andrew B.
2026-08-30 07:09:33 -05:00
committed by GitHub
parent dfc84ba030
commit e0029eb5a6
7 changed files with 51 additions and 4 deletions

View File

@@ -18,6 +18,16 @@ export const GLM_ANTHROPIC_DEFAULT_BASE_URLS = Object.freeze({
});
export const GLM_SHARED_MODELS = Object.freeze([
{
id: "glm-5.3-flash",
name: "GLM 5.3 Flash",
contextLength: 1000000,
maxOutputTokens: 131072,
toolCalling: true,
supportsReasoning: true,
supportedThinkingEfforts: ["low", "high", "max"],
supportsVision: true,
},
{
// GLM-5.3 exposes low|high|max reasoning_effort (default max); -high/-low
// are OmniRoute aliases resolved by GlmExecutor::parseGlmEffortTier.

View File

@@ -19,6 +19,7 @@ export const zaiProvider: RegistryEntry = {
// unknown IDs. Use the `glm` provider for effort tiers. Vision models are
// likewise omitted (handled elsewhere).
models: [
{ id: "glm-5.3-flash", name: "GLM 5.3 Flash" },
{ id: "glm-5.3", name: "GLM 5.3" },
{ id: "glm-5.2", name: "GLM 5.2" },
{ id: "glm-5.1", name: "GLM 5.1" },

View File

@@ -87,6 +87,7 @@ describe("GLM Coding provider registry surfaces", () => {
expect(PROVIDER_ID_TO_ALIAS.glm).toBe("glm");
expect(byProviderId).toEqual(byAlias);
expect(byProviderId.map((model) => model.id)).toEqual([
"glm-5.3-flash",
"glm-5.3",
"glm-5.3-high",
"glm-5.3-low",
@@ -109,6 +110,7 @@ describe("GLM Coding provider registry surfaces", () => {
it("declares exact GLM reasoning-effort tiers across every shared GLM provider", () => {
const routedTiers = new Map<string, readonly string[]>([
["glm-5.3-flash", ["low", "high", "max"]],
["glm-5.3", ["low", "high", "max"]],
["glm-5.3-high", ["high"]],
["glm-5.3-low", ["low"]],
@@ -181,6 +183,7 @@ describe("GLM Coding provider registry surfaces", () => {
const get = (id: string) => models.find((m) => m.id === id);
expect(get("glm-5")?.toolCalling).toBe(true);
expect(get("glm-5.3-flash")?.toolCalling).toBe(true);
expect(get("glm-4.7-flash")?.toolCalling).toBe(true);
expect(get("glm-4.5-air")?.toolCalling).toBe(true);
expect(get("glm-5.2")?.toolCalling).toBe(true);
@@ -194,6 +197,13 @@ describe("GLM Coding provider registry surfaces", () => {
reasoning: 4.8,
cache_creation: 1.0,
});
expect(getPricingForModel("glm", "glm-5.3-flash")).toEqual({
input: 0.075,
output: 0.25,
cached: 0.015,
reasoning: 0.25,
cache_creation: 0.075,
});
expect(getPricingForModel("glm", "glm-4.7-flash")).toEqual({
input: 0,
output: 0,

View File

@@ -67,6 +67,7 @@ const BEDROCK_CLAUDE_ALIASES = (...modelIds: string[]) => [
// Keep native/bare Z.AI GLM-5.2 context authoritative, but do not blindly apply
// it to every provider-wrapped alias: hosted providers can and do cap lower.
const AUTHORITATIVE_CONTEXT_WINDOW_MODEL_IDS = new Set([
"glm-5.3-flash",
"glm-5.3",
"glm-5.3-high",
"glm-5.3-low",
@@ -553,6 +554,14 @@ export const MODEL_SPECS: Record<string, ModelSpec> = {
// ── Z.AI GLM-5.3 (1M context mirrored from 5.2 — same base model; 128K max
// output; effort via reasoning_effort param, tiers are OmniRoute aliases) ──
"glm-5.3-flash": {
maxOutputTokens: 131072,
contextWindow: 1000000,
thinkingBudgetCap: 38912,
supportsThinking: true,
supportsTools: true,
supportsVision: true,
},
"glm-5.3": {
maxOutputTokens: 131072,
contextWindow: 1000000,

View File

@@ -111,6 +111,14 @@ export const CLAUDE_SONNET_5_PRICING = {
};
export const GLM_PRICING = {
// GLM-5.3 Flash (2026-08-26, https://models.dev / Z.AI)
"glm-5.3-flash": {
input: 0.075,
output: 0.25,
cached: 0.015,
reasoning: 0.25,
cache_creation: 0.075,
},
// GLM-5.3 (2026-08-14): Z.ai hasn't published 5.3 rates yet — mirrored from
// GLM-5.2 (same base model; 5.1 and 5.2 also share identical rates).
// Correct when https://docs.z.ai/guides/overview/pricing lists glm-5.3.

View File

@@ -38,6 +38,7 @@ export const VISION_MODEL_ID_FRAGMENTS = [
"glm-4v",
"glm-4.5v",
"glm-4.6v",
"glm-5.3-flash",
"gpt-4o",
"gpt-4.1",
"gpt-4-turbo",

View File

@@ -96,6 +96,7 @@ test("catalog suppresses inferred tiers for every GLM registry entry without a p
test("catalog exposes only GLM effort tiers that each provider can route", () => {
const routedTiers = new Map<string, string[]>([
["glm-5.3-flash", ["low", "high", "max"]],
["glm-5.3", ["low", "high", "max"]],
["glm-5.3-high", ["high"]],
["glm-5.3-low", ["low"]],
@@ -139,9 +140,10 @@ for (const provider of ["glm", "glm-cn", "glmt"]) {
});
}
test("zai advertises the GLM-5.3 base model only (DefaultExecutor sends ids verbatim)", () => {
test("zai advertises the GLM-5.3 base model and GLM-5.3 Flash (DefaultExecutor sends ids verbatim)", () => {
const ids = modelIds("zai");
assert.ok(ids.includes("glm-5.3"), `zai should advertise glm-5.3; got ${ids.join(", ")}`);
assert.ok(ids.includes("glm-5.3-flash"), `zai should advertise glm-5.3-flash; got ${ids.join(", ")}`);
for (const alias of ["glm-5.3-high", "glm-5.3-low", "glm-5.3-max"]) {
assert.ok(
!ids.includes(alias),
@@ -150,17 +152,18 @@ test("zai advertises the GLM-5.3 base model only (DefaultExecutor sends ids verb
}
});
test("modelSpecs carries 1M/128K specs for all GLM-5.3 ids", () => {
for (const id of GLM_5_3_IDS) {
test("modelSpecs carries 1M/128K specs for all GLM-5.3 ids including flash", () => {
for (const id of [...GLM_5_3_IDS, "glm-5.3-flash"]) {
const spec = MODEL_SPECS[id];
assert.ok(spec, `MODEL_SPECS should include ${id}`);
assert.equal(spec.contextWindow, 1_000_000);
assert.equal(spec.maxOutputTokens, 131_072);
assert.equal(spec.supportsThinking, true);
}
assert.equal(MODEL_SPECS["glm-5.3-flash"]?.supportsVision, true);
});
test("GLM_PRICING covers the GLM-5.3 ids with GLM-5.2-parity rates", () => {
test("GLM_PRICING covers the GLM-5.3 ids with GLM-5.2-parity rates and GLM-5.3-Flash rates", () => {
const reference = GLM_PRICING["glm-5.2"];
assert.ok(reference, "glm-5.2 pricing reference missing");
for (const id of GLM_5_3_IDS) {
@@ -168,6 +171,11 @@ test("GLM_PRICING covers the GLM-5.3 ids with GLM-5.2-parity rates", () => {
assert.ok(pricing, `GLM_PRICING should include ${id}`);
assert.deepEqual(pricing, reference);
}
const flashPricing = GLM_PRICING["glm-5.3-flash"];
assert.ok(flashPricing, "glm-5.3-flash pricing missing");
assert.equal(flashPricing.input, 0.075);
assert.equal(flashPricing.output, 0.25);
assert.equal(flashPricing.cached, 0.015);
});
test("GlmExecutor resolves glm-5.3-high to reasoning_effort=high on the OpenAI coding transport", () => {