Repository navigation
fix: separate confirmed overflow evidence from weak truncation guesses in window self-heal (#570) - #572
Conversation
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-572Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr572.tgz
npm install -g packageThis comment is automatically updated on each push. |
[bot] 🏷 Review complete — preflight independently verified, one defect found in review and fixed on the branch. Preflight (all three re-run by me):
Design review: provenance split, the retraction margin ( Defect found in review (fixed): retraction reads
Re-ran everything after the fix: typecheck clean, |
Semantic merge onto current master: master's #554 regex superset kept in util.ts (exceed[_\s]?context[_\s]?size); the raw-body fallback for side-passthrough payload estimates kept, now writing through the confirmed-channel naming; import union with backfillHostUsage (#591). Stale #554 test assertion updated to the confirmed channel (#572).
779a314 to
ee79b4c
Compare
Semantic merge onto current master: master's #554 regex superset kept in util.ts (exceed[_\s]?context[_\s]?size); the raw-body fallback for side-passthrough payload estimates kept, now writing through the confirmed-channel naming; import union with backfillHostUsage (#591). Stale #554 test assertion updated to the confirmed channel (#572).
ee79b4c to
35d2809
Compare
|
已在 35d2809 将本 PR 语义合并到当前 master 并重写为线性单提交(修 #575 同样的 diff-爆炸问题)。全量 1146/1146 通过、typecheck 0 错、build 成功。语义合并要点:#570 weak-overflow:util.ts 取 master #554 的超集正则;server 的保守估计保留 raw-body 兜底但走 confirmed 通道命名;side-request guard 改读 resolveLearnedLimit(confirmed→speculative),老 #554 测试断言对齐 confirmed 通道。CI 绿后请人工合并。 |
[bot] 🏷 Verified the rewritten branch independently:
Everything checks out. On the merge itself: I can't merge PRs — system rules forbid it. Please merge yourself: #572 |
The window is a deployment property, owned by declarations (config / registry / runtime-info), never adjusted from session traffic. The learned-window channel (confirmedContextLimit/confirmedContextLimits, retraction, weak-overflow arming) accumulated patch-on-patch fixes (ranxianglei#570, ranxianglei#572, ranxianglei#857, ranxianglei#969) and still mis-sized windows in the field (ranxianglei#987: a session window silently re-centered to 16898). Removed: - src/weak-overflow.ts (armFailureShrink/armedAtLeast ladder) and its tests; an upstream rejection now arms the one-shot emergency shrink directly at the stated window, or min(declared, payload-estimate) when no number is parseable (source=usage). - The self-heal application ladder in server.ts (learnedLimit / operatorOwnsWindow / nativeFromFallback learn paths) — the declared window resolves once and keeps governing. - confirmedContextLimit(s) session metadata fields. - sideRequestGuard's learnedLimit param; the guard now intersects the declared window with the usage-grounded arm only. Kept: the one-shot emergency shrink (per ranxianglei#969/ranxianglei#987 decisions), ranxianglei#496 forward-once gate (now keyed on the rejection arm), ranxianglei#857 usage-grade provenance, ranxianglei#570 no-retraction guarantees (trivially — nothing to retract). Tests rewritten to the new semantics; exit-matrix updated.
Problem (#570)
The weak-overflow heuristic (3 high-usage stream truncations in 15 min) and the strong path (a real non-2xx overflow rejection) both wrote into the same per-model
learnedContextLimits. Any mid-stream death — llama.cpp shared-KV exhaustion (failed to find free space in the KV cache), OOM, network reset — looked like an overflow, so one misjudged session permanently shrank the model's window for every later session, across restarts, with no correction path: the only upward self-heal is gated on fallback windows, never on the authoritative configured value.Fix (three parts)
Provenance split. Strong evidence (an actual non-2xx overflow rejection, incl. the payload-size upper bound) now lands in
metadata.confirmedContextLimits/confirmedContextLimit; the weak heuristic keeps writing only tolearnedContextLimits/learnedContextLimit. Resolution order is confirmed > speculative, so a weak guess can no longer clobber a confirmed window.Retraction. A successful turn whose upstream-reported input exceeds a learned window beyond a margin (
max(256 tokens, 3%)) proves it stale — KV-pressure false positive, resized server, … — and removes it before this request's config is resolved. True overflows cannot be contradicted (a turn cannot succeed above the real window); the armed emergency value (== the learned value exactly) sits below the margin and never retracts itself.Ground truth for llama.cpp.
inspectContextOverflownow recognizesexceed_context_size_errorand parses the real limit from the(N / M > W)body shape, so a genuine overflow learns W instead of letting the weak path guess.Both compression modes considered: plugin mode (agent-owned compression; proxy suppresses injection) and proxy mode — the changed paths are upstream-facing (error inspection, per-request limit resolution, session metadata) and identical on both; no wire-format change.
Pre-flight
npm run typecheck— cleannpm test— 1056/1057 pass; the single failure (launcher.test.ts: resolveClientCommand codex/claude resolve to themselves) is pre-existing on clean master in this environment (sandbox stub at/usr/bin/codexmakes the resolver return an absolute path) and unrelated to this changenpm run build— successNote: the real-client E2E suite (
tests/e2e/, needsACP_TEST_E2E=1+ live Responses upstream) was not runnable in this sandbox; the local e2e-style self-heal tests (tests/e2e-overflow-selfheal.test.ts,issue-393,issue496) all pass.