Repository navigation
fix(nudge): merge small ranges + effective T1 pending + tier-aware emergency arbitration - #57
Conversation
Cross-link: complementary with the adapter-side filterpi-side adapter filtering (ranxianglei/billion-context-pi#148 + the extracted Review: two regressions found1. The Master had three arbitration bands: growth-gated normal,
2. Emergency with nothing effective now injects every turn (medium). Master: emergency + no eligible tier → Suggested fix: restore a mid band — treat Checked clean
239 tests pass because nothing covers the 75–80% band or the emergency-with-nothing case — both worth a test before merge. |
|
Fixes for both regressions are up in #70 (contains this PR's commits via merge + current master, which also resolves the stale |
…nudges on effective pending Review fixes for ranxianglei#57 (two regressions): 1. The 75-95% over-limit band was deleted — maxContextLimitPct had no consumer. Restored as the pressure band: bypasses growth gate + cadence, picks the tier with the MAX pending (keeping ranxianglei#57's tier-aware argmax and effective-pending semantics), labeled OVER-LIMIT vs EMERGENCY by which threshold fired. 2. Emergency with zero effective pending injected every turn — and could offer sub-minCompressRange tail ranges that would be atomically rejected (the exact failure mode ranxianglei#57 fixes, resurfacing under pressure). Pressure nudges are now gated on effective pending > 0; the suppressed case reports why instead of spamming. Also merges master (truncate machinery, emergencyThresholdPct 0.95) into the branch: pr-57's arbitration is preserved, config keeps master's tuning + the new tier2GrowthMultiplier. 295 tests (+2 regression tests that are red on unpatched ranxianglei#57).
Problem
Diagnosed from the ACP endurance report (dog/billion-context-pi#23): under a
24.5h isolated session, compress failure rate hit 60.5% (825/1363), and the
dominant cause was "too small" rejections — 707 cases, 86% of all failures,
476 of those single-range.
Root cause is a granularity mismatch between nudge arbitration and the
ranges the nudge offers the model:
pendingByTiercomputed T1 pending as the aggregate sum of allcompressible ranges (inflated by fragmentation).
buildCompressibleRangessplits at user boundaries), and the model pickedonly 1–2 of them → `minCompressRange` rejection.
T1-only ranges, never at tier distillation — so T1 blocks piled up unconsolidated.
Fix
1. `mergeRangesToThreshold` (recommend.ts) — two-pass grouping. A greedy
accumulator merges consecutive compressible ranges until the batch reaches
`tokens*4 >= compress.minCompressRange`, then closes. Merges across ref gaps;
count-weighted `toolPct`; `dangerous` propagates. `recommendedRanges` now
returns these merged ranges, so the nudge offers batch-sized ranges the model
can compress in one call without tripping `minCompressRange`.
2. Effective T1 pending (compress.ts) — `pendingByTier` now counts only
effective merged ranges (`tokens*4 >= minCompressRange`) for T1, killing
the inflation that starved tier distillation.
3. Tier-aware arbitration (compress.ts `decideNudge`) —
overrides only when `t2Pen >= nudgeGrowthTokens × 1.5` AND `t2Pen > t1Eff`.
New config `tier2GrowthMultiplier: 1.5`.
(T1 effective vs T2/T3 summary totals) — so emergency now CAN route to
distillation when that reclaims the most tokens.
4. `renderNudgeText` (nudge-text.ts) — tier≥2 path now also serves the
emergency case: emergency voice + `[EMERGENCY — TIER N DISTILLATION]` header,
still with the full distillation block list + rules.
Tests
+16 (239 total, all pass; typecheck clean; build 103.72 KB).
three-split / dangerous propagation / count-weighted toolPct.
T2 large but T1 wins; emergency T2>T1 → tier 2 + override; emergency T1 max → tier 1.
total ≥ `minCompressRange` (documents the batching the report questioned).
Compatibility
No adapter API change. `tier2GrowthMultiplier` defaults to 1.5; existing
config-overrides continue to work (it is additive). Once merged and published,
billion-context-pi will bundle it on its next release bump.