fix: unify tool-message accounting across status report surfaces (issue #390) - #177
fix: unify tool-message accounting across status report surfaces (issue #390)#177ranxianglei wants to merge 1 commit into
Conversation
📦 Built Package ArtifactBranch: Option A — Install from npm PR tag (recommended)In your adapter project: npm install acp-kernel@pr-177Each push to this PR publishes a new version under the Option B — Download artifact
tar xzf acp-kernel-pr177.tgz
npm install ./packageThis comment is automatically updated on each push. |
[bot] 🏷 Reviewing this PR now — pulling branch |
[bot] 🏷 Review: LGTM — all four fixes verified against the branch ( What I ran (full pre-flight, not just trusting the description):
Fix-by-fix verification:
Test quality: the new tests cover the right regressions — 51K-char result landing in the tool bucket (12.8K/100%), cross-surface agreement between the breakdown and Minor nits (non-blocking, no changes required):
Verdict: correct, minimal, well-tested, and the description matches the code exactly. Ready for human merge (per repo rules I don't merge PRs myself). Don't forget the tracked follow-up in billion-context#390: pass |
What
Fixes the four kernel-side defects behind billion-context issue #390 (acp_status CONTEXT BREAKDOWN under-counts tool output by ~99%, prints two contradictory tool/text splits, mixes two token estimators without labeling, and can print bucket percents summing to >100%):
report.tsfield-selection bug —collectVisibleclassified messages bymessage.toolName ?? "text", but wire converters (anthropic.ts,openai.ts,responses.ts) only settoolNameon the call side; everytool-resulttherefore landed in the text bucket. Now classification uses the sharedisToolMessage()(contentType-based), and result-side tool names are resolved through the sharedtoolCallIdso both halves of an exchange land in the same named tool bucket (Top tools / drilldowntool:filter now work for results too).src/message-kind.tsexports the singleisToolMessage()definition;report.ts,recommend.ts(local copy deleted), andcompress.ts computeContextBreakdown(inline copy deleted) all use it. One definition, three surfaces.pct()no longer clamps to 1%: tiny buckets print0%and three buckets can no longer print 1%+1%+1% with sum >100.unprunedTokensdocstring/comment claimed "chars/4" but the nudge breakdown actually runs on the core's estimator (defaultCountTokens, CJK-aware, unless a host injects one intocreateCore). Comments corrected to state the real contract: same estimator on both sides of the Session-only subtraction (issue fix: hide all orphaned compress calls #18 family). No arithmetic change — the bili host already computesunprunedTokenswithdefaultCountTokens.Tests
tests/report-accounting.test.ts(new): 51K-char tool-result lands in the tool bucket (12.8K, 100%); breakdown tool split corroboratesbuildCompressibleRangestoolPct on the same message set; no 1% floor (sums ≤100); injected-estimator scale check (CJK 4000 chars → 4.0K withdefaultCountTokensvs 1.0K withestimateTokensFast); orphan result stays in tool bucket undertool; drilldown filters results by resolved name.tests/panel.test.ts: new same-scale Session-only case with CJK originals (1000 CJK chars = 1.0k, not 250).Pre-flight
npm run typecheck— cleannpm test— 556/556 pass (549 baseline + 7 new)npm run build— cleanNote:
npm run format:checkfails on 89 files at clean master (pre-existing, CI does not gate on it); edits follow each file's local style.Follow-up (separate repo)
billion-context must (a) pass
defaultCountTokensinstead ofestimateTokensFasttobuildStatusReportin its three acp_status paths, and (b) bump acp-kernel to this release. Tracked in billion-context#390.