A user copied the curl from the profile page and sent it as it stood. Every other field in that snippet is filled in for them — the base URL, the key they had just been issued — so "model": "MODEL" reads as a value rather than a blank, and they got: no endpoint serves "MODEL" which is true and useless. It reads the same whether the name was a typo, a placeholder left in from the documentation, or a real outage, and it never says what would have worked. The message now lists what is being served, capped at ten with a count for the rest, and says plainly when nothing is. That list is what /v1/models already returns to the same caller, so it discloses nothing new. The profile page's example now names a model that is actually running, real ones before simulated — the point of an example someone can run is that it runs, and sending a first request to the sim engine would answer in Greek letters. The landing and claim pages keep a placeholder, because they are served without a key and deliberately say nothing about what is here; theirs is <model-name>, which cannot be mistaken for a value, with a line saying where to get the real one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
69 lines
2.8 KiB
HTML
69 lines
2.8 KiB
HTML
{{define "landing"}}<!doctype html>
|
|
<html lang="en"><head>
|
|
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>llmgw</title><link rel="stylesheet" href="/_static/base.css">
|
|
</head><body><div class="wrap">
|
|
<header>
|
|
<h1>llmgw</h1>
|
|
<p class="sub">An OpenAI-compatible endpoint in front of self-hosted models.</p>
|
|
</header>
|
|
|
|
<p>Point any OpenAI client at this address. The API is the one you already have a
|
|
client for; only the base URL changes.</p>
|
|
|
|
<h2>Base URL</h2>
|
|
<pre>{{.BaseURL}}/v1</pre>
|
|
|
|
<h2>Example</h2>
|
|
<pre>curl {{.BaseURL}}/v1/chat/completions \
|
|
-H "Authorization: Bearer $LLMGW_API_KEY" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"model": "<model-name>", "messages": [{"role":"user","content":"hello"}]}'</pre>
|
|
<p class="note">
|
|
Replace <model-name> with a name from
|
|
<code>GET {{.BaseURL}}/v1/models</code>, which needs your key. Sending the
|
|
placeholder unchanged is answered with the list of models that are available.
|
|
</p>
|
|
|
|
<pre>from openai import OpenAI
|
|
client = OpenAI(base_url="{{.BaseURL}}/v1", api_key=os.environ["LLMGW_API_KEY"])</pre>
|
|
|
|
<h2>Which models</h2>
|
|
{{if .AuthEnabled}}
|
|
<p><code>GET /v1/models</code> lists what is available to your key. It needs the key,
|
|
which is why this page does not list them: this page is served to anyone who can
|
|
reach the address.</p>
|
|
{{else}}
|
|
<p><code>GET /v1/models</code> lists what is available.</p>
|
|
<p class="note">This gateway has no API keys configured, so it serves anyone who can
|
|
reach it. That is a deployment choice and only safe on a trusted network.</p>
|
|
{{end}}
|
|
|
|
<h2>Getting a key</h2>
|
|
{{if .SignupOpen}}
|
|
<p><a href="/signup">Create an account</a>. Someone will approve it, and then you
|
|
can issue your own keys from your <a href="/profile">profile</a> — as many as you
|
|
need, revoking them yourself when a laptop is retired or a script is done.</p>
|
|
<p class="note">Already have an account? <a href="/login">Sign in</a>.</p>
|
|
{{else if .Contact}}
|
|
<p>Ask {{if .ContactHref}}<a href="{{.ContactHref}}">{{.Contact}}</a>{{else}}<strong>{{.Contact}}</strong>{{end}}
|
|
for one. {{if .AuthEnabled}}If you already have an account,
|
|
<a href="/login">sign in</a>.{{end}}</p>
|
|
{{else}}
|
|
<p>Keys are issued by whoever operates this gateway. If you do not know who that
|
|
is, the address you reached this page at is the place to start asking.</p>
|
|
{{end}}
|
|
<p>A key is shown once and never again — only its hash is kept here — so put it in
|
|
a password manager straight away.</p>
|
|
|
|
{{if .Notice}}<p class="note">{{.Notice}}</p>{{end}}
|
|
|
|
<h2>Once you have one</h2>
|
|
<ul>
|
|
<li><code>GET {{.BaseURL}}/v1/models</code> — what your key may use</li>
|
|
<li><code>GET {{.BaseURL}}/me</code> — its limits, and what it has spent</li>
|
|
</ul>
|
|
|
|
<footer><span>llmgw {{.Version}}</span><span>{{.Now}}</span></footer>
|
|
</div></body></html>{{end}}
|