fix(arbitration): prefer provider-anchored usage over calibrated estimate - #214
Open
ranxianglei wants to merge 1 commit into
Open
fix(arbitration): prefer provider-anchored usage over calibrated estimate#214ranxianglei wants to merge 1 commit into
ranxianglei wants to merge 1 commit into
Conversation
…mate Incident 01a02d90: nudge/emergency arbitration ran on a chars/4×density estimate of 57K (51.8% of the 131,072 effective window) while the provider was already rejecting a 134.5K prompt — the density estimator was pinned at its 2.5 ceiling and could never close a 4.5× gap, so the 75%/95% bands never fired and the session dead-looped on 400s. pi's getContextUsage().tokens anchors on the provider-reported usage of the last assistant (cacheRead included via calculateContextTokens), which was >100% of the window on the very turn the loop started. Arbitrate on max(calibrated estimate, provider anchor) whenever the anchor is trustworthy: - null tokens (pi cannot anchor, e.g. right after pi-side compaction) → keep the calibrated estimate - post-compression transient turns: the anchor assistant predates the shrink; consuming it would false-EMERGENCY right after a successful compress (omp #18 family) → keep the calibrated estimate - provider-never-reports-usage regime: pi falls back to summing the whole session tree (never shrinks; omp issue #18) → detect via the same rule pi's compaction uses (assistant entry with non-zero usage) and keep the calibrated estimate The overflow self-heal 95% floor is unchanged and still applies after arbitration.
📦 Built Extension ArtifactBranch: Option A — Install from npm PR tag (recommended)pi install npm:billion-context-pi@pr-214Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pi-pr214.tgz
pi install ./packageThis comment is automatically updated on each push. |
Owner
Author
|
Review round 1 (agent reviewer, verified against pi-stable internals — verdict: ship): Healthy path verified safe for prefix cache: the max-merge only raises Minor findings (follow-ups, not blockers):
|
This was referenced Aug 23, 2026
Merged
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.
fix(arbitration): prefer provider-anchored usage over calibrated estimate
Problem
Same incident family as #204, but the deepest layer: the arbitration number itself was fiction.
Session
01a02d90(2026-08-23) dead-looped on400 (no body)from sglang. Autopsy of the session jsonl:stream_options.include_usage, parses it, persists it). The final pre-crash turn reported{input: 169, cacheRead: 134400}= 134,569 real context tokens — already past the effective input limit (262,144 − 131,072 maxTokensreserve).tokens=57463 pct=51.8— a chars/4×density estimate of the sent view, 4.5× below reality.density=2.5on 831 turns, i.e. pinned at its ceiling — but the true ratio was ~4.5, so calibration could never catch up and every threshold (75% nudge, 95% emergency) stayed closed while the provider rejected every request.The correct number was already in the host: pi's
getContextUsage().tokensanchors on the last assistant's provider-reported usage (plus estimated trailing tokens;calculateContextTokensincludescacheRead). On the very turn the loop started it read >100%. The extension fed it only todensity.update(), never to arbitration.Fix
Arbitrate on
max(calibrated estimate, provider anchor)— newsrc/arbitration.ts:The anchor is consumed only when trustworthy (
providerAnchoredTokens, all three guards required):realUsage.tokens > 0— pi yieldsnullwhen it cannot anchor (e.g. right after a pi-side compaction with no post-compaction usage).postCompressionSkip). To enable this,noteActiveBlocks()is hoisted above arbitration (was below the self-heal block; called once per context event, unchanged semantics).getAssistantUsageuses). Without it, pi's number is a whole-tree sum that never shrinks — the permanent false-EMERGENCY regime of omp issue fix: inline typebox into dist (ACP tags/nudge silently disappeared) #18.Taking
max()means a stale-low estimate can never mask a real overflow; the anchored number already includes pi's estimated trailing tail, so it never under-counts what is about to be sent.Overflow self-heal's armed ≥95% floor still applies after arbitration (unchanged).
Files changed
src/arbitration.ts(new)providerAnchoredTokens(realUsage, entries, postCompression)+ the three-guard rationale.src/index.tsnoteActiveBlocksabove arbitration;anchoredTokensmax-merge;anchoredTokensadded to thecontext-indebug event.tests/arbitration.test.ts(new)Tests
npm run typecheck✅ ·npm run build✅ ·npm test✅ 421 pass / 0 fail:null(tree-sum regime distrusted)null; empty entries →nullnull/0/NaNtokens →null;totalTokens-only usage counts; all-zero record does notRelation to other work
2026-08-23_overflow-nobody-arm(no-body 4xx arm): that PR recovers the loop after it starts; this PR prevents it from starting — with anchored arbitration the 95% emergency fires on the first genuinely oversized turn.2026-08-23_toolresult-token-cap: hard per-message cap, usage-agnostic. Orthogonal belt-and-braces.