feat(dashboard): LLM stats answer who/what spends tokens — member scope chips and spend breakdowns
Nightly Build / build (push) Successful in 4m27s

The stats section was designed single-user: four global charts, no
attribution. Request metadata rows now carry the session's source and
the frame's agent_id/depth (additive ensure_column), denormalized at log
time by the LoggingModel from the owner's pool — off the turn's hot
path, degrading to NULLs, never to a lost row.

The dashboard gains member scope chips filtering every chart, and a
breakdown row splitting the range's billed tokens by member, kind
(chat / sub-agents / cron / system agents / channels), agent, model and
provider — a sub-agent's spend is attributed to the sub-agent itself.
Rows predating the columns group under 'older data'.
This commit is contained in:
Daniele
2026-09-10 14:03:22 +01:00
parent 7e3fa3caad
commit 0958264c6f
14 changed files with 550 additions and 99 deletions
+19 -1
View File
@@ -312,6 +312,24 @@ dashboard-page {
color: #fff;
}
/* Scope chips (member filter) — same pill look as the range buttons. */
.home-stats-scope {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin: -0.25rem 0 1rem;
}
/* Subsection label above the breakdown grid. */
.home-stats-sub {
font-size: 0.78rem;
font-weight: 600;
color: var(--bs-secondary-color);
text-transform: uppercase;
letter-spacing: 0.04em;
margin: 0.25rem 0 0.75rem;
}
.home-stats-loading,
.home-stats-empty {
display: flex;
@@ -325,7 +343,7 @@ dashboard-page {
.home-stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 1rem;
margin-bottom: 2rem;
}