repos
/ orchard main

orchard

mirror

Every site I host, in one repo, along with the Cloudflare Tunnel and Caddy that front them. It's all Go, Vite, and SQLite, and it runs on a desktop at home with nothing listening on an inbound port.

blogbuncaddycloudflare-tunneldockergogolanghomelabhtml-templatemonorepoself-hostedseosqlitestatic-sitetypstuptime-monitoringviteweb-analytics

3.3 KB · 95 lines · HTML Raw History
 1{{template "head" .}}
 2
 3{{if .Fresh}}
 4<section class="fresh">
 5  <p class="label">Copy this now</p>
 6  <code class="secret">{{.Fresh}}</code>
 7  <p class="note">Nothing here can show it again. It is stored as a SHA-256 and the plaintext was never written down.</p>
 8</section>
 9{{end}}
10
11<section class="stats">
12  <div class="stat"><span class="num">{{.NKeys}}</span><span class="label">Live keys</span></div>
13  <div class="stat"><span class="num">{{comma .NCalls}}</span><span class="label">Calls logged</span></div>
14  <div class="stat"><span class="num">{{.Retain}}</span><span class="label">Retention</span></div>
15</section>
16
17<h2>Last 24 hours</h2>
18{{if .Usage}}
19<table>
20  <thead><tr><th>Caller</th><th class="n">Calls</th><th class="n">Prompt</th><th class="n">Output</th><th class="n">Errors</th><th class="n">tok/s</th></tr></thead>
21  <tbody>
22  {{range .Usage}}
23    <tr>
24      <td><a href="/calls?caller={{.Caller}}">{{if .Caller}}{{.Caller}}{{else}}unknown{{end}}</a></td>
25      <td class="n">{{comma .Calls}}</td>
26      <td class="n">{{comma .PromptTok}}</td>
27      <td class="n">{{comma .OutputTok}}</td>
28      <td class="n {{if .Errors}}bad{{end}}">{{.Errors}}</td>
29      <td class="n">{{printf "%.1f" .AvgTPS}}</td>
30    </tr>
31  {{end}}
32  </tbody>
33</table>
34{{else}}
35<p class="empty">Nothing has called through yet.</p>
36{{end}}
37
38<h2>API keys</h2>
39<form class="newkey" method="post" action="/keys">
40  <input type="text" name="name" placeholder="What will use it, like chat or aiagent" required maxlength="60">
41  <button type="submit">Create key</button>
42</form>
43
44{{if .Keys}}
45<table>
46  <thead><tr><th>Name</th><th>Key</th><th>Created</th><th>Last used</th><th></th></tr></thead>
47  <tbody>
48  {{range .Keys}}
49    <tr {{if .Revoked}}class="off"{{end}}>
50      <td>{{.Name}}</td>
51      <td><code>{{.Prefix}}&hellip;</code></td>
52      <td class="faint">{{when .Created}}</td>
53      <td class="faint">{{when .Used}}</td>
54      <td class="act">
55        {{if .Revoked}}
56          <span class="tag">revoked</span>
57          <form method="post" action="/keys/{{.ID}}/delete"><button type="submit" class="danger">Delete</button></form>
58        {{else}}
59          <form method="post" action="/keys/{{.ID}}/revoke"><button type="submit">Revoke</button></form>
60        {{end}}
61      </td>
62    </tr>
63  {{end}}
64  </tbody>
65</table>
66{{else}}
67<p class="empty">No keys yet. Nothing can call the gateway until there is one.</p>
68{{end}}
69
70<h2>Recent calls</h2>
71{{if .Recent}}
72<table>
73  <thead><tr><th>When</th><th>Caller</th><th>Prompt</th><th class="n">Tokens</th><th class="n">ms</th></tr></thead>
74  <tbody>
75  {{range .Recent}}
76    <tr>
77      <td class="faint">{{when .At}}</td>
78      <td>{{.Caller}}</td>
79      <td class="msg">{{short .Messages 90}}</td>
80      <td class="n">{{comma .OutputTok}}</td>
81      <td class="n {{if .Err}}bad{{end}}">{{.MS}}</td>
82    </tr>
83  {{end}}
84  </tbody>
85</table>
86<p class="more"><a href="/calls">Every call</a></p>
87{{else}}
88<p class="empty">No calls yet.</p>
89{{end}}
90
91<h2>Using it</h2>
92<p class="how">Point any OpenAI shaped client at <code>http://orchard-llm:8000/v1</code> on the bridge, or <code>https://llm.bythewood.me/v1</code> from anywhere else, and send the key as <code>Authorization: Bearer orch-&hellip;</code>. Ask for the model named <code>{{.Model}}</code>. Upstream is <code>{{.Upstream}}</code>.</p>
93
94{{template "foot" .}}