Skip to content

feat(opencode): surface context-window usage and session cost on the meter - #8659

Open
ardevdevts wants to merge 12 commits into
pingdotgg:mainfrom
ardevdevts:t3code/opencode-context-window-usage
Open

feat(opencode): surface context-window usage and session cost on the meter#8659
ardevdevts wants to merge 12 commits into
pingdotgg:mainfrom
ardevdevts:t3code/opencode-context-window-usage

Conversation

@ardevdevts

@ardevdevts ardevdevts commented Aug 29, 2026

Copy link
Copy Markdown

Problem

OpenCode sessions never reported token usage, so the context-window meter stayed empty for them while Codex and Claude sessions render usage.

Change

  • OpenCodeAdapter now emits thread.token-usage.updated: per-message counts from assistant message.updated events folded with cumulative session totals and USD cost from session.updated events. 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.
  • Context-window size (maxTokens) is resolved once per model from the provider.list catalog; a transient catalog failure is retried on the next session.updated instead of giving up for the session's lifetime.
  • Zero-token updates (e.g. compaction summary messages) no longer clobber the meter's per-message usage.
  • Contract: optional cost on ThreadTokenUsageSnapshot; the web context-window meter renders a Cost row when a provider reports it.

Note: Claude's total_cost_usd currently lands on the turn.completed payload 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.

image

Model: glm-5.3-flash · harness: opencode

Note

Add context-window usage and session cost reporting to OpenCodeAdapter meter

  • OpenCodeAdapter now emits thread.token-usage.updated events carrying a ThreadTokenUsageSnapshot with input/cache/output/reasoning token counts, cumulative session totals, resolved model context capacity, and cumulative session cost.
  • A per-turn contribution ledger records token usage from assistant messages, deduplicates same-key reports, and fences ownership so late updates from a prior turn cannot contaminate a later turn. The ownership map is bounded to 1,000 entries via oldest-first eviction in trimContributionTurnMap.
  • Model context limits are resolved best-effort through provider.list with a 5-second timeout and a 30-second retry cooldown per model. Failed lookups leave capacity unset rather than blocking usage emission.
  • ContextWindowMeter.tsx now renders a Cost row in its popover when the snapshot contains a positive cost, formatted by contextWindow.ts.
  • ThreadTokenUsageSnapshot in providerRuntime.ts gains an optional finite, nonnegative cost field.
  • Behavioral Change: failed, aborted, or interrupted turns now discard their contribution ledger entries via 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.updated from assistant message.updated and session.updated events.

The adapter adds normalizeOpenCodeTokenCounts / normalizeOpenCodeTokenUsage to clamp bad token payloads and map OpenCode’s split counts (input, cache, output, reasoning) into a ThreadTokenUsageSnapshot, including optional totalProcessedTokens, maxTokens from provider.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 cost on the snapshot; the web ContextWindowMeter shows a Cost row via formatContextWindowCost when cost is reported.

Reviewed by Cursor Bugbot for commit bd0a80e. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0a20ac01-005b-431a-bc60-299cca213b4b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 29, 2026
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts Outdated
@ardevdevts
ardevdevts marked this pull request as ready for review August 29, 2026 18:00
@macroscopeapp

macroscopeapp Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts
@t3dotgg

t3dotgg commented Sep 4, 2026

Copy link
Copy Markdown
Member

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. OpenCodeAdapter.test.ts covers zero-token updates, replacement of duplicate message.updated totals, accumulated usage and cost across tool steps, and usage plus modelUsage on idle turn completion. These cases are separate from the historical scanner in #8456. Before porting them, check message/part/session deduplication and fence late events to their owning turn. Keep context occupancy distinct from cumulative processed tokens. This records cases for review, not code that has already been ported.

@ardevdevts
ardevdevts force-pushed the t3code/opencode-context-window-usage branch from a3da3b1 to dcf485c Compare September 5, 2026 21:39
@github-actions github-actions Bot added size:XL 500-999 changed lines (additions + deletions). and removed size:L 100-499 changed lines (additions + deletions). labels Sep 5, 2026
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts Outdated
@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot 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.

ardevdevts and others added 9 commits September 5, 2026 18:55
- 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>
@ardevdevts
ardevdevts force-pushed the t3code/opencode-context-window-usage branch from 36550ae to 6712dc5 Compare September 5, 2026 22:55
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts Outdated
- 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
@ardevdevts
ardevdevts force-pushed the t3code/opencode-context-window-usage branch from 32b698c to ef71de3 Compare September 5, 2026 23:17
Comment thread apps/server/src/provider/Layers/OpenCodeAdapter.ts Outdated
- Skip `other`-owned messages when recording turn contributions
- Prevents late message.updated events from inflating current usage totals
@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants