Repository navigation
[PR] fix: first-byte stall warn per (origin,session) with cooldown instead of once-per-origin-per-process (#5164) - #5260
Open
ranxianglei wants to merge 4 commits into
Open
ranxianglei wants to merge 4 commits into
ranxianglei wants to merge 4 commits into
Conversation
… of once-per-origin-per-process (#5164)
Contributor
📦 Built Package ArtifactBranch: Latest build — install this exact versionnpm install -g billion-context@0.0.7309-pr.5260.842ebc4This exact version is immutable and reproducible. The rolling Recent builds (commit → version)
Download artifact
tar xzf billion-context-pr5260.tgz
npm install -g packageInstall instructions are refreshed on each push. |
This was referenced Oct 30, 2026
…byte-warn-cooldown
ranxianglei
pushed a commit
that referenced
this pull request
Oct 31, 2026
Review finding: both learn sites nested the veto clear inside the learned-flag flip guard (relay demand branch / loop UpstreamHttpError else-if). A session holding BOTH evidence classes — learned ON from an earlier demand 400, later vetoed by an extra-forbidden 4xx — could never clear its veto: re-demand evidence arriving while the flag was already true did nothing, so every tool-call turn 400'd forever in the opposite direction (the mirror image of #5260's stuck loop). The veto clear is now an independent transition in src/server/relay.ts and src/loop/core.ts, with its own warn log and markDirty, so the two evidence classes keep flipping the session either way. Regression test drives the full flip through the real relay (demand → forbid → re-demand → accept) and fails on the pre-fix code.
This branch has not been deployed
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.
Related to #5164 (stopgap / option-B content). Direction + default threshold remain an owner decision in #5262 — if A lands, this PR is its diagnostic foundation (acceptance ②④); if C, reject this PR.
What changed
The first-byte watchdog (
armFirstByteWatchdog, src/server/relay.ts) deduped warns with a process-lifetime Set per origin: each origin could ever warn once, claimed at fire time. In #5139 Phase 2 that meant the first post-wedge late fire burned ccproxy's single quota and every later stalled turn of the mega-session went completely silent — zero log lines explaining why turns were held ~300s.Warns are now throttled per (origin, session) with a cooldown (
FIRST_BYTE_WARN_COOLDOWN_MS = 60_000, code constant + test seam, no new config surface):forward POSTand client disconnect #3434's anti-spam intent survives: a pathological fast stall loop on one origin+session logs at most one line per window;(pending Ns)— under a post-wedge late fire that far exceeds the nominal 30s threshold and is exactly the number triage needs (incident turns were held ~300s while the line said "≥30s").Behavior change disclosure (old → new)
First-byte stall warn cadence: once per origin per process lifetime → at most once per (origin, session) per 60s. Log volume can increase for origins with repeated stalls (bounded by the cooldown). Client-visible behavior UNCHANGED — diagnostic only: no abort, no new failure path, no config surface (the fail-fast variant stays owner-gated in #5262).
Gate tests (#3617 both directions)
_resetFirstByteWarnStateForTest).Acceptance ③ (healthy long streams crossing the threshold survive) is untouched: this change touches neither
fetchWithTimeout's idle re-arm nor any response path — covered by the existing fetch-util/relay suites.Modes reasoned
Plugin mode and proxy mode both funnel through the single forward chokepoint (the watchdog arms around the initial upstream fetch at relay.ts regardless of lane —
lane∈ main/side/passthrough); the change is lane-agnostic logging only.kernel: none · pi-subagents: none · config surface: none (constant + test seam, matching how the existing threshold is treated)