feat(agents): live token meter — accumulate per-task usage across both providers #999
No reviewers
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
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!999
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/952"
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?
Summary
UsageDeltaEventextended with optionaldeltaCacheRead?/deltaCacheCreation?fields so both providers surface cache token breakdownsUsageDeltaEventalongside eachAssistantTurn(synthesized fromassistant.message.usage); the Cursor adapter already emitted these fromtoken-deltaupdatesevent-log.tsaccumulatesusage_deltaevents with a 250 ms coalesced SSE broadcast per task — avoids spamming clients on chatty turns; also patches the liveTaskRecord.input_tokens/output_tokens/cache_*_tokensfields so the list view shows fresh counts before the terminalresultrefetchuseTaskSSEhandlesusage_deltaSSE envelopes separately (nots/summaryfields), patching React Query cache so<TokenMeter>re-renders live without a full history refetch<TokenMeter>component — compact inline variant for task list rows + board panel; full breakdown variant for task detail header; colour-coded: dim → warning → error at 50 % / 90 % of configurable soft budget (default 200 k tokens)AssistantTurnusage extraction; event-log accumulation + live record update; cursor-adapter no-cache-fields assertionAlso fixes a pre-existing flaky test (
tool-call-widgets.test.tsx) where 18 concurrentReact.lazywidget loads routinely exceeded the 1 000 mswaitForbudget on loaded CI runners.Test plan
just qaclean (typecheck + Biome format + Biome lint + tests)apps/server/src/infrastructure/event-log-delta.test.ts— accumulation + 250 ms coalesce + live record updateapps/server/src/infrastructure/agent/sdk-adapter.test.ts—AssistantTurnusage +UsageDeltaEventfieldsapps/server/src/infrastructure/agent/cursor-sdk-delta.test.ts—token-deltaemits no cache fieldsCloses #952
18 lazy-loaded widgets running concurrently can exceed the default 1 000 ms waitFor budget on a loaded CI machine. Pass { timeout: 5000 } to the two waitFor calls in the dispatcher describe block so they have room to breathe without inflating the budget for unrelated tests. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>ci: Run #3270 is red (
failure). Logs not surfaced by the MCP but the job status is definitive — must be green before merge.test-gap: AC #952 requires "Adapter tests for both providers asserting
UsageDeltaEventcadence + correctness." Onlysdk-adapter.test.tsis updated. No test for the cursor adapter confirmingdeltaInput/deltaOutputstill emit correctly (and thatdeltaCacheRead/deltaCacheCreationare absent, as expected for cursor's rolling counter). Add a cursor adapter test even if it's a simple shape assertion.Implementation looks correct otherwise — coalescing logic, timer cleanup on result, live record mutation, SSE patch in
useTaskSSE, and<TokenMeter>component all look solid.Added
cursor-sdk-delta.test.tsassertion thatdeltaCacheReadanddeltaCacheCreationareundefinedon thetoken-deltapath. New CI run triggered.failureon head5c279618. Logs: https://forge.jacquin.app/charles/claude-hooks/actions/runs/1753 — fix the failing job and re-push.5c279618c8da3cb85583qa-1is red on headda3cb85583(run #3287 / UI: https://forge.jacquin.app/charles/claude-hooks/actions/runs/1765). Log content not retrievable via API — check the UI to see which step failed (Typecheck / Lint / Fmt / Test).qaalso failed at "Set up job" (0 s) which is likely a runner flake, butqa-1ran for 34 s before failing — that's a content failure, not infra. Fix whateverjust qasurfaces locally and push.Round-2 test-gap (cursor adapter) is addressed — no further code issues.
b40684b673a3c69dbb95