Skip to content

feat: bump GLM models - #1269

Merged
ital0 merged 11 commits into
mainfrom
italomenezes/thu-860-bump-tinfoil-glm-default-to-53-and-replace-deepseek-v4-flash
Sep 10, 2026
Merged

ital0 merged 11 commits into
mainfrom
italomenezes/thu-860-bump-tinfoil-glm-default-to-53-and-replace-deepseek-v4-flash

Conversation

@ital0

@ital0 ital0 commented Sep 6, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Tinfoil removed glm-5-2 from its catalog (the enclave still answers, on borrowed time). This PR moves both confidential defaults to the GLM 5.3 family on the same row ids, so threads, profiles and selections keep working and the change ships OTA through /config:

Row id Before After
019e7580-… GLM 5.2 · glm-5-2 GLM 5.3 · glm-5-3 · reasoningEffort: 'max'
01a06dd7-… DeepSeek V4 Flash · deepseek-v4-flash · vendor deepseek GLM 5.3 Flash · glm-5-3-flash · vendor zhipu · reasoningEffort: 'low' · image input

defaultModelsVersion 5 → 6. GLM 5.3 Flash becomes the default for new accounts, /config and the CLI (getSelectedModelQuery now prefers defaultModelId before the alphabetical fallback). Effort levels follow the decision recorded on the ticket (max / low).

What else had to change

  • Image support per slug. Both models are zhipu, so the vendor set could not express "Flash yes, GLM 5.3 no". modelSupportsImages checks the vendor set or an explicit slug set; five call sites switch to it. Composer behaviour for non-image models is unchanged (THU-844).
  • Pi 0.80.7 has no GLM 5.3. glm-5-3 / glm-5-3-flash alias onto Pi's glm-5.2 catalog entry, with the thinking map overridden so low stays low (Pi's glm-5.2 map sends it as high). The adapter now accepts the max thinking level. The glm-5-2 alias stays for rows not yet migrated. Removing the bridge is tracked in THU-867 (Pi 0.85.x migration; installable with the 7-day quarantine intact from 2026-09-12).
  • User-edited rows migrate too. upgrade-opus-default.ts became a lineage table (upgrade-model-defaults.ts): Opus (sonnet-4.5, opus-4.8), GLM (glm-5-1, glm-5-2), Flash (deepseek-v4-flash). A user-chosen name is preserved.
  • Backend keeps accepting the legacy slugs. glm-5-2 and deepseek-v4-flash join the same map that backs the proxy header check, the no-header fallback and receipt verification, so clients whose rows have not been renamed yet (edited rows, old builds, receipts issued before the deploy) keep working. The no-header fallback now imports the current default GLM slug instead of a hand-written string.
  • Quota prices are inherited on purpose. Migration 0029 seeds ('tinfoil','glm-5-3',1500,5250) and ('tinfoil','glm-5-3-flash',300,700) — the glm-5-2 and deepseek-v4-flash prices, not Tinfoil's list prices (1800/5750, 400/1250) — so the per-token quota weight does not change. Old rows stay. cost_nano_usd therefore stops being the invoice for these two slugs.

Compatibility notes

  • Builds 0.1.128 / 0.1.129 that do not update will see GLM and Flash fail locally with Managed model "glm-5-3(-flash)" has no Pi compatibility metadata after the OTA rename (no request leaves the device); Opus keeps working. Builds 0.1.124–0.1.127 use the old AI SDK path and keep working, at the enclave's default effort.
  • Rows still carrying glm-5-2 / deepseek-v4-flash keep working as long as Tinfoil serves those slugs.

Operations (before merge/deploy)

  1. Run migration 0029 in production before deploying the backend. Without the price rows the two new models answer 503 INFERENCE_PRICE_UNAVAILABLE.
  2. In the first week, compare completion_tokens per message for glm-5-3 vs glm-5-2 in inference_usage; if max inflates responses, lower the quota price of glm-5-3 with a one-line migration.

- GLM 5.3 Flash accepts images and GLM 5.3 does not, yet both carry
  vendor zhipu, so a vendor-level set cannot express the difference
- modelSupportsImages replaces vendorSupportsImages and checks the
  vendor set or an explicit image-capable slug set
- the five supportsImages call sites (Pi adapter, CLI direct and
  Tinfoil bindings) switch to it
- GLM 5.3 ships with reasoningEffort 'max'; piThinkingLevels stopped at
  xhigh, so a 'max' profile silently fell back to medium
- the test pins that 'max' now derives 'max'
- pi-ai 0.80.7 has no glm-5.3, so glm-5-3 and glm-5-3-flash resolve
  compatibility through the glm-5.2 entry, which already carries the
  right thinkingFormat (zai), zaiToolStream and supportsReasoningEffort
- the thinking map is overridden for those two slugs: Pi's glm-5.2 map
  sends low as 'high', so low stays 'low', medium/high map to 'high',
  and max maps to 'max'
- the glm-5-2 alias stays for rows not yet migrated
- tests assert the outgoing reasoning_effort for both new slugs
- swap the aliases for the real catalog ids once Pi is upgraded (THU-867)
- Tinfoil removed glm-5-2 from its catalog, so GLM 5.2 becomes GLM 5.3
  (glm-5-3) and DeepSeek V4 Flash becomes GLM 5.3 Flash (glm-5-3-flash,
  vendor zhipu) on the same row ids; defaults version 6 drives the OTA
