Skip to content

feat: add GLM-5.3 Flash to Z.AI model list - #7323

Merged
nesquena-hermes merged 3 commits into
nesquena:masterfrom
rh-id:feat/add-glm-5-3-flash
Sep 10, 2026
Merged

nesquena-hermes merged 3 commits into
nesquena:masterfrom
rh-id:feat/add-glm-5-3-flash

Conversation

@rh-id

@rh-id rh-id commented Aug 27, 2026 •

Copy link
Copy Markdown
Contributor

Thinking Path

  • Hermes WebUI aims for near 1:1 parity with Hermes CLI providers in the browser, and the model dropdown is driven by the curated per-provider catalogs in api/config.py (_PROVIDER_MODELS + _FALLBACK_MODELS)
  • Z.AI already ships a curated glm-5.3 entry (feat: add GLM-5.3 to Z.AI model list #7017) plus the older glm-4.5 / glm-4.5-flash sibling pair
  • Z.ai now lists GLM-5.3 Flash as its own selectable model (docs.z.ai/guides/llm/glm-5.3-flash); without a catalog entry, users only see it through unlabeled live-discovery merge or custom-provider setup
  • So the right shape is the minimal class fix: add glm-5.3-flash as a first-class sibling everywhere the base id is curated, reusing the existing base→flash ordering convention instead of adding new mechanisms

What Changed

  • api/config.py (+2):
    • _PROVIDER_MODELS["zai"]: {"id": "glm-5.3-flash", "label": "GLM-5.3 Flash"} immediately after glm-5.3 (mirrors the glm-4.5 → glm-4.5-flash adjacency)
    • _FALLBACK_MODELS Z.AI block: {"provider": "Z.AI", "id": "zai/glm-5.3-flash", "label": "GLM-5.3 Flash"} directly after zai/glm-5.3 (newest-first order preserved; shared by the OpenRouter fallback list reuse)
  • tests/test_glm_5_3_flash_catalog.py (new, modeled on test_glm_5_3_catalog.py): asserts catalog presence + exact label, base-then-flash sibling adjacency (glm-5.3-flash directly after glm-5.3, glm-5.2 next) with glm-5.1 after the 5.3 generation, fallback entry uniqueness + position, _zai_glm_classification("glm-5.3-flash", "zai") == "effort" with the public resolve_model_reasoning_efforts ladder, and end-to-end propagation through get_available_models()
  • Explicitly out of scope: no JS changes (dropdown/onboarding/OpenRouter paths derive from these dicts), no change to _zai_glm_classification (the ≥5.2 version gate already covers any glm-5.3* id), onboarding default stays glm-5.1 per feat: add GLM-5.3 to Z.AI model list #7017's deliberate decision, no CHANGELOG edit

Why It Matters

Users on a Z.ai/GLM plan currently have no labeled picker entry for GLM-5.3 Flash even though Z.ai documents it as a live model. Adding it to the two canonical catalogs makes it appear correctly labeled and capability-configured across the model picker, fallback list, onboarding wizard model list (which auto-derives from _PROVIDER_MODELS), and live-model merging — without touching any consumer code.

Verification

  • Proof the test bites: ran the new suite against the code WITHOUT the config edit (stash cycle) → 5 failed, 1 passed; the passing test is an intentional semantic guard pinning that the existing ≥5.2 classification gate already yields "effort" for the flash id. With the fix applied → all 6 pass.
  • Affected + neighboring runs (repo runner, Python 3.12 .venv, isolated test state): tests/test_glm_5_3_flash_catalog.py, tests/test_glm_5_3_catalog.py, tests/test_zai_reasoning_effort_gating.py, tests/test_custom_providers_in_panel.py, tests/test_model_resolver.py, tests/test_4413_seed_provider_models.py → 197 passed, 0 failed
  • Sibling sweep: grepped api/, static/, tests/, docs/, mcp_server.py for glm-5.3 and glm-4.5-flash. Every literal site outside config.py is test input, not catalog enumeration; consumers that auto-derive were verified, not assumed: onboarding wizard builds list(_PROVIDER_MODELS.get("zai", [])), ui.js dropdown reads /api/models + live merge with no static zai map, routes.py live-catalog prettifier restores the GLM acronym generically, i18n locales carry no model-name strings.
  • Who owns the truth: the model's id naming and reasoning_effort support are owned by Z.ai's docs — confirmed at https://docs.z.ai/guides/llm/glm-5.3-flash (model exists; reasoning_effort accepted, max recommended). That is external confirmation; I did not call the API myself.
  • What I could not verify:
    • No live browser screenshots captured (work happened in an agent workspace without exercising a rendered browser session). Verification is at the /api/models payload level — get_available_models() includes glm-5.3-flash under the zai group, which is what feeds the dropdown — happy to attach a picker screenshot if reviewers want one.
    • Whether all effort-ladder levels (not just the documented max) behave identically on the flash variant — same assumption class already carried by master's glm-5.2/glm-5.3 entries; flagged for maintainers
    • The installed hermes-agent core copy of _PROVIDER_MODELS["zai"] may lag; WebUI's static entry stands alone and _seed_provider_models_from_core only injects missing ids at startup, so no conflict either way

Risks / Follow-ups

  • If Z.ai later scopes the flash endpoint away from part of the effort ladder, a glm-*-flash carve-out in _zai_glm_classification would be needed; the new semantic guard test would catch the drift point
  • Unshipped follow-up noted in feat: add GLM-5.3 to Z.AI model list #7017 (bump onboarding default once api.z.ai serves glm-5.3 broadly) is intentionally untouched here — that default should probably move straight past glm-5.3 once it lands; keeping this PR single-purpose

Contract Routing

Task type: small provider-catalog addition (one logical change)
Touched areas: api/config.py curated zai catalogs; new product-semantics regression suite
Relevant public docs: AGENTS.md, CONTRIBUTING.md, docs/CONTRACTS.md, docs/GUIDELINES.md; README provider feature bullet unchanged (Z.AI already listed). No contract document is redefined; the new tests extend the existing reasoning-effort gating semantics test family rather than asserting opposite behavior.
Scope boundaries: backend data + tests only; no streaming/state layer touched; no UI framework changes.
Evidence needed & shown: fail-before/pass-after proof, neighbor green runs, sibling sweep, payload-level propagation.

Release note

Added the Z.ai GLM-5.3 Flash model (glm-5.3-flash) to the model picker and fallback lists, with proper labeling and reasoning-effort support inherited from the GLM ≥5.2 capability gate.

Model Used

ZCode coding agent powered by Z.ai GLM-5.3-Flash (builtin zai-coding-plan endpoint). Notable tool use: delegated @coder subagent implemented the catalog change + tests after read-only exploration agents mapped the catalogs; delegated @Reviewer subagent performed independent verification including a stash-based fail-before proof; WebFetch used to confirm the Z.ai docs page for glm-5.3-flash. All pytest runs executed locally via the repo runner in an isolated test environment.

Add glm-5.3-flash next to glm-5.3 in _PROVIDER_MODELS["zai"] and mirror
it in _FALLBACK_MODELS, following the existing glm-4.5 / glm-4.5-flash
sibling pattern. Reasoning-effort gating needs no change: the >= 5.2
version gate already classifies the id at the full effort tier.

Adds a regression suite asserting catalog presence, label, ordering,
fallback entry, and end-to-end propagation through
get_available_models().
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Summary

Reading the complete two-file diff at 57693c338, the full changed files at HEAD and on origin/master, the neighboring GLM-5.3 regression, and the native Z.AI capability classifier, this is the right data-layer change. The new model is added to both standalone WebUI catalog paths, and the existing GLM version parser already classifies the 5.3-flash suffix at the same effort tier as the base 5.3 model. I found no product-code blocker.

Code reference

The two catalog insertions are consistent at api/config.py:1151-1157 and api/config.py:1738-1744:

{"provider": "Z.AI", "id": "zai/glm-5.3", "label": "GLM-5.3"},
{"provider": "Z.AI", "id": "zai/glm-5.3-flash", "label": "GLM-5.3 Flash"},
{"provider": "Z.AI", "id": "zai/glm-5.2", "label": "GLM-5.2"},

The capability path at api/config.py:3585-3628 extracts the numeric GLM version before applying the 5.2-or-newer effort rule. Consequently, glm-5.3-flash reaches the effort branch without a flash-specific special case. That behavior is exercised at tests/test_glm_5_3_flash_catalog.py:128-142, while the payload test at tests/test_glm_5_3_flash_catalog.py:145-207 deliberately disables the installed-core catalog and proves that the WebUI-owned fallback reaches get_available_models().

Diagnosis / recommendation

The implementation is appropriately minimal. Adding consumer-side JavaScript or another reasoning exception would duplicate authority that already exists in api/config.py. The cache-isolation fixture also mirrors tests/test_glm_5_3_catalog.py:19-61, including restoration of the mutable config globals, so the payload test should not leak its temporary provider state into neighboring files.

One non-blocking test tightening would improve the ordering claim. tests/test_glm_5_3_flash_catalog.py:75-102 currently proves only 5.3 < 5.3-flash < 5.1; it does not prove that the provider catalog keeps the base and flash rows adjacent, even though the fallback test at :123-125 does. Assert flash_index == base_index + 1 there as well, and optionally assert that 5.2 follows flash. That would make both catalogs pin the same sibling-order contract.

Verification

The exact-head test, lint, browser-smoke, and conversation-lifecycle checks are green in the PR metadata. No contributor-authored code was executed during this read-only review.

@nesquena-hermes nesquena-hermes added size:M Medium PR (≤10 files, ≤250 LOC) ux User experience / visual polish labels Aug 27, 2026
Per PR review feedback (nesquena#7323): the provider-catalog ordering test now
asserts glm-5.3-flash immediately after glm-5.3 and glm-5.2 immediately
after the flash sibling, matching the adjacency the fallback test
already pins. The base<flash relative check is subsumed; flash<glm-5.1
is kept to pin 5.1 after the whole 5.3 generation.
@rh-id

rh-id commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the careful read — addressed in 25d1afb.

test_glm_5_3_flash_ordered_base_then_flash_then_glm_5_1 now asserts glm-5.3-flash == glm-5.3 + 1 and glm-5.2 == glm-5.3-flash + 1 in the provider catalog, so both catalogs pin the base-then-flash sibling adjacency (the fallback test already pinned its side). The old base < flash relative check is subsumed by adjacency; flash < glm-5.1 is kept to pin 5.1 after the whole 5.3 generation.

Teeth-proof: with the provider catalog mutated in memory to [glm-5.3, glm-5.2, glm-5.3-flash, ...] — an ordering where the old relative assertions still passed — the new adjacency assertion fires. Focused re-run: 95 passed (flash suite 6, glm-5.3 suite 8, zai reasoning-effort gating suite 81).

@rh-id

rh-id commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

@nesquena-hermes

@nesquena-hermes nesquena-hermes left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Release gate: SAFE TO SHIP (as-is) — catalog add for the direct Z.AI provider

Re-gated at head 25d1afbcca47 (rebased clean; three-dot diff is api/config.py +2 catalog rows + the new cache-isolated test).

  • Codex + Fable (both): SHIP. The two catalog rows mirror the existing base-then-flash convention and are correct for the direct Z.AI provider path (the picker reads the static zai catalog as the last fallback; onboarding reads it directly). The >=5.2 reasoning-effort version-gate classifies zai/glm-5.3-flash identically to zai/glm-5.3 — verified by running the classifier directly; the -flash suffix cannot break version parsing (major/minor are captured before the suffix). The new test fixture is byte-identical to the existing GLM-5.3 fixture and empirically does not poison neighboring test files.
  • Full suite: 15,222 passed. The only 2 non-passes are the known box/env baseline artifacts (test_cron_delivery_options, test_model_resolver) that fail identically on clean origin/master — this diff touches neither.
  • GLM-5.3 Flash is confirmed real (Z.ai native multimodal model, released Aug 26 2026).

On the OpenRouter namespace: the gate confirmed that _FALLBACK_MODELS is reused by OpenRouter onboarding where the canonical slug is z-ai/… (so zai/glm-5.3-flash 404s on OpenRouter). This is a pre-existing whole-class issue — every shipped Z.AI fallback row (glm-5.3, glm-5.2, glm-5.1, …) has the same zai/ prefix, and zai/ is correct for the direct provider. #7323 follows the established convention; fixing the OpenRouter namespace belongs class-wide, tracked in #7514. Shipping this as-is is the consistent call.

Thanks @rh-id — shipping to the experimental channel.

@greptile-apps

greptile-apps Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds GLM-5.3 Flash to the curated Z.AI provider and fallback catalogs, making it available through the existing model-discovery pipeline.

  • Adds correctly labeled bare and provider-prefixed catalog entries.
  • Adds regression coverage for catalog presence, ordering, uniqueness, capability classification, and /api/models propagation.

Confidence Score: 5/5

The PR appears safe to merge with no concrete blocking or non-blocking defects identified.

The new model follows existing Z.AI identifier, ordering, routing, and capability conventions, and the added tests exercise its propagation through the catalog payload.

Important Files Changed

Filename Overview
api/config.py Adds GLM-5.3 Flash consistently to both Z.AI catalog representations without changing routing or capability logic.
tests/test_glm_5_3_flash_catalog.py Covers the new entry’s metadata, ordering, reasoning tier, fallback uniqueness, and propagation through the production catalog builder.

Reviews (1): Last reviewed commit: "Merge branch 'master' into feat/add-glm-..." | Re-trigger Greptile

@nesquena-hermes
nesquena-hermes merged commit 40a6a76 into nesquena:master Sep 10, 2026
23 checks passed
nesquena-hermes added a commit that referenced this pull request Sep 10, 2026
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Shipped in exp-v0.52.294 🚢 — thanks @rh-id. GLM-5.3 Flash is now selectable in the Z.AI list, with the same effort-ladder treatment as GLM-5.3 (Codex + Fable both verified the version-gate classifies it identically, and confirmed the entry is correct for the direct Z.AI provider path). Heads-up: the OpenRouter onboarding namespace mismatch that surfaced during review (zai/ vs OpenRouter's z-ai/) is a pre-existing whole-class issue affecting every Z.AI fallback entry — tracked separately in #7514, not a blocker for this PR.

itsdarklikehell pushed a commit to itsdarklikehell/hermes-webui that referenced this pull request Sep 16, 2026
* feat: add GLM-5.3 Flash to Z.AI model list

Add glm-5.3-flash next to glm-5.3 in _PROVIDER_MODELS["zai"] and mirror
it in _FALLBACK_MODELS, following the existing glm-4.5 / glm-4.5-flash
sibling pattern. Reasoning-effort gating needs no change: the >= 5.2
version gate already classifies the id at the full effort tier.

Adds a regression suite asserting catalog presence, label, ordering,
fallback entry, and end-to-end propagation through
get_available_models().

* test: pin glm-5.3-flash sibling adjacency in zai provider catalog

Per PR review feedback (nesquena#7323): the provider-catalog ordering test now
asserts glm-5.3-flash immediately after glm-5.3 and glm-5.2 immediately
after the flash sibling, matching the adjacency the fallback test
already pins. The base<flash relative check is subsumed; flash<glm-5.1
is kept to pin 5.1 after the whole 5.3 generation.

---------

Co-authored-by: nesquena-hermes <nesquena+hermes@gmail.com>
itsdarklikehell pushed a commit to itsdarklikehell/hermes-webui that referenced this pull request Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M Medium PR (≤10 files, ≤250 LOC) ux User experience / visual polish

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants