From b1fd7f746e72560a6156576b32cd5ac3df72f913 Mon Sep 17 00:00:00 2001 From: Robert Fleming Date: Thu, 27 Aug 2026 18:57:17 +0000 Subject: [PATCH] Replace GLM 5.2 with GLM 5.3 Flash --- .../workshop-backend/__tests__/ai-models.test.ts | 12 ++++++++++++ packages/workshop-backend/src/ai-models.ts | 13 ++++++++++++- packages/workshop-shared/src/api.ts | 5 +++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/packages/workshop-backend/__tests__/ai-models.test.ts b/packages/workshop-backend/__tests__/ai-models.test.ts index c6e991452..68224aff4 100644 --- a/packages/workshop-backend/__tests__/ai-models.test.ts +++ b/packages/workshop-backend/__tests__/ai-models.test.ts @@ -526,6 +526,18 @@ describe("PDF attachment bridging", () => { return JSON.parse(capturedRequests[0].body); } + it("preserves image input for GLM 5.3 Flash", async () => { + const handle = getModel(env(), + {...WORKERS_AI_CONFIG, model: "@cf/zai-org/glm-5.3-flash"}, INITIATOR); + expect(handle.model).toMatchObject({reasoning: true, input: ["text", "image"]}); + const body = await capturePdfRequest(handle) as { + messages: { content: { image_url?: { url: string } }[] }[], + }; + expect(body.messages[0].content).toContainEqual(expect.objectContaining({ + image_url: { url: "data:image/png;base64,iVBOR" }, + })); + }, 15000); + it("sends Anthropic PDFs as document blocks", async () => { const handle = getModel(env(), ANTHROPIC_CONFIG, INITIATOR); const body = await capturePdfRequest(handle) as diff --git a/packages/workshop-backend/src/ai-models.ts b/packages/workshop-backend/src/ai-models.ts index b1bb2c3eb..d2807a02a 100644 --- a/packages/workshop-backend/src/ai-models.ts +++ b/packages/workshop-backend/src/ai-models.ts @@ -125,6 +125,16 @@ const API_STREAMS: Record> = { const ZERO_COST: ModelCost = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }; +// Remove when pi's bundled Workers AI catalog includes this model. +const GLM_5_3_FLASH_FALLBACK: Model<"openai-completions"> = { + id: "@cf/zai-org/glm-5.3-flash", name: "GLM 5.3 Flash", + api: "openai-completions", provider: "cloudflare-workers-ai", + baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1", + reasoning: true, input: ["text", "image"], + cost: {input: 0.15, output: 0.5, cacheRead: 0.03, cacheWrite: 0}, + contextWindow: 1048576, maxTokens: WORKERS_AI_OUTPUT_LIMIT, +}; + // Consult pi's builtin catalog for cost/compat metadata of a known model id. Unknown models are // fine (synthesized with zero cost). Import per-provider, not providers/all. function catalogModel(provider: AiModelConfig["provider"], modelId: string): Model | undefined { @@ -132,7 +142,8 @@ function catalogModel(provider: AiModelConfig["provider"], modelId: string): Mod case "anthropic": return (ANTHROPIC_MODELS as Record>)[modelId]; case "openai": return (OPENAI_MODELS as Record>)[modelId]; case "google": return (GOOGLE_MODELS as Record>)[modelId]; - case "cloudflare": return (CLOUDFLARE_WORKERS_AI_MODELS as Record>)[modelId]; + case "cloudflare": return (CLOUDFLARE_WORKERS_AI_MODELS as Record>)[modelId] ?? + (modelId === GLM_5_3_FLASH_FALLBACK.id ? GLM_5_3_FLASH_FALLBACK : undefined); case "ollama": return undefined; default: return undefined; } diff --git a/packages/workshop-shared/src/api.ts b/packages/workshop-shared/src/api.ts index 3dfe0bad5..bae5020eb 100644 --- a/packages/workshop-shared/src/api.ts +++ b/packages/workshop-shared/src/api.ts @@ -1192,8 +1192,9 @@ export const SUGGESTED_MODELS: Record< name: "Kimi K2.7 Code (Workers AI)", contextWindow: 262144, outputLimit: WORKERS_AI_OUTPUT_LIMIT, }, - "@cf/zai-org/glm-5.2": { - name: "GLM 5.2 (Workers AI)", contextWindow: 262144, outputLimit: WORKERS_AI_OUTPUT_LIMIT, + "@cf/zai-org/glm-5.3-flash": { + name: "GLM 5.3 Flash (Workers AI)", contextWindow: 1048576, + outputLimit: WORKERS_AI_OUTPUT_LIMIT, }, "@cf/deepseek-ai/deepseek-v4-pro-0813": { name: "DeepSeek V4 Pro 0813 (Workers AI)", contextWindow: 1048576,