ZAI and Kimi provider endpoint routing fixes
NousResearch/hermes-agent · cluster 966 · agent
Data as of
12 open items. Fix merged in #9907. Check it covers your case.
The short answer
- Known?
- Yes. 31 related items grouped here, 8 issues already closed.
- Fix event
- A fix was merged to main in PR #9907. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PR #9907. That is separate from the fix event. - Still open
- 4 issues and 8 PRs.
Next step: read #9907, then check whether your report is one of the 4 still open.
Read #9907Pick up a Lab taskThese issues and PRs address incorrect endpoint selection, ignored base URL configuration, and wrong billing paths for the ZAI/GLM and Kimi/Kimi-Coding providers across authentication, credential pools, and vision auxiliary clients. A recurring theme is hardcoded or incorrectly ordered endpoint probing causing users to be charged against metered quotas instead of subscription/coding-plan quotas.
Open issues4
- Issue#5908kimi-coding credential pool base_url not re-resolved from key prefix on load
- Issue#18302[Bug]: ZAI/GLM provider base_url causes 429/404 errors — config ignored by 5 code paths
- Issue#42536[bug] Z.AI/GLM provider endpoint probe order causes Coding Plan users to be charged against wallet balance instead of subscription quota
- Issue#55112[Bug]: hardcoded zai vision base_urls (paas/v4) bypass the coding-plan endpoint → silent metered billing
Open PRs8
- PR#13993fix(providers): add moonshotai provider, disambiguate from kimi-for-coding
- PR#18694fix(auth): re-resolve Kimi pool base URLs
- PR#37816Respect configured ZAI base URL
- PR#42547fix(zai): probe Coding Plan endpoints before generic to prevent silent wallet drain
- PR#55116fix(auxiliary): prepend zai coding-plan vision endpoint before metered paas/v4 (fixes #55112)
- PR#55156fix(auxiliary): try zai coding-plan vision endpoint before metered fallbacks (#55112)
- PR#83537fix(auth): re-resolve stale kimi pool base_url on load (#5908)
- PR#114111fix(auth): route Kimi Code credentials by key
Fixes on record
-
#9907 feat(zai): add GLM-5V-Turbo support for coding plan
files:
agent/auxiliary_client.py,hermes_cli/auth.py,hermes_cli/models.pyShow the diff
-
agent/auxiliary_client.py@@ -112,6 +112,7 @@ def _normalize_aux_provider(provider: Optional[str]) -> str: # "exotic provider" branch checks this before falling back to the main model. _PROVIDER_VISION_MODELS: Dict[str, str] = { "xiaomi": "mimo-v2-omni", + "zai": "glm-5v-turbo", } # OpenRouter app attribution headers -
hermes_cli/auth.py@@ -383,13 +383,16 @@ def _resolve_api_key_provider_secret( # Z.AI has separate billing for general vs coding plans, and global vs China # endpoints. A key that works on one may return "Insufficient balance" on # another. We probe at setup time and store the working endpoint. +# Each entry lists candidate models to try in order — newer coding plan accounts +# may only have access to recent models (glm-5.1, glm-5v-turbo) while older +# ones still use glm-4.7. ZAI_ENDPOINTS = [ - # (id, base_url, default_model, label) - ("global", "https://api.z.ai/api/paas/v4", "glm-5", "Global"), - ("cn", "https://open.bigmodel.cn/api/paas/v4", "glm-5", "China"), - ("coding-global", "https://api.z.ai/api/coding/paas/v4", "glm-4.7", "Global (Coding Plan)"), - ("coding-cn", "https://open.bigmodel.cn/api/coding/paas/v4", "glm-4.7", "China (Coding Plan)"), + # (id, base_url, probe_models, label) + ("global", "https://api.z.ai/api/paas/v4", ["glm-5"], "Global"), + ("cn", "https://open.bigmodel.cn/api/paas/v4", ["glm-5"], "China"), + ("coding-global", "https://api.z.ai/api/coding/paas/v4", ["glm-5.1", "glm-5v-turbo", "glm-4.7"], "Global (Coding Plan)"), + ("coding-cn", "https://open.bigmodel.cn/api/coding/paas/v4", ["glm-5.1", "glm-5v-turbo", "glm-4.7"], "China (Coding Plan)"), ] @@ -397,35 +400,37 @@ def detect_zai_endpoint(api_key: str, timeout: float = 8.0) -> Optional[Dict[str """Probe z.ai endpoints to find one that accepts this API key. Returns {"id": ..., "base_url": ..., "model": ..., "label": ...} for the - first working endpoint, or None if all fail. + first working endpoint, or None if all fail. For endpoints with multiple + candidate models, tries each in order and returns the first that succeeds. """ - for ep_id, base_url, model, label in ZAI_ENDPOINTS: - try: - resp = httpx.post( - f"{base_url}/chat/completions", - headers={ - "Authorization": f"Bearer {api_key}", - "Content-Type": "application/json", - }, - json={ - "model": model, - "stream": False, - "max_tokens": 1, - "messages": [{"role": "user", "content": "ping"}], - }, - timeout=timeout, - ) - if resp.status_code == 200: - logger.debug("Z.AI endpoint probe: %s (%s) OK", ep_id, base_url) - return { - "id": ep_id, - "base_url": base_url, - "model": model, - "label": label, - } - logger.debug("Z.AI endpoint probe: %s returned %s", ep_id, resp.status_code) - except Exception as exc: - logger.debug("Z.AI endpoint probe: %s failed: %s", ep_id, exc) + for ep_id, base_url, probe_models, label in ZAI_ENDPOINTS: + for model in probe_models: + try: + resp = httpx.post( + f"{base_url}/chat/completions", + headers={ + "Authorization": f"Bearer {api_key}", + "Content-Type": "application/json", + }, + json={ + "model": model, + "stream": False, + "max_tokens": 1, + "messages": [{"role": "user", "content": "ping"}], + }, + timeout=timeout, + ) + if resp.status_code == 200: + logger.debug("Z.AI endpoint probe: %s (%s) model=%s OK", ep_id, base_url, model) + return { + "id": ep_id, + "base_url": base_url, + "model": model, + "label": label, + } + logger.debug("Z.AI endpoint probe: %s model=%s returned %s", ep_id, model, resp.status_code) + except Exception as exc: + logger.debug("Z.AI endpoint probe: %s model=%s failed: %s", ep_id, model, exc) return None -
hermes_cli/models.py@@ -44,6 +44,7 @@ ("minimax/minimax-m2.7", ""), ("minimax/minimax-m2.5", ""), ("z-ai/glm-5.1", ""), + ("z-ai/glm-5v-turbo", ""), ("z-ai/glm-5-turbo", ""), ("moonshotai/kimi-k2.5", ""), ("x-ai/grok-4.20", ""), @@ -89,6 +90,7 @@ def _codex_curated_models() -> list[str]: "minimax/minimax-m2.7", "minimax/minimax-m2.5", "z-ai/glm-5.1", + "z-ai/glm-5v-turbo", "z-ai/glm-5-turbo", "moonshotai/kimi-k2.5", "x-ai/grok-4.20-beta", @@ -134,6 +136,7 @@ def _codex_curated_models() -> list[str]: "zai": [ "glm-5.1", "glm-5", + "glm-5v-turbo", "glm-5-turbo", "glm-4.7", "glm-4.5",
-
10 PRs closed without merging
From the close comments: superseded by another PR 4 · done elsewhere 2 · merged via another change 1 · other 3
- #967 feat(providers): add Kimi Coding endpoint with auto-detection · merged via another change
-
#5566 fix(credential_pool): use _resolve_kimi_base_url when seeding kimi-coding pool · other →
#5669 - #5669 fix(auth): kimi-coding pool base_url seeding + PKCE endpoint fallback · other
- #13954 fix(setup): clarify Moonshot/Kimi provider labels and accept MOONSHOT_API_KEY (#13935) · other
-
#42678 fix(auth): reorder Z.AI endpoint probe to try coding plan first (#42536) · superseded by another PR →
#42547,#42536
Show 5 more
-
#43629 fix(provider): use api.kimi.com/coding endpoint for kimi-coding provider · done elsewhere →
#43617 -
#43813 fix(provider): update kimi-coding endpoint and User-Agent (#43617) · superseded by another PR →
#43629,#43617 -
#48509 fix(auxiliary_client): resolve API keys for inferred custom endpoints · done elsewhere →
a8841e2 -
#58088 fix(zai): honor configured base url · superseded by another PR →
23d3eda - #61575 fix(agent): route Z.AI manual-pool entries through _resolve_zai_base_url · superseded by another PR
Closed issues · 8
- Closed#966[Feature]: Add Kimi Coding as a direct inference provider
- Closed#5561kimi-coding credential pool seeds wrong base_url for sk-kimi- keys, causing 401 on first request
- Closed#9888[Feature]: Glm-5v-turbo for GLM Coding Plan
- Closed#13935[Bug/UX]: kimi-coding provider misleading — points to kimi.com/coding not platform.moonshot.ai
- Closed#43617[Bug]: kimi-coding provider uses wrong endpoint + User-Agent for sk-kimi-* keys, breaking all API calls including vision
- Closed#58071[Bug] zai provider ignores config.yaml base_url and always probes endpoints in hardcoded order — standard endpoint always wins over coding endpoint
- Closed#61563zai manual-pool credentials always routed to metered /api/paas/v4 instead of /api/coding/paas/v4 (hermes auth add cannot override base_url)
- Closed#68239hermes auth add stamps registry-default base_url for kimi-coding — sk-kimi- keys paired with api.moonshot.ai/v1, instant 401
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.05: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the LabAt a glance
- Subsystem
- agent
- Merged PRs
- #9907
- Closed issues
- 8
- Attempts
- 10 PRs closed without merging
- Fix link checked
- 14 Apr 2026. This confirmation is old and may be out of date (a revert or reopen would not have invalidated it here); re-verify.