Skip to content

fix(grok): show context-window usage in the composer - #9206

Open
theman6660 wants to merge 2 commits into
pingdotgg:mainfrom
theman6660:fix/grok-composer-context-window
Open

fix(grok): show context-window usage in the composer#9206
theman6660 wants to merge 2 commits into
pingdotgg:mainfrom
theman6660:fix/grok-composer-context-window

Conversation

@theman6660

@theman6660 theman6660 commented Sep 2, 2026

Copy link
Copy Markdown

Closes #8382

What Changed

Grok threads never showed the composer context-window meter. The live adapter did not emit thread.token-usage.updated, so ContextWindowMeter had nothing to render.

This maps occupancy onto that existing path:

  • ACP sessionUpdate: "usage_update" when present
  • Grok's actual path today: session/update _meta.totalTokens
  • Window size from _meta (contextWindowTokens / contextWindow / maxTokens), else the current model's availableModels[]._meta.totalContextTokens, else 500k

Interrupted turns do not overwrite the last snapshot. Cursor gets the shared UsageUpdated case so the ACP union stays exhaustive.

No new UI. The existing composer meter is enough.

Why

Codex already shows used / max / %. Grok did not, even though grok agent stdio already streams fill on _meta.totalTokens.

Live Grok ACP still does not send usage_update. Occupancy lives on session/update _meta.totalTokens. Prompt-response usage.totalTokens is billed API tokens, not context fill. On a greeting turn those were 1615 occupancy vs 20554 billed. This PR does not use the prompt-response number, which is the difference from #5405.

UI Changes

Uses the existing context-window meter in the composer.

  • Before: Grok threads have no context fill indicator.
  • After: After the first occupancy-bearing session/update, Grok shows the same ring + used/max tooltip as Codex.

Validation

  • vp test run src/provider/acp/AcpRuntimeModel.test.ts src/provider/acp/AcpCoreRuntimeEvents.test.ts src/provider/acp/GrokAcpSupport.test.ts — 50 passed
  • Server typecheck: no new errors
  • Live Grok session: _meta.totalTokens is occupancy; prompt usage.totalTokens is billed tokens; signals.json has contextWindowTokens: 500000
  • GrokAdapter mock spawn tests fail on this Windows host (spawn EFTYPE on the .sh wrapper). That is existing, not introduced here. The new adapter test is in GrokAdapter.test.ts for Linux CI.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for the UI change (happy to add a Grok-thread capture)
  • A video is not applicable (no animation/timing change)

Note

Low Risk
Provider-adapter and event-mapping changes only; no auth or persistence changes, with deduplication and explicit exclusion of billed-token metadata reducing wrong-meter risk.

Overview
Grok threads can now drive the existing composer context-window meter by emitting thread.token-usage.updated from ACP session traffic, matching what Codex already had.

ACP parsing gains a UsageUpdated path for explicit usage_update notifications and for Grok’s live signal: session/update _meta.totalTokens (with window size from _meta keys or model metadata). Prompt-response _meta.usage.totalTokens is intentionally ignored so billed API tokens are not shown as context fill. makeAcpTokenUsageEvent maps occupancy into the canonical runtime event (positive used tokens only, clamped to max).

GrokAdapter dedupes snapshots, seeds max window from session setup availableModels[]._meta.totalContextTokens, refreshes on model change, and skips updates for interrupted turns. CursorAdapter handles the same UsageUpdated branch for exhaustiveness. The mock ACP agent can simulate occupancy via T3_ACP_EMIT_CONTEXT_USAGE.

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

Note

Add context-window usage events for Grok ACP adapter

  • Adds a canonical makeAcpTokenUsageEvent factory in AcpCoreRuntimeEvents.ts that converts positive usage measurements into thread.token-usage.updated events with rounded, maximum-bounded token counts
  • Extends ACP session-update parsing in AcpRuntimeModel.ts to project usage_update notifications and totalTokens metadata into UsageUpdated parsed events
  • Builds a model-to-context-window map from Grok session setup metadata in GrokAcpSupport.ts, resolving window sizes by exact model ID or base model ID
  • makeGrokAdapter in GrokAdapter.ts now processes UsageUpdated notifications, deduplicates snapshots, refreshes the cached window on model change, and emits token-usage events using the event-provided or model-derived window (default 500,000)
  • Risk: parseSessionUpdateEvent now emits UsageUpdated for any session-update containing totalTokens metadata; adapters or consumers that did not expect this event type on session updates need to handle it

Macroscope summarized a2087c9.

Grok ACP does not emit usage_update. Occupancy lives on session/update _meta.totalTokens. Map that onto the existing thread.token-usage.updated path so ContextWindowMeter can render.

Do not use prompt-response usage.totalTokens; that is billed API tokens, not context fill.

Closes pingdotgg#8382
@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 Sep 2, 2026
Comment thread apps/server/src/provider/Layers/GrokAdapter.ts
Comment thread apps/server/src/provider/Layers/GrokAdapter.ts Outdated

@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 6af161d. Configure here.

Comment thread apps/server/src/provider/Layers/GrokAdapter.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This change adds a cross-cutting production pipeline that turns ACP session metadata into persisted context-window updates for Grok and Cursor, including a new 500,000-token fallback displayed by the composer meter. A cancellation race can also allow stale usage to overwrite the meter, so the runtime behavior and fallback semantics need human review.

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.

Keep lastKnownMaxTokens in sync when sendTurn switches models. Dedup occupancy snapshots on used+emitted max so a later window size is not dropped.

if (event._tag === "UsageUpdated") {
const usageTurnId = resolveNotificationTurnId(ctx);
if (usageTurnId !== undefined && ctx.interruptedTurnIds.has(usageTurnId)) {

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.

🟡 Medium Layers/GrokAdapter.ts:1374

A queued UsageUpdated from a cancelled prompt is emitted as thread.token-usage.updated after interruptTurn clears activeTurnId, so stale usage overwrites the composer context meter. Treat usageTurnId === undefined as stale here, in addition to checking interruptedTurnIds.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/provider/Layers/GrokAdapter.ts around line 1374:

A queued `UsageUpdated` from a cancelled prompt is emitted as `thread.token-usage.updated` after `interruptTurn` clears `activeTurnId`, so stale usage overwrites the composer context meter. Treat `usageTurnId === undefined` as stale here, in addition to checking `interruptedTurnIds`.

@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 model-window selection cases from #5405 at 8a491a6d9f while finishing this meter. Its GrokAcpSupport tests cover separate 500,000 and 128,000 token model windows, an absent bound model with a known setup model, a sole known window, and no matching model among multiple windows. Retain those cases with occupancy-only input. Do not copy the prompt-response billed-token mapping. This note records the cases, not a test port or test run.

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

Labels

size:L 100-499 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.

[Bug]: Grok threads do not show context-window usage in the composer

2 participants