fix(loop): auto-retry acp-loop replay on transient upstream rejections (#189) - #190
Open
ranxianglei wants to merge 2 commits into
Open
fix(loop): auto-retry acp-loop replay on transient upstream rejections (#189)#190ranxianglei wants to merge 2 commits into
ranxianglei wants to merge 2 commits into
Conversation
#189) After a compress, provider risk-control may briefly reject the replay request (GLM Coding Plan: 400 {"code":3007,"msg":"captcha verify failed"} ~1s after the context rewrite), and the error was passed straight into the agent session. The replay request now retries transient upstream failures with exponential backoff (3 attempts total, 1500ms base, BILI_REPLAY_RETRY_BASE_MS override) on both the streaming loop and the Responses-API JSON loop. Transient = 429/5xx or 4xx bodies matching risk-control markers; plain 4xx still fail fast. Each retry logs a clear "likely provider risk-control — retrying" line; exhausted failures are surfaced with an "after N attempt(s)" suffix.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
GitHub #189: on GLM Coding Plan (zcode.z.ai), acp-loop replay requests get upstream
400 {"code":3007,"msg":"captcha verify failed"}within ~300ms. Old code passed the error straight into the agent session as[acp-proxy: compress loop upstream error 400: ...].What the log actually proves (fact vs hypothesis)
Facts from the reporter's log (5 events in one day):
re-requesting so the model sees the result— <1s after the previous response completed, no human delay.Candidate triggers (UNCONFIRMED — needs a controlled experiment):
3007is NOT in z.ai's public error-code reference (docs.z.ai/api-reference/api-code documents 1xxx–2xxx business codes; no 3xxx) — it's an internal ZCode-plan gateway code, so no authoritative public definition exists.Fix
Bounded retry with exponential backoff on the REPLAY request only (both the streaming loop
src/loop/core.tsand the Responses-API JSON loopsrc/compress-loop-responses.ts):BILI_REPLAY_RETRY_MAX; set1to restore the legacy fail-fast behavior exactly), backoff base 1500ms doubling per attempt (BILI_REPLAY_RETRY_BASE_MS;0= no delay).captcha,verify failed,risk control,风控,rate limit,too many requests,try again). Plain 4xx fails fast. Network-level failures are NOT retried (avoids stacking the 10-min timeout).upstream rejected replay (HTTP 400 ...); likely provider risk-control — retrying in 1500ms (attempt 1/3); final failure message carriesafter N attempt(s).Worst case if the hypotheses are wrong: the same error surfaces ≤4.5s later. Replay calls are idempotent LLM requests; no state mutation.
BILI_REPLAY_RETRY_MAX=1restores old behavior exactly.NOT doing (yet): smoothing the post-compress transition (split big compress / overlap tail) — larger semantic change; revisit if failures persist despite retries.
Path to hard evidence (controlled experiment, needs a GLM Coding Plan account)
Pure curl against
zcode.z.ai/api/v1/zcode-plan/anthropic/v1/messages, no bili involved:ACP_DUMP_REQ=1+ debug → the failing replay body is dumped to~/.local/state/billion-context/dumps/req-*-REREQUEST.json; resend that file standalone via curl after 30s → 3007 again ⇒ body content is the trigger (tests C).Tests / pre-flight
8 new regression tests (retry-then-success, persistent-captcha exhaustion, fatal-400 fail-fast, 429 retry, classifier matrix, backoff math, max-attempts env, MAX=1 legacy mode) + S3 "upstream 500 mid-loop" test updated for the new behavior. typecheck ✓ · 520/520 tests ✓ · build ✓. CHANGELOG + CONFIGURATION.md updated.