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:
@@ -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
@@ -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 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 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 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 GiB) on the RTX 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 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 & 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 |
@@ -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>
|
||||
|
||||
@@ -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
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user