feat(web,desktop): a turn's card lists what it wrote to the prompt cache, where the provider said

Merged
DA
7d ago
+180-26

What

This is the follow-up to #2155. The "Worked for" card now shows Cache write when the turn's provider reported it, so it matches the four token rows in Conductor's card (Input, Output, Cache read, Cache write).

eve's step.completed already reports cacheWriteTokens, but BrainRunUsage dropped it before the turn row was written. It is now recorded and shown:

  • ModelUsage (@sidecar/runtime) and BrainRunUsage (@sidecar/brain) gain an optional cacheWriteTokens. addModelUsage sums it, but only once some step's provider has reported it. Anthropic reports it; OpenAI does not, so OpenAI turns never get a misleading "Cache write 0".
  • The relay maps eve's step cacheWriteTokens into the step's usage. The turn row's usage jsonb takes the new optional key (TurnUsageColumnSchema), so no migration is needed, and rows written before this change still read.
  • On the wire, turnTokensSchema gains an optional cacheWriteTokens. Goldens were regenerated with LUKE_UPDATE_FIXTURES=1; the only diff is that one optional key in the four schemas that carry turn tokens.
  • On the card, the provider's input count includes both cache reads and cache writes, so Input shows the remainder and the rows add up to what the model read and wrote. The Cache write row appears only when the field is present.
  • Pricing (Devin review): the catalog's input_cache_write price is now read into ModelPricing.cacheWriteUsd, and tokensCostUsd charges the cache-write share at that rate (or the input rate where none is listed), taking it out of the uncached input so nothing is priced twice. Before this PR those tokens were not recorded at all and were priced as plain input.

Tests

  • requests.test.ts: cache writes are absent until an answer reports them, then sum from there.
  • plan-work.test.ts: a step whose provider reported 150 cache-write tokens lands them on the planning turn's tokens and on a worker session's tokens, through the real relay, writer, and read.
  • turn-record.test.ts: a row with cache writes reports them; one without leaves them out.
  • coder-host-usage.test.ts: 1000 in / 400 cache read / 200 cache write / 100 out on Opus costs $0.00468. model-catalog.test.ts now expects the write price read from the catalog fixture.
  • working-time.test.ts: the hovered card lists Input 200 / Output 50 / Cache read 1,200 / Cache write 600 for input 2,000. Existing cards without the field still show three rows.

Screenshots (Chrome render of the real AgentTranscriptView, footer hovered)

LightDark
lightdark

Mac validation

CI could not verify the Mac UI: CI builds nothing for the Mac, and ./scripts/verify.sh was not run because this is a Linux cloud VM. LUKE-159 is the manual Mac pass. ./scripts/check.sh exits 0.

šŸ¤– Generated with Claude Code