- GLM 5.3 Flash is the new defaultModelId for new accounts, /config,
  and the CLI
- Profiles ship reasoningEffort max (GLM 5.3) and low (Flash); no
  profile data migrates because modelId is unchanged
- Eval slug names and compile-only symbol references follow the rename
- reconciliation never touches a row whose hash diverged, so users who
  edited GLM 5.2 or DeepSeek V4 Flash stayed on a dead slug; the Opus
  repair from THU-843 only covered its own row
- the Opus migration becomes a table of lineages — Opus (sonnet-4.5,
  opus-4.8), GLM (glm-5-1, glm-5-2), Flash (deepseek-v4-flash) — iterated
  by the same normalize/upgrade logic, preserving a user-chosen name
- reconcile-defaults calls the generic version
- the app only stores selected_model when the user picks one, so a new
  account fell back to the system models ordered by name — after the
  rename that would be GLM 5.3 at max effort
- getSelectedModelQuery now orders the defaultModelId row first, so new
  accounts land on GLM 5.3 Flash while an explicit selection still wins
- The proxy header check, the no-header fallback and receipt
  verification all resolve slugs from defaultModels, so renaming the
  defaults would 400 every client whose row is not renamed yet: edited
  rows, old builds, and receipts issued up to two hours before the deploy.
- The two retired slugs join the same map as legacy identities; their
  old price rows stay in place.
- The no-header fallback imports the current default GLM slug from
  shared instead of a hand-written 'glm-5-2'.
- inference_prices is keyed on the exact (provider, model) with no
  fallback, so a slug without a row answers 503
  INFERENCE_PRICE_UNAVAILABLE the moment the new defaults go live.
- Migration 0029 seeds glm-5-3 at 1500/5250 and glm-5-3-flash at
  300/700. These are the quota prices of glm-5-2 and deepseek-v4-flash
  on purpose, not Tinfoil's list prices (1800/5750, 400/1250), so the
  per-token quota weight stays the same across the rename. The old rows
  stay in place for the legacy slugs.
- The journal entry (idx 29) is included: Drizzle only discovers
  migrations through the journal.
- Run this migration in production before deploying the backend.
@ital0 ital0 self-assigned this Sep 6, 2026
@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

Semgrep Security Scan

No security issues found.

@ital0
ital0 marked this pull request as ready for review September 6, 2026 18:31
@github-actions

github-actions Bot commented Sep 6, 2026 •

Copy link
Copy Markdown

Preview environment destroyed 🧹

Stack preview-pr-1269 and its Cloudflare subdomain have been cleaned up.

@github-actions

github-actions Bot commented Sep 6, 2026 •

Copy link
Copy Markdown

PR Metrics

Metric Value
Lines changed (prod code) +162 / -138
JS bundle size (gzipped) 🟢 640.2 KB → 640.2 KB (+35 B, +0.0%)
Test coverage 🟢 81.68% → 81.68% (+0.0%)
Performance (preview) Preview not ready — Render deploy may have timed out
Accessibility —
Best Practices —
SEO —

Updated Mon, 07 Sep 2026 16:04:15 GMT · run #2971

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔭 thunder-deep-review (advisory)

Reviewed the diff — no issues to report. ✅ Never approves, never requests changes, never gates merge.
head: bff3f9920a31 · mode: deep · deferred 0 item(s) already reported by other bots (best-effort dedup)

- The lineage migration reused a row's id but only moved model+name,
  leaving vendor/description stale. The Flash lineage changes vendor
  deepseek→zhipu, so an edited DeepSeek Flash row kept vendor 'deepseek'
  after becoming glm-5-3-flash, and resolveConfidentialModelCompatibility
  then looked up deepseek/glm-5.2 (undefined) and threw
  compatibility-missing on every send.
- Reconcile already carries these server-owned metadata fields for intact
  rows, but edited rows only pass through the migration, so
  normalizeModelDefault/upgradeModelDefaults now also migrate vendor and
  description to the target.
- The lineage tests now seed the legacy vendor (deepseek) and an old
  description so the regression is covered.
- Found by thunder-deep-review; GLM and Opus lineages were unaffected
  (no vendor change).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔭 thunder-deep-review (advisory)

Complements the other bots — surfaces only what they did not flag. Never approves, never requests changes, never gates merge.
head: f952e6becbc4 · mode: deep · deferred 0 item(s) already reported by other bots (best-effort dedup)

Comment thread shared/defaults/models.ts
- the JSDoc above defaultModelGlm53Flash still said confidential Flash
  "ships under a fresh id"; that was true when #1264 minted 01a06dd7
  instead of reusing the retired direct Flash row, but GLM 5.3 Flash now
  reuses that same id in place, so the sentence read as if this PR
  created a new id
- the frozen provider/isConfidential rationale already lives in the
  reconciliation code, so remove the comment rather than reword it
@ital0 ital0 changed the title feat(THU-860): move confidential defaults to GLM 5.3 and GLM 5.3 Flash feat: bump GLM models Sep 7, 2026
@ital0
ital0 merged commit 8f7f546 into main Sep 10, 2026
36 checks passed
@ital0
ital0 deleted the italomenezes/thu-860-bump-tinfoil-glm-default-to-53-and-replace-deepseek-v4-flash branch September 10, 2026 13:57

This branch was successfully deployed

1 active deployment
preview — 7854d726 Deployed Sep 7, 2026 by ital0 via deploy / deploy #2861
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant