Repository navigation
fix: gate fork sessions on char-count upper bound in preflight (#553) - #558
Conversation
[bot] 🏷 On it — checking out |
[bot] 🏷 Review complete — LGTM with minor nits. I checked out the PR branch and verified every claim independently. Verification (all executed, not taken on trust)
Triage conclusions
Nits / observations (non-blocking)
Housekeeping
|
#553) Semantic merge onto current master. The fork-predate relax walk (#544/ #575), wire overhead (#470), image floors (#488), side-request isolation (#388) and pi host-usage (#590) all landed after this PR's fork point (09ef208). Resolution: - preflight.ts: char regime (unknownBaseline / estimateCoreMessagesUpper / char-based splitChunks + netting / fitsWindow) grafted onto the multi- range walk; the upper bound also carries the image+wire floors. - server.ts: effectiveTokenCount feeds all three prepare branches; the trigger's tokenCount uses upper+floors only for anonymous zero-baseline sessions; unknown-baseline keeps the loop's fitsWindow judgment, known keeps master's rebuilt-payload re-estimate (#330). - unknown-baseline + nothing-compressible fails fast (PR semantics); known-baseline falls through to preflightCompress so the #330 relax path still runs. - Tests adapted to current master/kernel: fork conversation reshaped for the kernel's minPressureBenefit (5k) band and main-request shape (max_tokens>200) since #388 now routes the old shape to passthrough.
8403c7c to
9630396
Compare
|
已在 9630396 将本 PR 语义合并到当前 master 并重写为线性单提交(修 #575 同样的 diff-爆炸问题)。全量 1146/1146 通过、typecheck 0 错、build 成功。语义合并要点:#553 fork 上界:char regime 移植到 #575 多 range walk 上,上界补 #470/#488 floors;unknownBaseline 用 fitsWindow、known 用 master 重建实测;unknown+无range 才提前 failFast,known 落穿保 #330 relax;测试按新 kernel 阈值(minPressureBenefit 5k)与 #388 side-request 形态调整。CI 绿后请人工合并。 |
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)npm install -g billion-context@pr-558Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf billion-context-pr558.tgz
npm install -g packageThis comment is automatically updated on each push. |
[bot] 🏷 重写后的 验证结果(均实际执行)
Diff 审计(对照合并说明逐条核实)
一点范围观察(非阻塞)
CI 绿后请人工合并(按仓库规则我不执行 merge):#558 |
Problem (#553)
Anonymous prefix-affinity sessions minted after an ACP compression (forks) start with
lastInputTokens = 0. Preflight then decided solely on the optimisticdefaultCountTokensestimate (non-CJK 4 chars/token), which undercounts dense code/JSON replays by up to ~4x — so over-window payloads were forwarded raw upstream: no compression, no interception, doom-looping into #551's 300s transfer cutoffs andexceed_context_size_error400s.Fix
When a session has no measured baseline AND arrived anonymously (prefix-affinity resolution), judge payload size by a char-count upper bound — 1 token per char, which never undershoots BPE token counts since every token covers at least one character. Applied at three points:
tokenCount= char upper instead ofmax(baseline, optimistic), so over-window dense replays enter the compress loop.minUnitsguard so sub-minimum chunks are never emitted), char-based netting, and a regime-awarePreflightResult.fitsWindowverdict — optimistic for measured-baseline sessions (preserves the fix: stitched-stream usage double-count after compress re-request (adapter-anthropic >0 guard) #300 stale-baseline contract byte-for-byte), char upper for unknown-baseline ones (closes the residual gap where the loop exits with failure while the optimistic figure still says "fits").Explicit-identity zero-baseline sessions keep today's optimistic path: they are genuinely-new or post-native-compaction populations whose payloads are small or shrink, and they self-heal via the learned-window overflow path (
persist.tspersistslastInputTokensacross restarts, so zero-baseline anonymous sessions are exactly the fork/reload population).Why not an estimator multiplier? Any fixed k<4 false-fires on repetitive prose that BPE-compresses at ~4+ chars/token (the codex-compact-e2e setup sits at 3.5x window in chars while truly fitting at 87% of window); k=4 is exactly the bug. Content is indistinguishable by char-ratio, so the conservative measure is scoped structurally (anonymous + zero-baseline) instead.
Tests
tests/preflight-fork-estimate.test.ts: anonymous fork replay whose optimistic estimate fits but char upper does not → preflight fires, summarizes, forwards within window; small anonymous fresh session → no preflight (no over-fire). Both verified RED on old code / GREEN on fix.launcher.test.ts, fails identically on clean tree — sandbox lacks client binaries).npm run typecheckclean;npm run buildclean.E2E_CHECK=1zero-token preflight passes against built dist. FullACP_TEST_E2E=1run is not completable in this sandbox (codex warmup fails identically on the clean tree before any change lands) — flagged for CI/manual run.