A team's members, quota and spend were on three pages that linked to each other. They are three tabs of one page now, each at its old address, and choosing anything in the tree opens its limits, capacity and use beside it, editable in place. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
86 lines
3.8 KiB
HTML
86 lines
3.8 KiB
HTML
{{/* The usage tab of the people page. */}}
|
|
{{define "usage_body"}}
|
|
|
|
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
|
|
|
|
{{/* One row of controls above the charts, which is where a reader looks for
|
|
them. Links rather than a script: the choice is in the URL, so a view worth
|
|
coming back to can be bookmarked or pasted to somebody else. */}}
|
|
<div class="filters">
|
|
<span class="filter-label">Group by</span>
|
|
{{range .Groups}}<a class="chip{{if .Selected}} on{{end}}"
|
|
href="/admin/usage?by={{.Key}}&window={{$.Window}}">{{.Label}}</a>{{end}}
|
|
<span class="filter-label">Window</span>
|
|
{{range .Windows}}<a class="chip{{if .Selected}} on{{end}}"
|
|
href="/admin/usage?by={{$.By}}&window={{.Key}}">{{.Label}}</a>{{end}}
|
|
</div>
|
|
|
|
<div class="chart-row">
|
|
{{template "tschart" dict "t" .Requests "title" "Requests"
|
|
"note" "Requests served in each slice, counted where the key belongs now rather than where it was at the time."}}
|
|
{{template "tschart" dict "t" .Tokens "title" "Tokens"
|
|
"note" "Prompt and completion together, which is the figure a person recognises as what they consumed."}}
|
|
</div>
|
|
|
|
<div class="chart-row">
|
|
{{if .Priced}}
|
|
{{template "tschart" dict "t" .Spend "title" "Spend"
|
|
"note" "In whole units, the same ones a budget is written in."}}
|
|
{{else}}
|
|
{{/* Said rather than drawn. A spend chart flat along the bottom reads as a
|
|
quiet month, and this is not that. */}}
|
|
<div class="chart-wrap">
|
|
<h3 class="chart-title">Spend</h3>
|
|
<p class="empty">No model has a price, so every request costs zero and this
|
|
chart would be a flat line however busy the cluster is. Set prices in the
|
|
<code>pricing</code> block of the server configuration.</p>
|
|
</div>
|
|
{{end}}
|
|
</div>
|
|
|
|
{{if .Rows}}
|
|
<table class="rows">
|
|
<tr><th>Group</th><th class="num">Requests</th><th class="num">Tokens</th><th class="num">Spend</th><th class="num">Errors</th></tr>
|
|
{{range .Rows}}
|
|
<tr>
|
|
<td>{{.Name}}</td>
|
|
<td class="num">{{compact .Requests}}</td>
|
|
<td class="num">{{compact .Tokens}}</td>
|
|
<td class="num">{{.Spend}}</td>
|
|
<td class="num">{{if .Errors}}{{.Errors}}{{else}}—{{end}}</td>
|
|
</tr>
|
|
{{end}}
|
|
</table>
|
|
{{else}}
|
|
<p class="empty">Nothing recorded in this window.</p>
|
|
{{end}}
|
|
|
|
{{with .GPUHours}}
|
|
<h2>GPU time, by owner</h2>
|
|
{{/* What each owner's models held, whether or not anybody asked them
|
|
anything: a model kept loaded holds its cards all the same, and that is
|
|
the time a GPU quota is about. */}}
|
|
<div class="chart-row">
|
|
{{template "tschart" dict "t" $.GPUHeld "title" "GPUs held, by owner" "note" "The cards held by the replicas of each owner's models: models whose owner is a part of the quota tree."}}
|
|
</div>
|
|
<table class="rows">
|
|
<tr><th>Owner</th><th class="num">GPU-hours</th><th class="num">Held now</th></tr>
|
|
{{range .}}<tr><td>{{.Owner}}</td><td class="num">{{printf "%.1f" .Hours}}</td><td class="num">{{printf "%.0f" .Now}}</td></tr>{{end}}
|
|
</table>
|
|
<p class="note">From the metrics store, which keeps its history for as long as it is set to (fifteen days by default); a model with no owner is counted under “no owner”.</p>
|
|
{{end}}
|
|
|
|
{{/* The charts fold their tail; the table does not. Both are here because they
|
|
answer different questions, and the one that is easy to get wrong is
|
|
thinking the four coloured lines are all of it. */}}
|
|
<p class="note">The charts draw the four busiest groups by total and sum the
|
|
rest into “other”, so they always add up to the whole cluster. The table below
|
|
is every group, in the same order.</p>
|
|
|
|
<p class="note">A person is not a level of the quota tree — one person holds
|
|
keys in several projects — so grouping by person crosses the tree rather than
|
|
naming a level of it. Quotas are written on the other three, on the
|
|
<a href="/admin/quotas">Limits</a> tab.</p>
|
|
|
|
{{end}}
|