feat(server): show OpenCode session context window usage - #7072
Terrigible wants to merge 13 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: Team Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Warning Your free Security trial is over. An organization admin can upgrade to Advanced for continuous pull request security review or dismiss this notice. Comment |
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This adds OpenCode context-window usage as a new user-facing capability and changes the production event path with per-session metadata probes and background FIFO workers. The asynchronous behavior, fallback metadata defaults, and session-lifecycle handling warrant human review. Notes:
You can add or adjust custom eligibility rules. Learn more. |
|
Addressed the review findings from Cursor Bugbot and Macroscope on the metadata probe timeout. Root cause: the shared Fix: bound each probe with its own |
9a6daad to
5055ca4
Compare
|
Addressed the Bugbot finding about zero-token updates stalling the event pump (commit 06a727ec9). Root cause: Fix: bail out of |
Rebase of feat/opencode-context-window-usage onto upstream/main (2daff8c). Squashed 14 commits: context window reporting, token sanitization, probe timeouts, directory-scoped config probes, per-probe timeout handling, auto-compaction flag, and zero-token broadcast pump fix. Original commits: 06a727ec9 fix(server): don't stall OpenCode event pump on zero-token broadcasts 5055ca407 fix(server): read auto-compaction setting when catalog probe times out 9a4646a96 fix(server): keep OpenCode model catalog when a config probe times out 5f086b48b docs(server): trim OpenCode context usage comments 0855e3f5c fix(server): narrow OpenCode token counter guard for TS 6.0 f8192359f fix(server): scope OpenCode context usage probes to the session directory cac12a5f9 fix(server): tolerate malformed OpenCode token breakdowns e1481e234 fix(server): sanitize OpenCode token counts before reporting context usage f11a03df1 fix(server): tighten OpenCode context usage metadata probe timeout 157eda4bb fix(server): harden OpenCode context usage reporting 3d7f385b1 test(server): drop redundant OpenCode auto-compaction default test 9b5745485 feat(server): read auto-compaction from OpenCode config ec429fb3a fix(server): drop total processed tokens from OpenCode context usage 791219301 feat(server): report OpenCode session context window usage
06a727e to
09a9319
Compare
- require integer context windows before emitting maxTokens (fractional limits violated PositiveInt and could persist) - keep emitting token usage even when display output is suppressed after an interrupt, otherwise the meter underreports until the next completed message
|
Addressed the two new review findings on 09a9319 (now 537322a): Macroscope — fractional maxTokens (Medium, Cursor Bugbot — interrupt skips usage (Low, |
The suppress-path emit used activeTurnId, which is empty after an interrupt (turnless, breaking revert) and is already the next turn once awaitingBusyAfterInterruption is set (misattributing aborted counts to the new turn). Use interruptedTurnId / pendingIdle turn instead, and avoid stamping on the new turn when no aborted id is known.
|
Addressed Bugbot Medium on 537322a — Previous fix exempted token usage from Fix: in the suppress branch, resolve the usage turn as |
- trim verbose block comments to 1-2 liners - unify token counter helper (sanitizeCounter) - collapse nested Option/Exit checks into single guard - shorten session context field docs - keep all behavior and tests passing
…xt-window-usage # Conflicts: # apps/server/src/provider/Layers/OpenCodeAdapter.ts
# Conflicts: # packages/client-runtime/src/rpc/session.test.ts
The first token-bearing message.updated awaited the config.providers/config.get probes inline, stalling the sequential event pump for up to the probe timeout and delaying text deltas, approvals, and idle/completion events queued behind it. Emit the usage snapshot from cached metadata instead, running the probe in a session-scoped background fiber.
Queue token-bearing inputs for a per-session FIFO worker instead of forking one background fiber per message. A slow metadata probe could otherwise let the first message's stale counters overwrite newer usage once the probe completed, bypassing dedup because the late limit differed.
Handle probe/emit failures per worker iteration instead of letting one bad snapshot end the runContextWindowUsageWorker loop. A dead worker left modelContextWindowQueue set with nothing reading it, silencing the meter for the rest of the session. Only interruption still ends the loop on session teardown.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit d3a0df1. Configure here.
Record lastEmittedContextWindowUsage after the emit succeeds instead of before. A failed emit no longer marks the snapshot published, so an identical re-broadcast retries instead of deduping against a snapshot the meter never showed. Also propagate any interruption (pure or mixed) out of the usage worker so session teardown never waits on it, and cover stopping while the probe is wedged.
The upstream merge commits ran an older formatter over every staged file, leaving whitespace-only deltas in 31 files this branch never otherwise touched. Restore them to main's content so the PR shows only the OpenCode context-usage changes.
The re-merge resolution had reflowed Array.from onto multiple lines; main already carries the substantive sourceEvents lines, so restore its exact content.
# Conflicts: # apps/server/src/provider/Layers/OpenCodeAdapter.test.ts # apps/server/src/provider/Layers/OpenCodeAdapter.ts
|
Note: GPT-6 on behalf of shivam (@shivamhwp). The new metadata tests in Use an The added |
|
Thanks for the PR. We're not taking changes to the orchestration and provider layers right now: that part of the server is being rewritten for V2, and merging into the current code would either conflict with or be thrown away by that work. Closing for now. If this is still an issue once V2 lands, please reopen (or open a fresh PR against the new code) and we'll take a proper look. |

What Changed
Why
Caveats
UI Changes
N/A — server-side only; the meter is already supported.
Checklist
Implementation Details
ThreadTokenUsageSnapshotfrom OpenCode's per-message token breakdown (input, output, reasoning, cache read/write).compaction.autofrom the project'sopencode.json; the flag defaults totruewhen the config can't be read.usedTokensto the context window so the meter never reads past 100% when OpenCode's cumulative counts momentarily overshoot around auto-compaction.0.message.updatedevents so repeated snapshots don't persist duplicatecontext-window.updatedactivities.OPENCODE_CONTEXT_METADATA_PROBE_TIMEOUT_MS); a wedged fetch degrades the meter to token counts without a percentage rather than hanging session start.Created by deepseek-v4-flash via opencode.
Note
Medium Risk
Changes OpenCode event handling and concurrent config probing on the hot session path; failures are bounded but incorrect metadata could misstate compaction or context limits until probes succeed.
Overview
OpenCode threads can now drive the same context usage meter as Codex and Claude by turning cumulative assistant
message.updatedtoken counters intothread.token-usage.updatedsnapshots.OpenCodeAdapteradds helpers to sanitize token fields, sum usage, build aThreadTokenUsageSnapshot(optionalmaxTokensfrom the model catalog,compactsAutomaticallyfromcompaction.auto), and dedupe identical re-broadcasts. Metadata is loaded once per session via bounded 2s probes toconfig.providersandconfig.get(session directory–scoped); failures degrade to counts without a percentage cap rather than blocking the event pump.Usage emission runs on a per-session FIFO background worker so slow or hung config probes do not stall sequential session events. Zero-token broadcasts skip probes; interrupted turns still publish usage on the correct turn id.
OpenCodeAdapter.testgains a config mock and broad coverage for clamping, malformed counters, probe timeouts, pump ordering, dedup, emit failures, and session stop while probing.Reviewed by Cursor Bugbot for commit 6939051. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add OpenCode session context-window usage reporting via background worker
OpenCodeAdapterthat sanitizes malformed counters, sums input/output/reasoning/cache tokens, and includes the model context limit when availablerunContextWindowUsageWorker, a per-session FIFO background worker that loads model metadata and emitsthread.token-usage.updatedevents without blocking the sequential event pumploadContextUsageMetadataprobesconfig.providersandconfig.getin parallel with a 2-second timeout; failures and timeouts leave defaults and are not retriedemitContextWindowUsageskips zero-token payloads, suppresses duplicate snapshots, and only marks a snapshot as emitted after the event succeedsemitContextWindowUsagenow forks a background worker per session on first positive-token payload; session teardown must propagate interruption to stop it, as verified by the stop-during-usage-probe test in OpenCodeAdapter.test.tsMacroscope summarized 6939051.