The gap
ai_usage is written at exactly one choke point — runUserWorkersAi in lib/user-ai.ts (plus recordVoiceUsage for the key-proxy and recordPlatformUsage for Workers-AI). The coding Engine never passes through any of them. Claude Code / Codex / Grok run on the user's own machine, spending on their own subscription or key, and the platform records nothing.
Measured on the live ledger (30d, operator account):
| kind |
cost |
calls |
| chat |
$18.95 |
814 |
| voice |
$8.51 |
840 |
| overseer |
$7.45 |
326 |
| copilot |
$4.85 |
244 |
| coding |
$0.70 |
67 |
That coding row is only the cloud-side Pilot deciding what to do next. The Engine's own consumption — almost certainly the single largest item for anyone using Coder in earnest — is absent. So the Usage page reads $40.92 when real spend is materially higher, and there is no signal that anything is missing.
Why this matters beyond curiosity
The implementation path is already open
packages/browser-runner/src/coding/headless.ts parses Claude Code's stream-json and already handles the result event (line ~497) — it reads is_error/result/subtype and discards the usage and total_cost_usd fields on the same object. The data is flowing through today and being thrown away.
- In the
result case, capture usage (input/output/cache tokens) + total_cost_usd when present.
- Report it with the existing session event channel (
/coding/event) — no new transport, no relay change.
- Cloud side: ledger it as
kind:"engine", provider:"anthropic", with the CLI-reported cost — this is the one number that is not an estimate, since Claude Code computes it itself.
- Raw (non-Claude) engines emit no such event → record nothing rather than guess. Codex/Grok stay invisible until each exposes an equivalent; say so in the UI rather than implying zero.
Acceptance
Found while answering "what is $40.92 and is it real". Related: #45 (platform actuals), #56, #57, #68.
The gap
ai_usageis written at exactly one choke point —runUserWorkersAiinlib/user-ai.ts(plusrecordVoiceUsagefor the key-proxy andrecordPlatformUsagefor Workers-AI). The coding Engine never passes through any of them. Claude Code / Codex / Grok run on the user's own machine, spending on their own subscription or key, and the platform records nothing.Measured on the live ledger (30d, operator account):
That
codingrow is only the cloud-side Pilot deciding what to do next. The Engine's own consumption — almost certainly the single largest item for anyone using Coder in earnest — is absent. So the Usage page reads $40.92 when real spend is materially higher, and there is no signal that anything is missing.Why this matters beyond curiosity
The implementation path is already open
packages/browser-runner/src/coding/headless.tsparses Claude Code's stream-json and already handles theresultevent (line ~497) — it readsis_error/result/subtypeand discards theusageandtotal_cost_usdfields on the same object. The data is flowing through today and being thrown away.resultcase, captureusage(input/output/cache tokens) +total_cost_usdwhen present./coding/event) — no new transport, no relay change.kind:"engine",provider:"anthropic", with the CLI-reported cost — this is the one number that is not an estimate, since Claude Code computes it itself.Acceptance
claudeengine producesai_usagerows withkind:"engine".ai-pricing.ts.Found while answering "what is $40.92 and is it real". Related: #45 (platform actuals), #56, #57, #68.