Every LLM call, Arena-mode comparison, and meeting-transcript run burns tokens that today go unmeasured. Platform's `meter` service (`evalops/platform/internal/meter/`) ingests wide events with `RecordUsage` for exactly this — per `team_id` / `agent_id` / `surface` with input/output/cache tokens and total cost in USD.
Ask
When `KESTREL_METER_BASE` + `KESTREL_METER_TOKEN` are set, fire a `RecordUsage` (or `RecordUsageBatch`) call on every model round-trip with:
```
{
"team_id": config.teamId,
"agent_id": "kestrel",
"surface": "desktop",
"event_type": "chat|arena|meeting_transcribe|journal",
"model": ,
"provider": "openrouter",
"input_tokens": ,
"output_tokens": ,
"total_cost_usd": ,
"metadata": { "arena_variant": , "meeting_id": }
}
```
Related
- This unblocks a console attribution panel (`evalops/console#15`) showing cost-by-agent including kestrel.
- evalops/maestro already does meter-event mirroring via `meter-service-client.js` — use that as the reference.
Scope
~1 day. Add the client, wire on every call site, no UX change.
Every LLM call, Arena-mode comparison, and meeting-transcript run burns tokens that today go unmeasured. Platform's `meter` service (`evalops/platform/internal/meter/`) ingests wide events with `RecordUsage` for exactly this — per `team_id` / `agent_id` / `surface` with input/output/cache tokens and total cost in USD.
Ask
When `KESTREL_METER_BASE` + `KESTREL_METER_TOKEN` are set, fire a `RecordUsage` (or `RecordUsageBatch`) call on every model round-trip with:
```
{
"team_id": config.teamId,
"agent_id": "kestrel",
"surface": "desktop",
"event_type": "chat|arena|meeting_transcribe|journal",
"model": ,
"provider": "openrouter",
"input_tokens": ,
"output_tokens": ,
"total_cost_usd": ,
"metadata": { "arena_variant": , "meeting_id": }
}
```
Related
Scope
~1 day. Add the client, wire on every call site, no UX change.