mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-05 17:40:11 +02:00
* feat(issues): show per-run token usage on the execution log (MUL-5762)
The execution log already lists every agent run on an issue; it just
never said what any of them cost. task_usage has held per-task token
counts since migration 032 — nothing surfaced them per run.
Three placements, one data source:
- Execution-log header carries the issue total ("2.1M · $4.92") and
opens the breakdown.
- Each row carries its own token figure. This takes the slot the
relative timestamp held: the sidebar is 288px and a third column
would come out of the trigger text, which is what people scan. The
list is sorted newest-first, so ordinal recency is already free; the
timestamp moves into the row tooltip alongside duration and model,
neither of which was surfaced there before.
- The transcript dialog gets the same figure in its header, with the
input/output/cache split in the run-info popover.
Backend: ListIssueTaskUsage returns per-(task, provider, model) rows in
one query, joined onto the existing task-runs response. The model
dimension stays on the wire because cost is priced client-side per
model — a row that collapsed two models cannot be priced at all.
Cost reuses estimateCost from the runtime usage page, so the issue and
the workspace never disagree; the new summarizeTaskUsage helpers live
next to it rather than starting a second cost formula.
No usage recorded stays distinguishable from zero end to end — omitted
on the wire, undefined in the schema, null from the summarizer, an em
dash in the UI. A run from before usage reporting was not free.
Removes the standalone "Token usage" sidebar section: it showed the
same issue totals minus the cost and minus any way to attribute them,
and every field it had is in the dialog. The /api/issues/:id/usage
endpoint it read stays — the CLI's `issue usage` still uses it.
Co-authored-by: multica-agent <github@multica.ai>
* fix(issues): address review on per-run token usage (MUL-5762)
Three findings from @Emacs, all confirmed against the code:
1. Drop the token figure from active rows. The daemon reports usage
once, after `runner.run` returns (internal/daemon/daemon.go), and
ReportTaskUsage publishes no realtime event — so a running task has
no usage to show and would not learn of it mid-run if it did. The
branch was only ever exercised by a hand-written fixture, which is a
test asserting a scenario production cannot produce. The row keeps
its timer; restore the figure in the same change that adds
incremental reporting + cache invalidation.
2. Subscribe the usage surfaces to the custom-pricing store. estimateCost
reads custom rates imperatively via getCustomPricing(), so nothing
re-rendered these after a saved rate change — the header total, the
dialog's totals and per-run costs, the cost-by-agent split, and the
"unmapped model" notice all kept quoting the old price until the task
list happened to refetch. Same subscription the runtime usage page
already carries, plus the snapshot in every memo that prices usage.
Regression test pinned: it fails without the subscription.
3. Give the dialog's status glyph an sr-only label. TaskStatusIcon is
aria-hidden, so a screen reader could not tell a failed run from a
completed one — the execution log rows already pair the two.
Co-authored-by: multica-agent <github@multica.ai>
---------
Co-authored-by: Lambda <lambda@multica.ai>
Co-authored-by: multica-agent <github@multica.ai>