Files
llmgw/internal/web/templates/about.html
T
Ilker ManapandClaude Opus 5.5 b6478e24b7
CI / test (push) Failing after 6m43s
An introduction for decision makers, linked from the website
docs/llmgw-intro.pdf is a 21-slide presentation: what llmgw adds on
premise, screens from a running cluster, and how it compares with
LiteLLM, Kong AI Gateway, Agent Router, llm-d, NVIDIA Dynamo and vLLM
production-stack from their own documentation. The /about page and the
published site link to it in the repository, so the binary does not
carry it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:36:47 +01:00

342 lines
19 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{{define "about"}}{{if not .Site}}<!doctype html>
<html lang="{{lang}}"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="{{t "about.meta.description"}}">
{{end}}<title>llmgw</title>
{{template "sitestyle" .}}
{{if not .Site}}</head><body>{{end}}
<div class="wrap">
<header class="bar">
<a class="mark" href="#top" aria-label="{{t "about.home_label"}}">
<svg width="26" height="26" viewBox="0 0 26 26" aria-hidden="true">
<rect x="1" y="1" width="24" height="24" rx="6" fill="none" stroke="currentColor" stroke-width="2"/>
<path d="M7 9h12M7 13h12M7 17h12" stroke="var(--fiber)" stroke-width="2" stroke-linecap="round"/>
</svg>
llmgw
</a>
<nav aria-label="{{t "about.nav.label"}}">
<a href="#what">{{t "about.nav.what"}}</a>
<a href="#fabrics">{{t "about.nav.fabrics"}}</a>
<a href="#install">{{t "about.nav.install"}}</a>
<a href="#proxy">{{t "about.nav.proxy"}}</a>
<a href="#download">{{t "about.nav.download"}}</a>
<a href="{{.DeckURL}}" type="application/pdf">{{t "about.nav.deck"}}</a>
<a href="https://gitea.mynodes.xyz/ilker/llmgw">{{t "about.nav.source"}}</a>
{{if not .Site}}<a href="/">{{t "about.nav.gateway"}}</a>{{end}}
</nav>
</header>
<div class="hero" id="top">
<div>
<p class="eyebrow">{{t "about.hero.eyebrow" .Version}}</p>
<h1 style="margin-top:14px">{{th "about.hero.title"}}</h1>
<p class="lede">{{t "about.hero.lede"}}</p>
<div class="cta">
<a class="btn" href="#download">{{t "about.hero.download"}}{{with .Release}} {{.}}{{end}}</a>
<a class="btn ghost" href="{{.InstallURL}}">{{t "about.hero.guide"}}</a>
<a class="btn ghost" href="{{.DeckURL}}" type="application/pdf">{{t "about.hero.deck"}}</a>
</div>
<div class="oneline" aria-label="{{t "about.hero.oneline_label"}}">
<code><span class="p">$ </span>sudo llmgw server init --admin you@example.com</code>
<button class="copy" style="position:static" data-copy="sudo llmgw server init --admin you@example.com" type="button">{{t "about.copy"}}</button>
</div>
</div>
<figure class="schem">
<svg viewBox="0 0 440 250" role="img" aria-labelledby="schem-t">
<title id="schem-t">{{t "about.schem.title"}}</title>
<!-- clients -->
<g>
<rect class="s-box" x="4" y="58" width="92" height="30" rx="6"/>
<text class="s-label" x="50" y="77" text-anchor="middle" translate="no">openai sdk</text>
<rect class="s-box" x="4" y="110" width="92" height="30" rx="6"/>
<text class="s-label" x="50" y="129" text-anchor="middle">{{t "about.schem.editor"}}</text>
<rect class="s-box" x="4" y="162" width="92" height="30" rx="6"/>
<text class="s-label" x="50" y="181" text-anchor="middle" translate="no">curl</text>
</g>
<path id="c1" class="s-link" d="M96 73 C130 73 130 118 160 118"/>
<path id="c2" class="s-link" d="M96 125 H160"/>
<path id="c3" class="s-link" d="M96 177 C130 177 130 132 160 132"/>
<!-- gateway -->
<rect class="s-gw" x="160" y="96" width="84" height="58" rx="8"/>
<text class="s-strong" x="202" y="122" text-anchor="middle">llmgw</text>
<text class="s-label" x="202" y="139" text-anchor="middle">:8080</text>
<path id="fa" class="s-link" d="M244 114 C272 114 272 62 300 62"/>
<path id="fb" class="s-link" d="M244 136 C272 136 272 188 300 188"/>
<!-- fabric a -->
<rect class="s-fab" x="300" y="14" width="136" height="98" rx="10"/>
<text class="s-label" x="312" y="32" translate="no">nvl72 · gb200</text>
<g transform="translate(312 42)">
<rect class="s-gpu-a" width="22" height="22" rx="3"/><rect class="s-gpu-a" x="28" width="22" height="22" rx="3"/>
<rect class="s-gpu-a" x="56" width="22" height="22" rx="3"/><rect class="s-gpu-a" x="84" width="22" height="22" rx="3"/>
<rect class="s-gpu-a" y="28" width="22" height="22" rx="3"/><rect class="s-gpu-a" x="28" y="28" width="22" height="22" rx="3"/>
<rect class="s-gpu-idle" x="56" y="28" width="22" height="22" rx="3"/><rect class="s-gpu-idle" x="84" y="28" width="22" height="22" rx="3"/>
</g>
<!-- fabric b -->
<rect class="s-fab" x="300" y="138" width="136" height="98" rx="10"/>
<text class="s-label" x="312" y="156" translate="no">ib-b · h100-80g</text>
<g transform="translate(312 166)">
<rect class="s-gpu-b" width="22" height="22" rx="3"/><rect class="s-gpu-b" x="28" width="22" height="22" rx="3"/>
<rect class="s-gpu-idle" x="56" width="22" height="22" rx="3"/><rect class="s-gpu-idle" x="84" width="22" height="22" rx="3"/>
<rect class="s-gpu-idle" y="28" width="22" height="22" rx="3"/><rect class="s-gpu-idle" x="28" y="28" width="22" height="22" rx="3"/>
<rect class="s-gpu-idle" x="56" y="28" width="22" height="22" rx="3"/><rect class="s-gpu-idle" x="84" y="28" width="22" height="22" rx="3"/>
</g>
<!-- requests in flight -->
<circle class="pulse" r="4"><animateMotion dur="2.4s" repeatCount="indefinite"><mpath href="#c1"/></animateMotion></circle>
<circle class="pulse" r="4"><animateMotion dur="2.4s" begin="0.8s" repeatCount="indefinite"><mpath href="#c2"/></animateMotion></circle>
<circle class="pulse" r="4"><animateMotion dur="2.4s" begin="1.6s" repeatCount="indefinite"><mpath href="#c3"/></animateMotion></circle>
<circle class="pulse" r="4"><animateMotion dur="2.4s" begin="1.2s" repeatCount="indefinite"><mpath href="#fa"/></animateMotion></circle>
<circle class="pulse b" r="4"><animateMotion dur="2.4s" begin="2s" repeatCount="indefinite"><mpath href="#fb"/></animateMotion></circle>
</svg>
<figcaption>{{t "about.schem.caption"}}</figcaption>
</figure>
</div>
<section id="what">
<div class="sec-head">
<div>
<h2>{{t "about.what.title"}}</h2>
<p class="intro">{{t "about.what.intro"}}</p>
</div>
<div class="facts">
<div class="fact"><h3>{{t "about.what.api.title"}}</h3>
<p>{{th "about.what.api.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.placement.title"}}</h3>
<p>{{t "about.what.placement.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.ondemand.title"}}</h3>
<p>{{t "about.what.ondemand.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.keys.title"}}</h3>
<p>{{t "about.what.keys.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.editors.title"}}</h3>
<p>{{t "about.what.editors.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.chat.title"}}</h3>
<p>{{t "about.what.chat.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.mirror.title"}}</h3>
<p>{{t "about.what.mirror.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.engines.title"}}</h3>
<p>{{t "about.what.engines.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.upgrades.title"}}</h3>
<p>{{t "about.what.upgrades.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.dashboard.title"}}</h3>
<p>{{th "about.what.dashboard.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.knowledge.title"}}</h3>
<p>{{th "about.what.knowledge.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.guard.title"}}</h3>
<p>{{t "about.what.guard.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.signin.title"}}</h3>
<p>{{t "about.what.signin.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.ha.title"}}</h3>
<p>{{t "about.what.ha.text"}}</p></div>
<div class="fact"><h3>{{t "about.what.media.title"}}</h3>
<p>{{t "about.what.media.text"}}</p></div>
</div>
</div>
</section>
<section id="fabrics">
<div class="sec-head">
<div>
<h2>{{t "about.fabrics.title"}}</h2>
<p class="intro">{{t "about.fabrics.intro"}}</p>
<p class="intro"><a href="https://gitea.mynodes.xyz/ilker/llmgw/src/branch/main/docs/fabrics.md">{{t "about.fabrics.guide"}}</a></p>
</div>
<div class="fab-grid">
<div class="order" aria-label="{{t "about.fabrics.order_label"}}">
<div><b>1</b><h3>{{t "about.fabrics.nvlink.title"}}</h3><p>{{th "about.fabrics.nvlink.text"}}</p></div>
<div><b>2</b><h3>{{t "about.fabrics.ib.title"}}</h3><p>{{t "about.fabrics.ib.text"}}</p></div>
<div><b class="x">×</b><h3>{{t "about.fabrics.never.title"}}</h3><p>{{t "about.fabrics.never.text"}}</p></div>
</div>
<div>
<h3>{{t "about.fabrics.doctor"}}</h3>
<div class="term" aria-label="{{t "about.fabrics.doctor_label"}}"><pre>$ sudo llmgw doctor
<span class="fail">FAIL</span> nvlink this machine has NVSwitch but nvidia-fabricmanager is inactive
<span class="dim">→ systemctl enable --now nvidia-fabricmanager</span>
<span class="warn">WARN</span> fabric nvidia_peermem is not loaded: GPUDirect RDMA is off
<span class="dim">→ modprobe nvidia_peermem</span>
<span class="ok">OK</span> gpu 8 GPUs: 8× NVIDIA H100 80GB HBM3
<span class="ok">OK</span> nvlink NVLink groups: [0 1 2 3 4 5 6 7]
<span class="ok">OK</span> fabric mlx5_0/1 ACTIVE at 400 Gb/s (InfiniBand), subnet manager 0x248a07030030f0c0
<span class="ok">OK</span> fabric subnet managers: 0x…f0c0 (master, priority 15), 0x…f1d4 (standby, priority 14)
<span class="ok">OK</span> agent NCCL bootstraps over ens3 (10.1.0.21)</pre></div>
</div>
<ul class="watch">
<li><strong>{{t "about.fabrics.sm.title"}}</strong>{{t "about.fabrics.sm.text"}}</li>
<li><strong>{{t "about.fabrics.map.title"}}</strong>{{th "about.fabrics.map.text"}}</li>
<li><strong>{{t "about.fabrics.racks.title"}}</strong>{{th "about.fabrics.racks.text"}}</li>
<li><strong>{{t "about.fabrics.ports.title"}}</strong>{{t "about.fabrics.ports.text"}}</li>
</ul>
</div>
</div>
</section>
<section id="install">
<div class="sec-head">
<div>
<h2>{{t "about.install.title"}}</h2>
<p class="intro">{{t "about.install.intro"}}</p>
<p class="intro">{{th "about.install.guide" .InstallURL}}</p>
<p class="cta" style="margin-top:18px"><a class="btn" href="{{.InstallURL}}">{{t "about.install.cta"}} →</a></p>
</div>
<ol class="steps">
<li>
<h3>{{t "about.install.binary.title"}}</h3>
<p>{{t "about.install.binary.text"}}</p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>VERSION={{or .Release "vX.Y.Z"}}{{if not .Release}} <span class="c"># from the releases page</span>{{end}}
U=https://gitea.mynodes.xyz/ilker/llmgw/releases/download/$VERSION
curl -fsSLO $U/llmgw-$VERSION-linux-amd64
curl -fsSL $U/checksums.txt | sha256sum -c --ignore-missing
sudo install -m0755 llmgw-$VERSION-linux-amd64 /usr/local/bin/llmgw</code></pre></div>
</li>
<li>
<h3>{{t "about.install.server.title"}}</h3>
<p>{{th "about.install.server.text"}}</p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>sudo llmgw</code></pre></div>
<a href="{{.InstallURL}}#setup" style="text-decoration:none"><div class="term" aria-label="{{t "install.tty_label"}}"><pre translate="no" style="font-size:clamp(4px,.62vw,.5rem);line-height:1.25">{{.Still "setup-checks"}}</pre></div></a>
</li>
<li>
<h3>{{t "about.install.node.title"}}</h3>
<p>{{th "about.install.node.text"}}</p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>sudo llmgw node add ubuntu@10.0.0.21 --fabric ib-a:mlx5_0,mlx5_1</code></pre></div>
<div class="term" aria-label="{{t "about.install.node.output_label"}}"><pre>$ llmgw ctl nodes
NODE STATE GPUS MEM CLASSES FABRICS REPLICAS LAST SEEN
gpu01 <span class="ok">ready</span> 8/8 free 503G h100-80g ib-a 0 2s</pre></div>
</li>
<li>
<h3>{{t "about.install.model.title"}}</h3>
<p>{{th "about.install.model.text"}}</p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>curl https://llm.example.com/v1/chat/completions \
-H "Authorization: Bearer $LLMGW_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "coder", "messages": [{"role": "user", "content": "hello"}]}'</code></pre></div>
</li>
</ol>
</div>
</section>
<section id="proxy">
<div class="sec-head">
<div>
<h2>{{t "about.proxy.title"}}</h2>
<p class="intro">{{t "about.proxy.intro"}}</p>
<p class="intro">{{th "about.proxy.loopback"}}</p>
</div>
<div class="tabs">
<input type="radio" name="proxy" id="t-caddy" checked>
<input type="radio" name="proxy" id="t-nginx">
<div class="tablist" role="presentation" translate="no">
<label for="t-caddy">Caddy</label>
<label for="t-nginx">nginx</label>
</div>
<div class="panel p-caddy">
<p class="meta"><span>{{th "about.proxy.caddy"}}</span>
<a href="{{.Download}}/Caddyfile" translate="no">Caddyfile</a></p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>{{.Caddy}}</code></pre></div>
</div>
<div class="panel p-nginx">
<p class="meta"><span>{{th "about.proxy.nginx"}}</span>
<a href="{{.Download}}/nginx.conf" translate="no">nginx.conf</a></p>
<div class="code"><button class="copy" type="button">{{t "about.copy"}}</button><pre><code>{{.Nginx}}</code></pre></div>
</div>
<ul class="rules">
<li><strong>{{t "about.proxy.stream.title"}}</strong>{{t "about.proxy.stream.text"}}</li>
<li><strong>{{t "about.proxy.timeout.title"}}</strong>{{t "about.proxy.timeout.text"}}</li>
<li><strong>{{t "about.proxy.headers.title"}}</strong>{{th "about.proxy.headers.text"}}</li>
<li><strong>{{t "about.proxy.body.title"}}</strong>{{t "about.proxy.body.text"}}</li>
</ul>
</div>
</div>
</section>
<section id="download">
<div class="sec-head">
<div>
<h2>{{t "about.download.title"}}</h2>
<p class="intro">{{th "about.download.intro"}}</p>
</div>
<div>
{{if .Release}}
<div class="ver"><span class="tag">{{.Release}}</span>{{with .Date}}<span class="eyebrow">{{t "about.download.released" .}}</span>{{end}}</div>
<div class="dl-wrap">
<table class="dl">
<thead><tr><th>{{t "about.download.col.for"}}</th><th>{{t "about.download.col.file"}}</th><th>{{t "about.download.col.notes"}}</th></tr></thead>
<tbody>
<tr><td translate="no">Linux x86-64</td><td><a href="{{$.Download}}/llmgw-{{$.Release}}-linux-amd64"><code>llmgw-{{$.Release}}-linux-amd64</code></a></td><td class="note">{{t "about.download.static_any"}}</td></tr>
<tr><td translate="no">Linux ARM64</td><td><a href="{{$.Download}}/llmgw-{{$.Release}}-linux-arm64"><code>llmgw-{{$.Release}}-linux-arm64</code></a></td><td class="note">{{t "about.download.static"}}</td></tr>
<tr><td translate="no">Linux x86-64, NVLink</td><td><a href="{{$.Download}}/llmgw-{{$.Release}}-linux-amd64-nvml"><code>llmgw-{{$.Release}}-linux-amd64-nvml</code></a></td><td class="note">{{t "about.download.nvml"}}</td></tr>
<tr><td>{{t "about.download.mac_arm"}}</td><td><a href="{{$.Download}}/llmgw-{{$.Release}}-darwin-arm64"><code>llmgw-{{$.Release}}-darwin-arm64</code></a></td><td class="note">{{th "about.download.mac_note"}}</td></tr>
<tr><td translate="no">macOS Intel</td><td><a href="{{$.Download}}/llmgw-{{$.Release}}-darwin-amd64"><code>llmgw-{{$.Release}}-darwin-amd64</code></a></td><td class="note"></td></tr>
<tr><td translate="no">Caddy</td><td><a href="{{$.Download}}/Caddyfile"><code>Caddyfile</code></a></td><td class="note">{{t "about.download.proxy_note"}}</td></tr>
<tr><td translate="no">nginx</td><td><a href="{{$.Download}}/nginx.conf"><code>nginx.conf</code></a></td><td class="note">{{t "about.download.proxy_note"}}</td></tr>
<tr><td>{{t "about.download.checksums"}}</td><td><a href="{{$.Download}}/checksums.txt"><code>checksums.txt</code></a></td><td class="note">{{t "about.download.checksums_note"}}</td></tr>
</tbody>
</table>
</div>
{{else}}
<p class="intro" style="margin-top:0">{{th "about.download.dev" .Version}}</p>
{{end}}
</div>
</div>
</section>
<section id="status">
<div class="sec-head">
<div>
<h2>{{t "about.status.title"}}</h2>
<p class="intro">{{t "about.status.intro"}}</p>
</div>
<div class="status">
<div class="proven">
<h3>{{t "about.status.proven"}}</h3>
<ul>
<li>{{t "about.status.proven.single"}}</li>
<li>{{t "about.status.proven.ondemand"}}</li>
<li>{{t "about.status.proven.keys"}}</li>
<li>{{t "about.status.proven.upgrades"}}</li>
<li>{{t "about.status.proven.stores"}}</li>
<li>{{t "about.status.proven.chat"}}</li>
<li>{{t "about.status.proven.ha"}}</li>
<li>{{t "about.status.proven.signin"}}</li>
<li>{{t "about.status.proven.kb"}}</li>
</ul>
</div>
<div class="open">
<h3>{{t "about.status.open"}}</h3>
<ul>
<li>{{th "about.status.open.fabrics"}}</li>
<li>{{t "about.status.open.planes"}}</li>
<li>{{t "about.status.open.weights"}}</li>
</ul>
</div>
</div>
</div>
</section>
<footer>
<span>llmgw {{.Version}}</span>
<span><a href="https://gitea.mynodes.xyz/ilker/llmgw">{{t "about.nav.source"}}</a> ·
<a href="https://gitea.mynodes.xyz/ilker/llmgw/src/branch/main/CHANGELOG.md">{{t "about.footer.changelog"}}</a> ·
<a href="https://gitea.mynodes.xyz/ilker/llmgw/src/branch/main/docs/reference.md">{{t "about.footer.reference"}}</a></span>{{if not .Site}}{{template "langs"}}{{end}}
</footer>
</div>
<script>
var say = { copy: {{t "about.copy"}}, copied: {{t "about.copied"}}, selected: {{t "about.selected"}} };
document.querySelectorAll('.copy').forEach(function (b) {
b.addEventListener('click', function () {
var text = b.dataset.copy || b.parentElement.querySelector('pre').innerText;
var done = function (label) { b.textContent = label; setTimeout(function () { b.textContent = say.copy; }, 1600); };
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () { done(say.copied); }, function () { select(); });
} else { select(); }
function select() {
var el = b.dataset.copy ? b.parentElement.querySelector('code') : b.parentElement.querySelector('pre');
var r = document.createRange(); r.selectNodeContents(el);
var s = window.getSelection(); s.removeAllRanges(); s.addRange(r);
done(say.selected);
}
});
});
</script>
{{if not .Site}}</body></html>{{end}}{{end}}