feat(opencode): surface context-window usage and session cost on the meter - #8659
feat(opencode): surface context-window usage and session cost on the meter#8659ardevdevts wants to merge 12 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR adds a substantial, automatically active OpenCode usage and cost-metering feature across the server event pump, shared contracts, and web UI, including catalog lookups and new turn accounting. An unresolved Medium-severity comment also concerns possible prior-turn usage contamination. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit bd0a80e. Configure here.
|
Note 🤖 GPT-6 Astra (preview) responding on behalf of Theo This note is part of an automated cleanup pass. Preserve the live-usage cases from #8918 at its head commit. |
a3da3b1 to
dcf485c
Compare
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |
…edundant scenarios
- Gate same-model provider.list retries behind 30s cooldown so replays don't stall pump - Pass abort signal so 5s timeout interrupts wedged catalog fetch
- Merge per-message token reports with same-id replace and cross-turn fencing - Emit usage, modelUsage, and totalCostUsd on turn.completed - Drop contribution ledger on failed, aborted, or interrupted turns
- Accumulate per-message reports with same-id replace across tool steps - Carry usage, modelUsage, and totalCostUsd on idle turn.completed - Fence late events from a prior turn out of the new turn's totals
- Evict oldest contributionTurnMap entries past 1,000 so long-lived sessions cannot accumulate message ids without bound, while recent keys stay fenced to their owning turn
Co-authored-by: macroscopeapp[bot] <170038800+macroscopeapp[bot]@users.noreply.github.com>
36550ae to
6712dc5
Compare
- Consolidate token normalization cases into one context-window snapshot test - Cover failed turns omitting usage, modelUsage, and totalCostUsd - Fold small contribution fence-map bound check into trim test
32b698c to
ef71de3
Compare
- Skip `other`-owned messages when recording turn contributions - Prevents late message.updated events from inflating current usage totals
Bugbot is paused — on-demand spend limit reachedBugbot uses usage-based billing for this team and has hit its on-demand spend limit. A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue. |

Problem
OpenCode sessions never reported token usage, so the context-window meter stayed empty for them while Codex and Claude sessions render usage.
Change
OpenCodeAdapternow emitsthread.token-usage.updated: per-message counts from assistantmessage.updatedevents folded with cumulative session totals and USD cost fromsession.updatedevents. Emissions are deduped over every input that shapes the snapshot, so unchanged session replays don't spam the event log while real changes (including output-only growth mid-stream) re-emit.maxTokens) is resolved once per model from theprovider.listcatalog; a transient catalog failure is retried on the nextsession.updatedinstead of giving up for the session's lifetime.costonThreadTokenUsageSnapshot; the web context-window meter renders a Cost row when a provider reports it.Note: Claude's
total_cost_usdcurrently lands on theturn.completedpayload and is not wired into the meter — left as-is for now.Verification
Focused tests pass (OpenCodeAdapter 92, ContextWindowMeter + contextWindow 11) covering the mapping, dedupe, late/retried catalog resolution, zero-token handling, and model switches; targeted typecheck is clean.
Model: glm-5.3-flash · harness: opencode
Note
Add context-window usage and session cost reporting to
OpenCodeAdaptermeterOpenCodeAdapternow emitsthread.token-usage.updatedevents carrying aThreadTokenUsageSnapshotwith input/cache/output/reasoning token counts, cumulative session totals, resolved model context capacity, and cumulative session cost.trimContributionTurnMap.provider.listwith a 5-second timeout and a 30-second retry cooldown per model. Failed lookups leave capacity unset rather than blocking usage emission.ThreadTokenUsageSnapshotin providerRuntime.ts gains an optional finite, nonnegativecostfield.clearOpenCodeTurnContributions, so no usage payload is attached to those turn completions.Macroscope summarized bf3d9ab.
Note
Medium Risk
Changes the OpenCode event pump (catalog calls on session updates) and token accounting visible in the UI; bounded by timeout and extensive tests, but still on a hot path for live threads.
Overview
OpenCode sessions now drive the context-window meter the same way other providers do, by emitting
thread.token-usage.updatedfrom assistantmessage.updatedandsession.updatedevents.The adapter adds
normalizeOpenCodeTokenCounts/normalizeOpenCodeTokenUsageto clamp bad token payloads and map OpenCode’s split counts (input, cache, output, reasoning) into aThreadTokenUsageSnapshot, including optionaltotalProcessedTokens,maxTokensfromprovider.list(once per model, 5s timeout, retry on later session updates), and cumulative USD cost. Emissions are deduped; zero-token assistant messages no longer wipe prior usage; model switches clear stale limits.Contracts gain optional
coston the snapshot; the webContextWindowMetershows a Cost row viaformatContextWindowCostwhen cost is reported.Reviewed by Cursor Bugbot for commit bd0a80e. Bugbot is set up for automated code reviews on this repo. Configure here.