{{/* People, their limits and their use: one page in three tabs, because all three are about the same tree. Each tab keeps its old address. Forms and links work as plain navigation; htmx, when it loads, swaps only #people, so a change does not jump the page. */}} {{define "admin_people"}} People · llmgw

People

Organizations, teams, projects and the people in them: what each may use, and what it used

{{template "nav" .Nav}}
{{if .Users}}
{{with .Detail}}{{end}}
{{template "people_body" .Users}}
{{else if .Quotas}}{{template "limits_body" .Quotas}} {{else if .Usage}}{{template "usage_body" .Usage}} {{end}}
{{end}} {{/* One branch or person: its limits, its capacity and its use, together. */}} {{define "people-detail"}}{{$d := .}}{{$sel := printf "%s:%s" .Kind .ID}}
{{if eq (printf "%s" .Kind) "user"}}person{{else}}{{.Kind}}{{end}}

{{.Name}}

{{if and .Path (ne .Path .Name)}}

{{.Path}}

{{end}} ×
{{with .Memberships}}

In {{range $i, $m := .}}{{if $i}}, {{end}}{{$m.Path}}{{end}}

{{else}}{{if eq (printf "%s" $d.Kind) "user"}}

On their own: in no organization, team or project.

{{end}}{{end}} {{if or .Limits .Person}}

Limits

{{if not .BudgetsBind}}

No model has a price, so budgets stay at zero; rate and token limits apply.

{{end}} {{with .Limits}}
Requests/min
{{template "quota-value" dict "Own" .RPM "Up" .RPMUp "From" .RPMFrom}}
Tokens/min
{{template "quota-value" dict "Own" .TPM "Up" .TPMUp "From" .TPMFrom}}
Budget
{{if .Budget}}{{.Budget}}{{if .Period}}/{{.Period}}{{end}}{{else}}{{template "quota-value" dict "Own" "" "Up" .BudgetUp "From" .BudgetFrom}}{{end}}
Spent, {{$d.QuotaWindow}}
{{.Spend}}{{if .HasPct}} {{.Percent}}%{{end}}
Models
{{if .Models}}only {{.Models}}{{else if .ModelsFrom}}limited by {{.ModelsFrom}}{{else}}every model{{end}}
{{if .Member}}
Each member
{{.Member}}
{{end}}
{{if .Shadowed}}

{{.Shadowed}}

{{end}}
{{if .HasAny}}change{{else}}set{{end}} limits {{template "quota-form" (dict "Scope" (printf "%s" .Scope) "ID" .ID "CSRF" $d.CSRF "Sel" $sel "F" (dict "RPM" .RPM "TPM" .TPM "Budget" .Budget "Period" .Period "Models" .Models "HasAny" .HasAny) "Title" (printf "Quota for %s" .Crumb) "Note" "Shared by everything beneath it.")}}
limit each member {{template "quota-form" (dict "Scope" (printf "%s-member" .Scope) "ID" .ID "F" .MemberRaw "CSRF" $d.CSRF "Sel" $sel "Title" (printf "Each member of %s, separately" .Crumb) "Note" "Every member gets this much here, counted apart from the others.")}}
{{end}} {{with .Person}}
Requests/min
{{or .RPM "—"}}
Tokens/min
{{or .TPM "—"}}
Budget
{{if .Budget}}{{.Budget}}{{if .Period}}/{{.Period}}{{end}}{{else}}—{{end}}
Spent, {{$d.QuotaWindow}}
{{.Spend}}{{if .HasPct}} {{.Percent}}%{{end}}
Models
{{if .Models}}only {{.Models}}{{else}}every model{{end}}
{{if .HasAny}}change{{else}}set{{end}} limits {{template "quota-form" (dict "Scope" "user" "ID" .ID "CSRF" $d.CSRF "Sel" $sel "F" (dict "RPM" .RPM "TPM" .TPM "Budget" .Budget "Period" .Period "Models" .Models "HasAny" .HasAny) "Title" (printf "%s, everywhere" .Email) "Note" "Across every key this person holds, every project they use and the chat page.")}}
{{end}} {{end}} {{if .HasCapacity}}

Capacity

{{with .Capacity}}
GPUs
{{or .GPUs "—"}}
Cores
{{or .Cores "—"}}
Memory GB
{{or .Memory "—"}}

Held of guaranteed (at most the limit). change

{{else}}

No capacity quota: its models share the cluster by their class alone. set one

{{end}} {{end}} {{if .HasUsage}}

Use, {{.UsageWindow}}

{{if .Totals.Name}}

{{compact .Totals.Requests}} requests · {{compact .Totals.Tokens}} tokens{{if .Priced}} · {{.Totals.Spend}} spent{{end}}{{if .Totals.Errors}} · {{.Totals.Errors}} errors{{end}}

{{template "tschart" dict "t" .Requests "title" "Requests" "note" ""}} {{template "tschart" dict "t" .Tokens "title" "Tokens" "note" ""}} {{if .Priced}}{{template "tschart" dict "t" .Spend "title" "Spend" "note" ""}}{{end}} {{else}}

Nothing used in this window.

{{end}} {{end}} {{end}}