Repository navigation
[PR] Failed compression calls become collapsible regular messages, no longer permanently occupying the context. | 失败的压缩调用变成可折叠的普通消息,不再永久占着上下文 - #4291
Conversation
A compress tool-result rendered "[Compression FAILED…" applied ZERO ranges: no block carries its arguments, decompress never consults it, and its summary draft is dead weight. ALWAYS_PROTECTED_TOOLS protected these exchanges by tool name alone, so a failing compress loop permanently bloated context (live incident: 70 failed calls = 116KB of unreclaimable residue, ~75% of a 227K context was compress residue). - protected.ts: FAILED_COMPRESS_RESULT_PREFIX + isFailedCompressResult + collectFailedCompressCallIds; isMessageProtected gains optional failedToolCallIds — failed exchanges lose ALWAYS protection (both halves), successful/partial/pending keep it - collectProtectedToolCallIds: skips failed compress calls (pairing can never re-protect their results) - compress.ts assignRefsNode + unit-projection filterProtectedToolMessages: thread the failed-call set - refs.ts BLOCKED→numeric migration (#2607) self-heals legacy sessions: the next assignRefs re-refs old failed exchanges as foldable
Kernel Boundary rule 2 (CI kernel-guard): kernel/src changes require a version bump in kernel/package.json so accumulated changes can ship as an independent acp-kernel release later. Regenerates both lockfiles (version lines only).
📦 Built Package ArtifactBranch: Option A — Install this exact build (recommended)npm install -g billion-context@0.0.5105-pr.4291.d4453d1This exact version is immutable and reproducible. The rolling Option B — Download artifact
tar xzf billion-context-pr4291.tgz
npm install -g packageInstall instructions are refreshed on each push. |
(ai: vllm-qwen/qwen3.8-27b) 查重: 不重复。 本 PR 是 #4289 的实现 PR(自身线程);检索 open+closed 的 issue/PR,无其他在途工作做「失败压缩交换可折叠」——最近的邻居 #4217(failed-only 轮次的 ephemeral 失败帧不进上游)机制不同:它管的是失败帧的出站可见性,不管已持久化残渣的可回收性。 标签: bug / scope/kernel / p1(缓存泄露类——上下文只增不减地失控增长,按 10-19 规则定 p1;客户端面跨所有走代理的车道,不猜单个客户端标签)。 初审结论:方向正确、回执契约成立,但豁免没有覆盖全部判定站点和全部方言——实测三处缺口,正在 PR 分支上补齐。 方向与契约核验(通过):
实测缺口(用 PR head 代码构造会话跑
修法(已在做,kernel-only,不动宿主):把 #4289 豁免上移到 完成后按八问体例给最终结论。 |
The first pass left three shapes permanently pinned: - path-pattern protectedTools routed assignRefs through isMessageProtectedWithPairing without the failed set, keeping the call half (the 9-21KB drafts) at BLOCKED - buildCompressibleRanges never received the failed set, so the failed call was classified protected and fragmented the advertised ranges - MCP dialect names (mcp__bili__compress) were outcome-blind: recognition keyed on the bare name "compress" while host tool-hooks stay unconditional Move the #4289 exemption to the top of isMessageProtected (after the host isMessageProtected hook, before every built-in source), make failure recognition dialect-aware through the existing Config.isCompressTool union (bare "compress" always counts), and thread the failed set through isMessageProtectedWithPairing plus the remaining judgment sites (recommend, ccr, absorb, unit-projection). Exchanges under an unknown dialect without a recognizer stay conservatively pinned. Host side unchanged: src/config.ts already injects both hooks. Five new regression tests pin all four facets including both negative controls.
(ai: vllm-qwen/qwen3.8-27b) Review 结论:PR 方向正确;我独立审核 + probe 实锤后发现初版留了三个判定站点未覆盖,已在分支上直接补齐(新 head 八问
验证状态
收工判定:代码侧闭环(方向 + 三缺口 + 负控 + 自愈全部钉住),剩 CI 全绿确认 + owner 合并。kernel 变更走 human-only review,请 @ranxianglei 审后合并。 |
(ai: vllm-qwen/qwen3.8-27b) CI 全绿确认:新 head 代码与 CI 均已闭环,kernel 变更按 human-only review 待你合并:#4291 |
Rebased onto the #4291 head (fix/unprotect-failed-compress @ 6be85cb): the refused-prefix fix now stacks on top of the all-judgment-site failed threading instead of an intermediate #4291 state. Version rebumped past #4291's 0.0.155 so the two PRs can merge in either order without a kernel-guard collision.
📦 Merged Build PublishedThis merge to master was published as npm install -g billion-context@0.0.740-master.fcf3e82 # this exact build
npm install -g billion-context@master # always the newest merged build
|
kernel-change: #4289 — failed compress exchanges (receipt prefix "[Compression FAILED", zero ranges applied) are dead drafts, not compression metadata: no block covers their arguments and decompress never consults them. Un-exempt both halves so they fold like ordinary messages, or a failing compress loop bloats context forever. The protection judgment lives in acp-kernel (shared by every lane) and cannot be solved host-side.
Fixes #4289
一句话
压缩失败的调用(结果以
[Compression FAILED开头 = 一个 range 都没折成)不再享受"永久不可折叠"的元数据豁免 —— 它和普通消息一样可以被下一次压缩回收;成功/部分成功/还没出结果的调用保持豁免不变。为什么安全
[Compression FAILED开头;成功与部分成功的回执以[Compressed开头,保持豁免compress.stripImages默认开启——否则带图消息不可压缩会形成只升不降的输入地板撑爆上下文 #2607),修复上线后第一次 assignRefs 会自动把历史失败调用重新编号为可折叠,无需迁移脚本改动
kernel/src/protected.ts—FAILED_COMPRESS_RESULT_PREFIX/isFailedCompressResult()/collectFailedCompressCallIds();Failed compression invocations are never folded back for reclamation, and the context keeps ballooning under the weight | 失败的压缩调用永远不会被折叠回收,上下文被压缩残渣越撑越大 #4289 豁免提升到isMessageProtected顶部(宿主isMessageProtectedhook 之后、一切内置保护源之前:ALWAYS 表、protectedTools pattern、宿主 tool-hook),使所有判定站点一致解除失败交换的豁免;识别经既有Config.isCompressTool方言感知(barecompress恒计数,mcp__bili__compress等 MCP 方言由宿主注入的 recognizer 认领);isMessageProtectedWithPairing新增可选失败集合参数;collectProtectedToolCallIds跳过失败调用(配对保护不会复活它们的结果)kernel/src/compress.ts— assignRefs 节点把失败集合传进保护判定(调用端 + 配对端;path-pattern 形状同样覆盖)kernel/src/recommend.ts—buildCompressibleRanges接收同一失败集合:失败调用不再被归类为 protected、不再把 advertised range 切碎(KDD#12 单一投影一致性)kernel/src/ccr.ts/kernel/src/absorb.ts— CCR 存储与 absorb 候选判定同样感知失败交换kernel/src/unit-projection.ts—filterProtectedToolMessages同样感知失败交换kernel/tests/issue4289-failed-compress-fold.test.ts— 11 个测试:数字 ref / 可折叠 / 成功与部分成功仍 BLOCKED / 无结果在途仍 BLOCKED / 存量 BLOCKED 自愈迁移 / 单元形状,外加 5 个新回归:advertised range 覆盖 / path-pattern 形状 / MCP 方言可折叠且 advertised / 未知方言保守钉住(负控)/ 方言识别单元src/config.ts本就同时注入两个 hook(isToolProtected+isCompressTool)行为变更披露
protectedToolspattern 与宿主 tool-hook 从此无法钉住失败交换(它们本就不钉成功的)isCompressToolrecognizer 的宿主)下的失败交换保持保守钉住 —— 行为不变protectedLatestTools刻意不豁免(opt-in 的近因语义,默认空)验证
6be85cb5d):issue4289 测试文件 11/11;22 个相关 kernel 测试文件(recommend/protected-/message-protection/absorb/ccr/crush/wire-tool-result/orphan-sweep/ranges-/carrier/dead-ref/media/block-map/issue3236/protect-recent/tool-pairs)307/307 绿;verif-subset-guard 2/2(compress.ts 属 Tier-A 守护清单);typecheck + build 绿4e2c22fef上全仓已全绿(kernel 1434/1434)