agents: live token meter — accumulate per-task usage across both providers #952
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Blocks
Depends on
#953 agents: per-model rate table + runner cost computation (cursor parity with claude-code)
charles/claude-hooks
#967 dashboard: two-meter run header — live context-window % + cumulative $ cost
charles/claude-hooks
#969 dashboard: per-tool token attribution chart in run header tooltip
charles/claude-hooks
Reference
charles/claude-hooks#952
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
User story
As an operator running expensive agents under a hard monthly budget cap (€200 extra-usage), I want a live per-task token meter that ticks up as the agent works, regardless of provider, so I can interrupt runaway tasks before they burn the budget.
Context
Today every observability tile reads zero for cursor runs because
cursor-sdk-adapter.tshardcodesusage: emptyUsage()andtotalCostUsd: 0. Claude Code surfaces token counts only on the terminalresultevent (no live ticker). The user has explicitly stripped[1m]everywhere because of past budget overrun (per global memoryfeedback_one_m_context.md) — token visibility is load-bearing for cost control, not just UI polish.This issue assumes the foundation issue (cursor
InteractionUpdatedeltas —usage_deltaevent added to the port) has landed, or implements the minimum amount of that scaffolding needed for the meter to work.Acceptance criteria
Port
UsageDeltaEvent { type: "usage_delta", sessionId, deltaInput, deltaOutput, deltaCacheRead?, deltaCacheCreation? }. Emitted incrementally as the agent runs.Cursor adapter
TokenDeltaUpdatevia the interaction listener. Translate toUsageDeltaEvent.Claude adapter
UsageDeltaEventper assistant turn fromassistant.message.usage(post-turn deltas; not as fine-grained as cursor but still live).Runner / event log
TaskRecord(record.usage = { input, output, cache_read, cache_creation }); update on eachusage_delta.usage_deltaSSE envelope at most every 250 ms per task to avoid spamming the wire on rapid streams.task_history(already wired forresult.totalUsage); this issue keeps that invariant — the meter is a display of in-progress state, the row is still authoritative.Frontend
<TokenMeter task={...} />component. Renders inline tokens-in / tokens-out, optionally cache-read / cache-creation. Updates live via SSE.Tests
UsageDeltaEventcadence + correctness.result.totalUsage.Out of scope
References
InteractionUpdatedelta issuedelta-types.d.tsTokenDeltaUpdatefeedback_one_m_context.md🤖 Auto-assigned to code-lead (heuristic: area:agents → code-lead (architecture-touching)). Reply
/unassignto reroute.🧹 janitor: this ticket has been idle-assigned since 2026-05-08T15:36:16.000Z. Re-dispatching.