Skip to content

fix: acp_status breakdown uses the CJK-aware estimator (issue #390) - #399

Closed
ranxianglei wants to merge 1 commit into
masterfrom
2026-08-31_status-report-accounting
Closed

fix: acp_status breakdown uses the CJK-aware estimator (issue #390)#399
ranxianglei wants to merge 1 commit into
masterfrom
2026-08-31_status-report-accounting

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

What

Issue #390, bili-side half. The acp_status CONTEXT BREAKDOWN passed estimateTokensFast (chars/4) to buildStatusReport while the nudge-side breakdown (same session, same report output) runs on the core's CJK-aware defaultCountTokens — so in Chinese sessions the report systematically underestimated ~4×, and the two surfaces in one acp_status answer used different scales without any label.

  • src/loop/core.ts (unified-loop handleAcpStatus), src/stream.ts, src/compress-loop-responses.ts: pass defaultCountTokens instead of estimateTokensFast to buildStatusReport — one scale for the whole report, matching the nudge and the panel's Session-only contract.
  • src/server.ts: drop the now-unused estimateTokensFast import.
  • No src/plugin.ts arithmetic change: unprunedTokens already uses defaultCountTokens, same estimator as the nudge breakdown (createCore() is called without injected ports) — the release v0.1.6 #18-family defect there was the kernel's panel.ts docstring claiming "chars/4"; fixed in acp-kernel PR vscode copilot 缺乏适配 #177.

Tests

  • tests/loop-core.test.ts: new regression — an acp_status round over a 4000-CJK-char message must print 4.0K text (100%) (CJK 1:1), and the old chars/4 scale (1.0K) must not appear.

Pre-flight

  • npm run typecheck — clean
  • npm test — 869/869 pass
  • npm run build — clean

Companion PR (kernel-side half of #390)

acp-kernel#177 fixes the remaining defects: tool-results misclassified as text in the breakdown (field-selection bug), the two conflicting "tool" definitions (now one shared isToolMessage), the pct 1% floor, and the panel scale-contract comments. Follow-up after acp-kernel#177 releases: bump acp-kernel here to the new version (exact pin, per AGENTS.md §5 cross-repo rule) so the bundled dist picks up the tool-bucket fix.

@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown

📦 Built Package Artifact

Branch: 2026-08-31_status-report-accounting (d57fe49)

Option A — Install from npm PR tag (recommended)

npm install -g billion-context@pr-399

Each push to this PR publishes a new version under the pr-399 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr399.tgz
npm install -g package

This comment is automatically updated on each push.

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 ework agent · vllm-qwen/qwen3.8-27b

[bot] 🏷 Picked up. Checking out 2026-08-31_status-report-accounting (598b687), reviewing the diff against the issue description, and running the full pre-flight (typecheck / test / build). Will report back with results.

@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 ework agent · vllm-qwen/qwen3.8-27b

[bot] 🏷 Verification complete on 2026-08-31_status-report-accounting (598b687). All checks pass:

Diff vs. description — matches exactly

  • src/loop/core.ts:139handleAcpStatus now passes defaultCountTokens to buildStatusReport
  • src/stream.ts:217 — Anthropic-wire acp_status proxy tool → defaultCountTokens
  • src/compress-loop-responses.ts:105 — Responses-wire acp_status proxy tool → defaultCountTokens
  • src/server.ts — unused estimateTokensFast import dropped
  • tests/loop-core.test.ts — new loop #390 regression: 4000-CJK-char message must print 4.0K text (100%), and 1.0K text (100%) (chars/4) must not appear

Additional checks

  • No remaining estimateTokensFast call sites anywhere in src/ (only a doc mention in UNIFIED_LOOP_SPEC.md:96 and a comment in the new test).
  • assignRefs / defaultCountTokens / buildStatusReport all exported by the pinned acp-kernel@0.0.47.
  • Regression test has teeth: temporarily reverting src/loop/core.ts to master makes the test fail (not ok 2); with the fix it passes. So the CJK 1:1 scale is genuinely pinned down.

Pre-flight (re-run locally, matches the issue's claims)

  • npm run typecheck — clean
  • npm test — 869/869 pass
  • npm run build — clean

Minor (report only): UNIFIED_LOOP_SPEC.md:96 still documents buildStatusReport(state, messages, estimateTokensFast) for acp_status — now stale; worth a one-line spec update whenever you touch that doc.

Follow-up status (acp-kernel bump): acp-kernel#177 is NOT yet on latest — npm's latest is still 0.0.47; only the prerelease 0.0.47-pr.177.30 exists. Per AGENTS.md §5 (kernel must ship first, exact pin), the acp-kernel bump here stays blocked until #177 merges and a stable version publishes. Flagging so it isn't lost.

PR is ready for human merge — nothing to fix on the bili side.

@ranxianglei
ranxianglei force-pushed the 2026-08-31_status-report-accounting branch from 598b687 to d57fe49 Compare September 4, 2026 09:29
@ranxianglei

Copy link
Copy Markdown
Owner Author

🤖 ework agent · qwen3.8-27b

[bot] 🏷 结论:本票描述的 bug 已在 PR #400 中修复并合入 master,无需再开新 PR。

证据

master 上的 commit 1fb6b69

fix: stateless decompress — pure retrieval, no deactivate, cache retained (#400)

改动文件与本票三个根因一一对应(src/decompress-shared.ts + tests/proxy-decompress-cache.test.ts),采用的正是你拍板的无状态检索语义。

三个根因如何被覆盖

  1. syncBlocks 复活已失活块 —— decompress 不再调用 deactivateBlock:块从未被失活,下一轮客户端重发全史时 syncBlocks 看到的本就是 active 块,不存在"复活"动作,因此也没有"摘要 + 已还原全文"同轮双重计费。
  2. decompress 即删 blockContents 缓存 —— 删掉了 if (count > 0 || cached) 分支里的 deactivateBlock(...)blockContents.delete(blockId):缓存永久保留,同一块可无限次 decompress,每次都是完整原文,不会再退化成 [Restored block bN — 0 item(s)]
  3. loop 路径把折叠视图喂给回退检索 —— 回退改为 collectBlockContent(state, block, ctx.compressMessages ?? ctx.messages, { full }),与流路径(server.ts 传 originalMessages)对齐;ProxyToolCtx 新增可选 compressMessages 字段,loop/stream 两条路径对同一请求返回一致内容。

acp-kernel 零改动ctx.core.decompress() 本就是纯块查询、collectBlockContent 本就是无状态原语、deactivateBlock 只是导出的原语(现在 decompress 不再用它)。此前为 expanded 方案临时开的 kernel PR #181 已关闭未合并。

验收标准对照(无状态语义)

  • compress → decompress → 重发全史后:块保持 active === true、转发视图仍折叠(summary 在视图中)✓
  • 重复 decompress 同一块:每次返回完整原文、不退化 ✓
  • loop / stream 路径对同一 decompress 请求返回一致内容 ✓

说明

我这边也独立按同一方案实现过一版(基于较早的 base),核对后发现与 #400 实质相同(仅 header 文案措辞不同:#400[Block bN content — K item(s)]),故不重复开 PR,本地那份半成品分支作废。

建议直接关闭本票(已由 #400 修复,随下个 release 生效)。如需我把 #400 的 diff 与本票逐条根因再对一遍、或补一个回归 e2e,说一声即可。

@ranxianglei

Copy link
Copy Markdown
Owner Author

Closing: superseded by #397 (acp-status.ts). The three status dispatchers this PR touched (loop/core.ts / stream.ts / compress-loop-responses.ts) were replaced by the unified handleAcpStatus in src/acp-status.ts, which calls buildStatusReport(..., defaultCountTokens, ...) — the CJK-aware estimator is already in use.

@ranxianglei ranxianglei closed this Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant