Repository navigation
Description
Environment
- billion-context 0.1.209
- Reproduced on master
e209109bfc3c628c655f09e729784c9f1b95835a - Observed with Hermes using proxy-side ACP compression
- Trigger requires
compress.visibilityMarkers: falsefor the no-continuation exit
Actual behavior
A successful compress call whose model-authored summary contains the uppercase word FAILED is classified as a failed compression. With visibility markers disabled, the loop takes the failed-only exit and finishes with stop_reason: "max_tokens" without making the next model request, so the client's task stops on the compression round.
Expected behavior
Success or failure must be determined from the tool result's status line, not from arbitrary words inside the stored summary. A successful compression must refresh the folded view and continue the model loop even when its summary quotes an earlier failure.
Mechanism
The successful receipt has a [Compressed …] status line followed by fingerprint lines containing the model-authored summary. src/loop/core.ts uses pr.result.includes("FAILED") in five places. If the summary mentions an earlier FAILED tool result, those checks misclassify the new successful compression as failed. This affects continuation, fold refresh, failed-only recovery, and committed-result accounting.
A normal successful compression with markers disabled continues correctly; marker visibility alone is not the trigger. Genuine failures whose first status line contains FAILED must retain their existing recovery behavior.
Minimal reproduction
Run a real proxy-server compression with an eligible range and a valid summary containing FAILED, with visibilityMarkers: false.
- Before: one upstream request, no continued answer, final
stop_reason: "max_tokens". - Expected: a second upstream request containing the successful tool result, followed by the task's final answer.
Proposed fix
Classify only the first non-empty status line with proxyToolResultFailed() and use it consistently at all five call sites. Add both the failing summary-keyword regression and the ordinary-success negative control, then validate through a fresh real Hermes session.
Related: #4856 covers plugin identity and proxy execution, not this result-classification bug.
Suggested labels: bug, hermes, scope/wiring, p2.
Activity
LkxPro commentedon Oct 31, 2026
(ai: custom/kimi-k3.1-pro)
Implemented in #5384: #5384
ranxianglei commentedon Oct 31, 2026
(ai: vllm-qwen/qwen3.8-27b)
查重:不重复。 #5386 是独立缺陷。相关条目核对:#5383 是 owner 的 v0.1.210「回归占位」(ranxianglei 开,只收 210 才有的新坏),不是本 bug——#5384 之前误写
Fixes #5383,我已改成#5386;#4856 是插件身份/proxy 执行的另一条线,机制不同。全库检索无同类在途修复。标签:
bug·hermes·scope/wiring·p2(功能性缺陷,特定触发,可重发绕行)。审核(先审后做)
[Compressed …](src/stream.ts:1356),其后逐块追加指纹行(src/stream.ts:1387–1398)内嵌模型自撰摘要摘录。若摘要引用了更早的FAILED工具结果,src/loop/core.ts五处用整串pr.result.includes("FAILED")判定(1394/1415/1493/1574/1581)就会把这次成功误判成失败。proxyToolResultFailed()只取首个非空状态行判 FAILED,五处统一替换;真失败回执([Compression FAILED:/[decompress FAILED:/[absorb FAILED:)FAILED 都在首行,恢复行为不变。结构化八问
FAILED,就被当成失败压缩处理,本轮直接结束、不再发起下一次模型请求,客户端任务卡在压缩轮。includes("FAILED");成功回执的指纹行带模型摘要,摘要引用旧 FAILED 就命中 → 成功被误判为失败。runCompressLoop(dsh/opencode/pi/hermes/codex…),Hermes 上复现;触发=该轮唯一动作是一次成功压缩且其摘要含大写 FAILED(报告配置visibilityMarkers:false)。特定条件下任务停摆、需重发,非数据丢失/缓存泄露 → p2。[Compressed …]不含 FAILED → 正常续跑 + 刷新折叠视图;真失败首行含 FAILED → 维持原恢复路径。交付
runCompressLoop的 proxy 压缩路径(x-bili-plugin-compression: proxy→pluginMode=false,src/server/handle.ts:1817)、visibilityMarkers:false真实生效(src/config.ts:410/3032→ctx.visibilityMarkers);第二条是带牙回归测试(修复前 1 次上游请求→断言挂,修复后 2 次→过)。Fixes #5383(那是 v210 回归占位,合并会误关占位、漏关本 bug),已改为Fixes #5386;其余正文(含Related: #4856)未动。非阻塞小观察(不塞进本 PR):
buildVisibilityMarker(src/loop/core.ts:54–79)选图标时仍逐行includes("FAILED");标记可见时,成功折叠若摘要含 FAILED 会显示 ❌ 而非 📦。纯外观、同机制不同症状,建议后续单开小修。收工判定: 方向正确、diff 干净、测试有效,issue 引用已修正;等远程 CI 绿即可合并。