homepage: amber CRT theme, VT323, current-fleet docs + API access guide

- style.css: green phosphor -> amber CRT-AMBIOS palette; docs styles for
  screenshots, code blocks, key warning (full + bare mode)
- index/admin/docs: VT323 from the Google Fonts CDN
- docs.html: rewrite #chat/#models for the live fleet (flash-server v2,
  radiance native FP8, Qwen3.5-9B Q6_K); new #api-access with OpenWebUI
  key walkthrough + Opencode and Pi configs; three OpenWebUI screenshots
- services.json: AI card details match the current fleet
- deploy-remote.sh: ship shared/homepage/img/ to /srv/homepage/
- docs: Homepage.md theme wave + OpenWebUI.md picker access-control law
This commit is contained in:
Frank
2026-10-07 23:27:23 -07:00
parent 6632d0a2f6
commit cee90eea52
11 changed files with 169 additions and 41 deletions
+3
View File
@@ -5,6 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>frank — admin</title>
<base href="/">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=VT323&display=swap">
<link rel="stylesheet" href="style.css">
</head>
<body>
+100 -17
View File
@@ -5,6 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>frank — docs</title>
<base href="/">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=VT323&display=swap">
<link rel="stylesheet" href="style.css">
</head>
<body>
@@ -31,13 +34,18 @@
<section id="chat">
<h1>Talking to the AI</h1>
<p>The everyday front door is <a href="https://ai.franksdank.cloud">Open WebUI</a>
(it has its own login the first time; use the same email you use everywhere).
Pick a model in the chat's model selector — the three models the fleet runs are
described <a href="#models">below</a>. Open WebUI keeps your chat history; the raw
model endpoints do not.</p>
<p>Images go to <code>frank-primary</code> or <code>frank-secondary</code>
(both see them). Audio (WAV) goes to <code>frank-secondary</code> only.</p>
<p>The everyday front door is <a href="https://ai.franksdank.cloud">Open&nbsp;WebUI</a>,
the family chat app. Open the address, click <strong>Continue with authentik</strong>,
and use the same single sign-on as everything else — no separate password. Your
conversations are saved to your account, so history follows you between devices.</p>
<img src="img/openwebui-chat.png" alt="Open WebUI chat screen with a question and the AI's answer">
<p>Below the text box, the model box on the right chooses which model answers you.
Family accounts get <code>frank-secondary</code> — the fleet's fast all-rounder,
which also sees images: drag a photo or screenshot straight into the chat box.
Frank's account can additionally reach the bigger models.</p>
<img src="img/openwebui-model-picker.png" alt="The Open WebUI welcome screen with frank-secondary selected in the model box">
<p>Open WebUI keeps your chat history; the raw model endpoints (used by developer
tools, see <a href="#api-access">API access</a>) do not.</p>
</section>
<section id="models">
@@ -47,27 +55,26 @@
<h2>frank-large — deep reasoning</h2>
<ul>
<li><strong>Model:</strong> Qwen3.8-27B (UD-Q8_K_XL, 31.5 GiB).</li>
<li><strong>Capacity:</strong> 262k-token context, exactly one conversation at a time. Text only.</li>
<li><strong>Inputs:</strong> text.</li>
<li><strong>Model:</strong> Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62&nbsp;GiB) — an uncensored edition that thinks before answering.</li>
<li><strong>Capacity:</strong> 200k-token context, two conversations at a time; sees images.</li>
<li><strong>Inputs:</strong> text, image.</li>
<li><strong>Best for:</strong> cybersecurity and debugging. <em>Use requires Frank's permission.</em></li>
<li><strong>Not for:</strong> images. It cannot see them.</li>
</ul>
<h2>frank-primary — the primary model</h2>
<ul>
<li><strong>Model:</strong> Qwen3.8-Flash-Next (Q8_0, 175.3 GiB) with MTP + n-gram speculative drafting on both R9700s.</li>
<li><strong>Capacity:</strong> 262k-token context, exactly one conversation at a time; sees images.</li>
<li><strong>Model:</strong> Qwen3.8-Flash-Next at native FP8 precision (radiance, 173&nbsp;GiB across both R9700s) — the biggest brain on the network.</li>
<li><strong>Capacity:</strong> 200k-token context, two conversations at a time; sees images.</li>
<li><strong>Inputs:</strong> text, image.</li>
<li><strong>Best for:</strong> software engineering, system administration, and instruction tasks.</li>
</ul>
<h2>frank-secondary — the fast utility model</h2>
<ul>
<li><strong>Model:</strong> Gemma4-12B QAT (Balanced, Q4_K_M, 7.4 GiB).</li>
<li><strong>Capacity:</strong> one million tokens of pooled context across four simultaneous conversations (up to 262k each); fastest at images.</li>
<li><strong>Inputs:</strong> text, image, audio.</li>
<li><strong>Best for:</strong> agentic search, RAG, research subagents, translation, roleplay, and summarization — any small task that doesn't need much intelligence, and anything with a picture (screenshots, photos, diagrams).</li>
<li><strong>Model:</strong> Qwen3.5-9B-Uncensored (Q6_K, 6.9&nbsp;GiB) on the RTX&nbsp;3090 — roughly 95 tokens per second.</li>
<li><strong>Capacity:</strong> two simultaneous conversations, 200k tokens each; sees images.</li>
<li><strong>Inputs:</strong> text, image.</li>
<li><strong>Best for:</strong> agentic search, RAG, research subagents, translation, roleplay, and summarization — any small task that doesn't need much intelligence, and anything with a picture (screenshots, photos, diagrams). This is the model Open&nbsp;WebUI offers to family accounts.</li>
</ul>
<p class="foot-note">Which one to pick? Small utility work, RAG, search, and
@@ -76,6 +83,82 @@
<code>frank-large</code> (with Frank's permission).</p>
</section>
<section id="api-access">
<h1>API access — the AI on your own laptop</h1>
<p>Developer assistants like <strong>Opencode</strong> and <strong>Pi</strong> are
chat programs that run on your own computer and can read your files, run commands,
and edit code while they talk. They are all built to speak the same standard
language as the big commercial products (the "OpenAI-compatible" API), and our
server speaks it too. You give the program three things — an address, a personal
key, and a model name — and your laptop thinks through our hardware.</p>
<h2>Step 1 — get your personal key</h2>
<ol>
<li>Open <a href="https://ai.franksdank.cloud">ai.franksdank.cloud</a> and log in.</li>
<li>Click your circle (bottom-left corner) → <strong>Settings</strong> → <strong>Account</strong>.</li>
<li>Scroll to <strong>API keys</strong> → press <strong>Show</strong> → <strong>Create new secret key</strong>.</li>
<li>Press the copy icon. The key looks like <code>sk-3f2a…</code>.</li>
</ol>
<img src="img/openwebui-api-keys.png" alt="The Open WebUI Account settings page with the API key field at the bottom">
<p class="key-warn">The key is a password. Anyone who has it can use our AI as
you. Paste it only into the program's config file — never into a shared chat,
a screenshot, or a git repository.</p>
<h2>Step 2 — the three details every tool asks for</h2>
<ul>
<li><strong>Base URL:</strong> <code>https://ai.franksdank.cloud/api/v1</code></li>
<li><strong>Model:</strong> <code>frank-secondary</code></li>
<li><strong>API key:</strong> the <code>sk-…</code> from step 1 — sent as the header <code>Authorization: Bearer sk-…</code></li>
</ul>
<p>Proof that it works, from any terminal (replace the key):</p>
<pre><code>curl https://ai.franksdank.cloud/api/v1/chat/completions \
-H "Authorization: Bearer PASTE-YOUR-KEY" \
-H "Content-Type: application/json" \
-d '{"model": "frank-secondary", "messages": [{"role": "user", "content": "Hello!"}]}'</code></pre>
<h2>Step 3a — Opencode</h2>
<p>Install once (<code>npm install -g opencode-ai</code>), then create the file
<code>~/.config/opencode/opencode.json</code> with:</p>
<pre><code>{
"$schema": "https://opencode.ai/config.json",
"provider": {
"frank": {
"npm": "@ai-sdk/openai-compatible",
"name": "Frank fleet",
"options": {
"baseURL": "https://ai.franksdank.cloud/api/v1",
"apiKey": "PASTE-YOUR-KEY"
},
"models": {
"frank-secondary": { "name": "frank-secondary" }
}
}
}
}</code></pre>
<p>Start <code>opencode</code> and pick the model with <code>/model</code> —
it appears as <code>frank/frank-secondary</code>.</p>
<h2>Step 3b — Pi</h2>
<p>Create the file <code>~/.pi/agent/models.json</code> with:</p>
<pre><code>{
"providers": {
"frank": {
"baseUrl": "https://ai.franksdank.cloud/api/v1",
"api": "openai-completions",
"apiKey": "PASTE-YOUR-KEY",
"models": [
{ "id": "frank-secondary" }
]
}
}
}</code></pre>
<p>Then start Pi with <code>pi --model frank/frank-secondary</code>.</p>
<p class="foot-note">The key works only for the family AI — it is not your
Authentik password, and losing it costs nothing beyond asking Frank to rotate it.
Want a bigger model (frank-primary, frank-large)? Ask Frank to raise your access.</p>
</section>
<section id="media">
<h1>Media &amp; files</h1>
<ul>
Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

+3
View File
@@ -5,6 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>frank — services</title>
<base href="/">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=VT323&display=swap">
<link rel="stylesheet" href="style.css">
</head>
<body>
+4 -4
View File
@@ -269,8 +269,8 @@
"section": "AI",
"details": {
"role": "Deep reasoning model",
"spec": "Qwen3.8-27B (UD-Q8_K_XL, 31.5 GiB) — 262k-token context, one conversation at a time, text only.",
"inputs": ["text"],
"spec": "Qwen3.8-Flash-Next v2 Swift1.5 abliterated (halogen flash-server, ~62 GiB) — 200k-token context, two conversations at a time; sees images. Speculative decoding always on.",
"inputs": ["text", "image"],
"use": "Cybersecurity and debugging. Requires Frank's permission."
},
"url": "",
@@ -286,7 +286,7 @@
"section": "AI",
"details": {
"role": "Primary model",
"spec": "Qwen3.8-Flash-Next (Q8_0, 175.3 GiB) — full 262k-token context, one conversation; sees images. Spec-drafted (MTP + n-gram) on both R9700s.",
"spec": "Qwen3.8-Flash-Next at native FP8 precision (radiance, 173 GiB) — 200k-token context, two conversations; sees images. Runs on both R9700s with tiered expert memory.",
"inputs": ["text", "image"],
"use": "Software engineering, system administration, and instruction tasks."
},
@@ -303,7 +303,7 @@
"section": "AI",
"details": {
"role": "Fast utility model",
"spec": "MiMo-V2.6-Distill-Qwen-9B (INT8 W8A16, 12 GiB) on SGLang — 606k-token pool across four 151k-token conversations; 84 tok/s decode; sees images.",
"spec": "Qwen3.5-9B-Uncensored (Q6_K, 6.9 GiB) on llama.cpp CUDA — two 200k-token conversations at a time; sees images; ~95 tok/s decode on the RTX 3090.",
"inputs": ["text", "image"],
"use": "Agentic search, RAG, research subagents, translation, roleplay, and summarization — any small task that doesn't need much intelligence."
},
+25 -16
View File
@@ -1,17 +1,18 @@
/* The homepage theme: terminal TUI, green-on-black, 1995 phosphor palette.
A ?bare=1 toggle strips the page to bare, unstyled HTML (Q27). The page
never sets a custom or hidden cursor, so the user's cursor is untouched (Q28). */
/* The homepage theme: terminal TUI, amber-on-black, CRT-AMBIOS palette with
the VT323 bitmap font (Google Fonts CDN). A ?bare=1 toggle strips the page
to bare, unstyled HTML (Q27). The page never sets a custom or hidden cursor,
so the user's cursor is untouched (Q28). */
:root {
--bg: #050805;
--fg: #33ff66;
--dim: #2f8f52;
--bg: #0a0600;
--fg: #ffb000;
--dim: #a06a00;
--down: #ff5555;
--wip: #ffcc33;
--link: #33ccff;
--head: #aaffcc;
--border: #1a4d2e;
--panel: #0a120a;
--link: #ffd75f;
--head: #ffe9a8;
--border: #5c3d00;
--panel: #150c02;
}
* { box-sizing: border-box; }
@@ -21,12 +22,12 @@ html { background: var(--bg); }
body {
background: var(--bg);
color: var(--fg);
font-family: "Terminus", "Fira Code", "DejaVu Sans Mono", "Consolas", monospace;
font-size: 15px;
line-height: 1.55;
font-family: "VT323", "Terminus", "Fira Code", "DejaVu Sans Mono", "Consolas", monospace;
font-size: 19px;
line-height: 1.4;
margin: 0;
padding: 24px;
text-shadow: 0 0 4px rgba(51, 255, 102, 0.30);
text-shadow: 0 0 4px rgba(255, 176, 0, 0.30);
}
/* Subtle scanlines. */
@@ -96,13 +97,21 @@ body::before {
/* The user docs page (static prose). */
.docs { max-width: 780px; }
.docs h1 { color: var(--head); font-size: 1.25rem; border-bottom: 1px solid var(--border); padding-bottom: 4px; }
.docs h2 { color: var(--head); font-size: 1.05rem; margin-top: 20px; }
.docs h1 { color: var(--head); font-size: 1.7rem; border-bottom: 1px solid var(--border); padding-bottom: 4px; }
.docs h2 { color: var(--head); font-size: 1.35rem; margin-top: 20px; }
.docs a { color: var(--link); }
.docs code { color: var(--head); }
.docs pre { background: var(--panel); border: 1px solid var(--border); border-radius: 2px; padding: 10px 12px; overflow-x: auto; }
.docs pre code { color: var(--fg); }
.docs img { display: block; max-width: 100%; border: 1px solid var(--border); border-radius: 2px; margin: 10px 0; }
.docs .key-warn { color: var(--down); }
.docs .foot-note { color: var(--dim); }
html[data-bare="1"] .docs h1, html[data-bare="1"] .docs h2 { color: #000; border-color: #000; }
html[data-bare="1"] .docs a, html[data-bare="1"] .docs code { color: #000; }
html[data-bare="1"] .docs pre { background: none; border-color: #000; }
html[data-bare="1"] .docs pre code { color: #000; }
html[data-bare="1"] .docs img { border-color: #000; }
html[data-bare="1"] .docs .key-warn { color: #000; }
/* Bare mode (Q27): strip to default browser rendering. */
html[data-bare="1"] body { background: #fff; color: #000; font-family: serif; text-shadow: none; font-size: 16px; }