Repository navigation
fix: count reasoning tokens in context-usage display estimates (#371) - #374
Merged
Merged
Conversation
Contributor
📦 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. |
added 2 commits
September 10, 2026 23:24
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
ranxianglei
force-pushed
the
2026-09-08_reasoning-in-context-estimate
branch
from
September 10, 2026 15:44
425a5d6 to
3d40d57
Compare
Owner
Author
|
简述做了啥 |
Owner
Author
简述一句话:让 ACP 的上下文用量展示估算把 为什么是两处(两条重复代码路径,只改一处修不全):
具体改动:
验证:1086/1086 通过(master 原 1077,+9);9 个新测试均实证在改前代码上失败;双 agent 评审(code §5.3 + tests §5.6)均 APPROVE。 明确不做 / 遗留:
Fixes #371 |
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