Conversation
3064946 to
827e237
Compare
|
Ran this on a 5-profile Hermes fleet — one z.ai Coding Plan key, The retry storm is the real damage, and this gate breaks it. Before the gate, each 1305'd call retried up to MoA 2.0 is what makes this urgent. Since #54016 (references fire on every user/tool response, in parallel, through the provider's real route), a single task's tool loop becomes a burst of concurrent z.ai aggregator calls. On Caveat for single-key fleets: the gate is process-local, so N gateway processes sharing one key get N independent semaphores → effective ceiling One adjacent gap, separate from this PR: the opencode-identity work (#51792) is only wired into the main OpenAI client, not And to avoid conflation in testing: distinct from 1305, the coding plan also returns a hard |
A process-local threading semaphore caps simultaneous in-flight calls to the Z.AI/GLM endpoint (which returns 429/1305 under concurrent load) so a delegate_task swarm doesn't keep it pegged; every other provider passes straight through. Z.AI-only, opt-in by host, non-fatal (a starved gate proceeds rather than hangs). Audit fixes: the seconds timeout is parsed with env_float (was env_int, so a fractional HERMES_ZAI_ACQUIRE_TIMEOUT_S=0.5 silently snapped to the 30s default); the default-cap test now asserts the module's actual default via a clean reload (was a tautology re-checking the stdlib helper) + tests for env override and fractional-timeout parsing.
827e237 to
1e1bd8e
Compare
|
Final audit revision pushed as The field report in #issuecomment-4881661503 exposed two material gaps in the earlier patch, both now fixed:
The default is now Final verification: 25 focused tests, 152 related integration tests, 44 streaming tests, and a 729-test broad regression pass all green; The adjacent client-identity item from the field report remains intentionally separate from this concurrency-focused PR. |
|
Thanks for the focused concurrency investigation and for incorporating the MoA, streaming-lifetime, interrupt-race, fleet-scaling, and operator-documentation feedback. This automated hermes-sweeper review is closing this under the standing configuration policy:
A viable follow-up would re-scope the controls to a profile-safe Closed as not-planned per standing maintainer policy ( |
|
Implemented every requested configuration-policy change in #64911.\n\nThe user-facing controls now live only in the active profile's |
Summary
Adds a strict, process-local concurrency bound for Z.AI / Zhipu model calls made by direct agents, delegated subagents, and Mixture-of-Agents (MoA). The goal is to stop a fan-out from sustaining
HTTP 429 / code 1305overload retries against the Coding Plan endpoint.The important correction in this revision is that saturation now queues instead of silently proceeding uncapped. The previous best-effort timeout path could exceed the configured ceiling exactly when the provider was already overloaded.
Why this matters
A 1305 retry storm is more than a latency problem. In the field report on this PR, overloaded Coding Plan calls carried roughly 130k tokens and could be attempted up to six times, repeatedly re-sending the same large context and consuming the rolling quota. A five-profile deployment sharing one key reported zero 1305 responses in its active observation window after setting the cap to
2, while MoA continued to run normally.MoA makes the bound especially important: reference models fan out in parallel and the acting aggregator uses its resolved provider route on every relevant iteration. If that aggregator is GLM on Z.AI, the outer virtual
moaprovider is not enough to identify or limit the real requests.What changed
BoundedSemaphorefor resolved Z.AI destinations.4to2;HERMES_ZAI_MAX_CONCURRENT=0disables it.HERMES_ZAI_ACQUIRE_TIMEOUT_Sraises locally without contacting the provider; the default0waits for a slot.codex_responsespreflight while rebasing the main call path.Non-Z.AI providers still take the direct no-op path. A bare
glm-*model name is intentionally insufficient for detection because local and third-party endpoints can serve GLM models without being Z.AI.Scope and limitations
The semaphore is process-local. If several CLI or gateway processes share one key, the effective ceiling is:
process count × HERMES_ZAI_MAX_CONCURRENTFleet operators should normally keep the per-process value at
1or2. Cross-process coordination remains separate work.This patch does not reinterpret the hard
Usage limit reached for 5 hourresponse; that is a rolling spend quota, not concurrency overload. The adjacent client-identity concern raised in the field report is also separate from concurrency and is intentionally not mixed into this focused patch.Verification
Three independent verification layers passed on the rebased final commit:
Additional checks:
ruff,py_compile, andgit diff --checkpassed.