fix: redact brand string for z.ai provider to avoid content-filter 429 (#60118) - #60140
fix: redact brand string for z.ai provider to avoid content-filter 429 (#60118)#60140AlexFucuson9 wants to merge 1 commit into
Conversation
…ch#60118) z.ai (GLM Coding Plan) silently rejects system prompts containing the literal string "Hermes Agent", returning HTTP 429 with code 1305 (mislabeled content-filter rejection). Because every Hermes request injects this brand string into the system prompt, every request to z.ai fails — and the 429 is treated as a transient throttle, so it retries 3x before surfacing as "rate limiting". Add brand-string redaction in build_api_kwargs() for the z.ai provider path, replacing "Hermes Agent" → "the assistant" and "Nous Research" → "the development team" in system messages only. This follows the same pattern used by the Anthropic adapter (line 2545) which replaces "Hermes Agent" → "Claude Code" for Anthropic's content filters. Fixes NousResearch#60118
Duplicate of #59975 (earliest open, same site |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the Z.AI prompt trigger. The reported source condition is still present on current main, but this implementation does not reach the normal direct Z.AI path.
Problems
- The new
if _is_zaiblock is below the legacy no-profile branch in the PR diff.zaiis a registeredZaiProfile(plugins/model-providers/zai/__init__.py:111-127), andbuild_api_kwargs()returns from the provider-profile path before the added block (agent/chat_completion_helpers.py:998-1028). - Non-Codex iteration-limit summaries bypass
_build_api_kwargs()and sendapi_messagesdirectly (agent/chat_completion_helpers.py:1836-1847), leaving that request path uncovered. - The PR has no regression tests for the registered Z.AI path or input/cache preservation.
Suggested changes
- Sanitize a per-request message copy before provider-profile dispatch, and add the same handling to the direct summary request path.
- Add focused tests for registered
zai, system-only replacement, unchanged source messages, and non-Z.AI passthrough.
Automated hermes-sweeper review.
| # z.ai (GLM Coding Plan) silently rejects system prompts containing | ||
| # "Hermes Agent" — returns HTTP 429 code 1305 (mislabeled content | ||
| # filter). Redact brand strings in system messages so the provider | ||
| # doesn't trip its filter. See issue #60118. |
There was a problem hiding this comment.
This block is in the legacy no-profile branch. Direct zai resolves to the registered ZaiProfile, whose earlier return bypasses this code entirely; move a copy-only sanitizer before provider-profile dispatch or to the outbound request-construction boundary.
Summary
z.ai (GLM Coding Plan) silently rejects system prompts containing the literal string "Hermes Agent", returning HTTP 429 with code 1305 (mislabeled content-filter rejection). Every Hermes request injects this brand string, so every request fails with a fake "rate limit" error.
Root Cause
z.ai's content filter trips on "Hermes Agent" in the system prompt. The 429/1305 response is mislabeled — it's not a rate limit, it's a content filter. The account has quota, the key works, and removing the brand string makes requests succeed.
Changes
_is_zaiprovider detection flag inbuild_api_kwargs()Precedent
The Anthropic adapter already does the same thing (line 2545): it replaces "Hermes Agent" → "Claude Code" for Anthropic's content filters. This is the same pattern applied to z.ai.
Test Plan
Fixes #60118