fix: count reasoning tokens in context-usage display estimates (#371) - #374
Open
ranxianglei wants to merge 2 commits into
Open
fix: count reasoning tokens in context-usage display estimates (#371)#374ranxianglei wants to merge 2 commits into
ranxianglei wants to merge 2 commits into
Conversation
added 2 commits
September 9, 2026 00:42
estimateContextComposition (nudge breakdown) and collectVisibleMessages (acp_status overview) both skipped reasoning parts, so displayed context-usage percentages systematically undercounted real usage (token-utils.ts usage formula includes reasoning). - ContextComposition gains reasoningTokens; total includes it - nudge breakdown + acp_status CONTEXT BREAKDOWN gain a reasoning category - per-message drilldown totals/sort/lines include reasoning footprint - system prompt breakdown example + category list updated - +8 tests (1085/1085 passing) Fixes #371
- add nudge breakdown line test asserting rendered reasoning category - fix 2 pre-existing vacuous acp_status tests (partial mocks dropped by filterMessages → passed with zero visible messages) - tighten protected-reasoning assertion to exact value - system prompt breakdown example percentages now sum to 100% 1086/1086 tests passing
📦 Built Plugin ArtifactBranch: Option A — Install from npm PR tag (recommended)opencode plugin opencode-acp@pr-374 --globalEach push to this PR publishes a new version under the Option B — Install from GitHubopencode plugin "github:ranxianglei/opencode-acp#2026-09-08_reasoning-in-context-estimate" --globalOption C — Download artifact
tar xzf opencode-acp-pr374.tgz
cp -r package/dist ~/.cache/opencode/packages/opencode-acp@latest/node_modules/opencode-acp/dist
This comment is automatically updated on each push. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The context-usage display estimators count only
text+toolmessage parts and skipreasoningparts entirely, while the real usage formula includes reasoning (lib/token-utils.ts:44:input + cacheRead + cacheWrite + output + reasoning). Two duplicated code paths are affected:estimateContextComposition(lib/messages/inject/utils.ts:586) — powers the nudgeBreakdown:line.collectVisibleMessages+renderOverview(lib/compress/status.ts:125/:185) — powers theacp_statusoverview (CONTEXT BREAKDOWNline). Note:acp_statusdoes not callestimateContextComposition(the import atstatus.ts:9is dead) — fixing only the issue's suggested location would not fix theacp_statusdisplay.Result: displayed percentages systematically undercount real usage, and the largest residual component (reasoning — #368) is invisible in the display.
Not affected:
/acp contextcommand — its TOTAL comes from API-reported tokens and already includes reasoning. The decision path (when to nudge) also already uses the API formula; this is a display-only fix.Solution
Count
reasoningparts (len/4heuristic, same as text parts) as their own visible category in both estimators:ContextCompositiongainsreasoningTokens;total= system + tool + summary + message + reasoning. Reasoning feedsmsgTotal(→protectedTokens,largestRangesreflect full footprint) but notmessageTokens(text/code classification stays clean).| N reasoning (Q%).acp_statusoverview:VisibleMessageInfogains areasoningfield (kept separate fromtokens= text+tool to avoid double counting); inclusion gate widened totokens > 0 || reasoning > 0(reasoning-only messages now visible); overview total +CONTEXT BREAKDOWNline gain the reasoning category; per-message drilldown sort/totals/lines use full footprint (tokens + reasoning).Display-only: no persisted-state, internal-tag, config, or decision-path changes.
Files
lib/messages/inject/utils.ts—ContextComposition+estimateContextCompositionreasoning branch + total.lib/messages/inject/inject.ts— nudge breakdown line.lib/compress/status.ts—VisibleMessageInfo,collectVisibleMessages,renderOverview,renderUncompressedDrilldown.lib/prompts/system.ts— breakdown example + bullets.tests/inject-utils-pure.test.ts(+4),tests/protection-aware-stats.test.ts(+1),tests/acp-status.test.ts(+3, plus 2 pre-existing vacuous tests fixed — their partial mocks were dropped byfilterMessagesso they passed with zero visible messages),tests/inject.test.ts(+1 rendered nudge-line test).devlog/2026-09-08_reasoning-in-context-estimate/— REQ / WORKLOG.Testing
9b7adfd).Known interactions / documented non-goals
stripProtectedReasoning, open): its pass runs BEFOREinjectCompressNudgesinlib/hooks.ts, so post-merge the nudge-path estimator naturally matches sent content.acp_statusreads raw DB messages and will still show request-time-stripped reasoning — feat: strip reasoning from protected-exempt historical messages (gated) #370-side concern, out of scope here.buildCompressibleRangesrange tokens intentionally still exclude reasoning (ranges = compressible amounts; the pipeline's min-size checkcountMessageCharactersalso excludes reasoning — adding it there risks phantom "Range too small" rejections, chore: bump version to 1.6.0 #37). Consequence: the nudge's "Effective compressible: ~X" and the overview total now include reasoning while per-range lines don't. Candidate follow-up issue.dcp-message-idtoken annotation (countMessageCharacters) still excludes reasoning — pre-existing, out of scope, candidate follow-up.countAllMessageTokensfallback (token-utils.ts) unchanged — first-turn only, no reasoning present at that point.Fixes #371