Files
llmgw/internal/web/templates/org.html
T
Ilker ManapandClaude Opus 5.5 02fa639657 Open the mirror's registry on what is current, not an empty search box
The mirror page lists Hugging Face's trending models without anything
typed, with views for what is new this month and what is most
downloaded, filters for task and size, and each repository's parameter
count, architecture, context length and age from one registry call.
"Only what these nodes can run" is on by default and leaves out
architectures the nodes' llama.cpp cannot load, and adapters, saying how
many it hid. Listings are remembered for ten minutes.

The stylesheet is now linked by a hash of its content. It is cached for
a day, so under a fixed name a deploy's new styles reached people a day
after its markup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-28 21:56:58 +02:00

113 lines
4.8 KiB
HTML

{{define "org"}}<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{.Org.Name}} · llmgw</title><link rel="stylesheet" href="{{stylesheet}}">
</head><body><div class="wrap">
<header>
<h1>{{.Org.Name}}</h1>
<p class="sub">{{.People}} {{if eq .People 1}}person{{else}}people{{end}} ·
use, members and limits across the organization</p>
{{template "nav" .Nav}}
</header>
{{if gt (len .Orgs) 1}}
<div class="filters">
<span class="filter-label">Organization</span>
{{range .Orgs}}<a class="chip{{if eq .ID $.Org.ID}} on{{end}}" href="/org/{{.ID}}">{{.Name}}</a>{{end}}
</div>
{{end}}
{{if .Error}}<p class="error">{{.Error}}</p>{{end}}
<h2>Use</h2>
<div class="filters">
<span class="filter-label">Group by</span>
{{range .Groups}}<a class="chip{{if .Selected}} on{{end}}"
href="/org/{{$.Org.ID}}?by={{.Key}}&amp;window={{$.Window}}">{{.Label}}</a>{{end}}
<span class="filter-label">Window</span>
{{range .Windows}}<a class="chip{{if .Selected}} on{{end}}"
href="/org/{{$.Org.ID}}?by={{$.By}}&amp;window={{.Key}}">{{.Label}}</a>{{end}}
</div>
<div class="chart-row">
{{template "tschart" dict "t" .Requests "title" "Requests"
"note" "Requests made in this organization's projects."}}
{{template "tschart" dict "t" .Tokens "title" "Tokens"
"note" "Prompt and completion together."}}
</div>
{{if .Priced}}
<div class="chart-row">
{{template "tschart" dict "t" .Spend "title" "Spend" "note" "In whole units, the ones a budget is written in."}}
</div>
{{end}}
{{if .Rows}}
<table class="compact">
<tr><th>{{if eq .By "user"}}Person{{else if eq .By "project"}}Project{{else}}Team{{end}}</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 used in this window.</p>{{end}}
<p class="note">Only what was spent in this organization's projects. What its
people do elsewhere — in another organization, or on their own — is not shown.</p>
<h2>Teams, projects and limits</h2>
{{if .Quotas}}
<table class="quota-tree">
<tr><th>Where</th><th class="num">Requests/min</th><th class="num">Tokens/min</th>
<th class="num">Budget</th><th>Spent · 30 days</th></tr>
{{range .Quotas}}
<tr class="q-depth-{{.Indent}}">
<td class="q-where"><span class="q-name">{{.Path}}</span> <span class="q-kind">{{.Scope}}</span>
{{if .Models}}<div class="q-sub">only <code>{{.Models}}</code></div>{{end}}
{{if .Shadowed}}<div class="q-sub q-warn">{{.Shadowed}}</div>{{end}}</td>
<td class="num">{{template "quota-value" dict "Own" .RPM "Up" .RPMUp "From" .RPMFrom}}</td>
<td class="num">{{template "quota-value" dict "Own" .TPM "Up" .TPMUp "From" .TPMFrom}}</td>
<td class="num">{{if .Budget}}{{.Budget}}{{if .Period}}<span class="q-per">/{{.Period}}</span>{{end}}
{{else}}{{template "quota-value" dict "Own" "" "Up" .BudgetUp "From" .BudgetFrom}}{{end}}</td>
<td class="q-spent"><span class="q-spend">{{.Spend}}</span>
{{if .HasPct}}<span class="q-meter{{if ge .Percent 90}} hot{{end}}"><i style="width:{{pct .Percent 100}}%"></i></span>
<span class="q-pct">{{.Percent}}%</span>{{end}}</td>
</tr>
{{end}}
</table>
<p class="note">Limits are set by the cluster's administrators.</p>
{{end}}
<h2>Members</h2>
{{if .Members}}
<table class="compact">
<tr><th>Person</th><th>Member of</th><th>State</th></tr>
{{range .Members}}<tr>
<td>{{.Email}}</td>
<td>{{range .Places}}<span class="chip-m">{{.Where}}{{if eq .Role "manager"}} <b class="chip-role">manager</b>{{end}}</span>{{end}}</td>
<td class="state state-{{.State}}">{{.State}}</td>
</tr>{{end}}
</table>
{{else}}<p class="empty">Nobody is a member yet.</p>{{end}}
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span></footer>
</div></body></html>{{end}}
{{define "org-none"}}<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Organizations · llmgw</title><link rel="stylesheet" href="{{stylesheet}}">
</head><body><div class="wrap">
<header>
<h1>Organizations</h1>
<p class="sub">There are none on this cluster</p>
{{template "nav" .Nav}}
</header>
<p>Everyone uses the gateway on their own, under their personal quota. An
organization, once there is one, gets a page here for its managers: its use by
team, project and person, its limits, and its members.</p>
<p><a href="/admin/users">Create one on the people page</a>, then make someone
its manager with the star on their membership.</p>
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span></footer>
</div></body></html>{{end}}