updating to use stable-diffusion.cpp for the image generation as ollama has since removed it

This commit is contained in:
itsamejms
2026-08-24 11:23:10 +01:00
parent da443175c5
commit f3e06d2bd3
9 changed files with 430 additions and 256 deletions
+50 -7
View File
@@ -10,7 +10,7 @@ interface LlmConfig {
temperature: number;
max_tokens: number;
top_p: number;
image_model: string;
image_api_url: string;
embed_model: string;
}
@@ -30,6 +30,9 @@ export function SettingsPanel() {
const [conn, setConn] = useState<{ ok: boolean; models: string[]; error: string } | null>(null);
const [dataDir, setDataDir] = useState<DataDirInfo | null>(null);
const [relocating, setRelocating] = useState(false);
// ponytail: probe the sd-server so a non-technical DM gets a green check, same pattern as the LLM test.
const [imgTesting, setImgTesting] = useState(false);
const [imgConn, setImgConn] = useState<{ ok: boolean; error: string } | null>(null);
// ponytail: advanced SQLite viewer — read-only, two DBs (lore.db / generations.db).
const [sqlDb, setSqlDb] = useState<"lore" | "generations">("generations");
const [sqlInput, setSqlInput] = useState("SELECT name, type FROM sqlite_master WHERE type='table' ORDER BY name");
@@ -153,6 +156,24 @@ export function SettingsPanel() {
setTesting(false);
}
// ponytail: probe the configured sd-server. Save first so it uses the latest URL.
async function testImage() {
if (!config) return;
setImgTesting(true);
setImgConn(null);
try {
await invoke("set_llm_config", { config });
const r = await invoke<{ ok: boolean; error: string }>("test_image_connection");
setImgConn(r);
if (r.ok) addToast("sd-server reachable", "success");
else addToast(`Image server not reachable: ${r.error}`, "error");
} catch (e) {
setImgConn({ ok: false, error: String(e) });
addToast(`Image server not reachable: ${e}`, "error");
}
setImgTesting(false);
}
// ponytail: provider presets fill in the API URL pattern + default model.
const PRESETS: { label: string; url: string; model: string; key?: boolean }[] = [
{ label: "Ollama", url: "http://localhost:11434", model: "llama3.2" },
@@ -177,7 +198,7 @@ export function SettingsPanel() {
temperature: 0.7,
max_tokens: 512,
top_p: 0.9,
image_model: "x/flux2-klein:4b",
image_api_url: "http://localhost:1234",
embed_model: "nomic-embed-text",
};
function resetDefaults() {
@@ -386,17 +407,39 @@ export function SettingsPanel() {
</div>
)}
<h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Image Model</h3>
<h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Image Server</h3>
<div className="flex flex-col gap-1">
<label className="text-[var(--color-text-secondary)] text-xs font-medium">
Image model
sd-server URL
</label>
<p className="text-[10px] text-[var(--color-text-dim)] leading-relaxed">
Base URL of a <a href="https://github.com/leejet/stable-diffusion.cpp" target="_blank" rel="noreferrer" className="underline">stable-diffusion.cpp</a> `sd-server` (A1111-compatible API). Start it with your chosen model, e.g.<br /><code className="font-mono">sd-server -m model.safetensors</code>
</p>
<input
className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-2 text-[var(--color-text-primary)] placeholder-[var(--color-text-dim)] focus:outline-none focus:border-[var(--color-gold-bright)]"
value={config.image_model}
onChange={(e) => setConfig({ ...config, image_model: e.target.value })}
placeholder="x/flux2-klein:4b"
value={config.image_api_url}
onChange={(e) => setConfig({ ...config, image_api_url: e.target.value })}
placeholder="http://localhost:1234"
/>
{/* ponytail: mirror the LLM test button so a non-technical DM gets a green check */}
<div className="flex items-center gap-2 mt-1">
<button
type="button"
onClick={testImage}
disabled={imgTesting}
className="rounded-lg bg-[var(--color-bg-surface)] border border-[var(--color-border-glass)] px-3 py-1.5 text-xs font-medium text-[var(--color-text-secondary)] hover:border-[var(--color-gold-bright)] hover:text-[var(--color-gold-bright)] transition-colors cursor-pointer disabled:opacity-50"
>
{imgTesting ? "Testing…" : "Test connection"}
</button>
{imgConn && (
<span className={`text-xs ${imgConn.ok ? "text-[var(--color-success)]" : "text-[var(--color-danger)]"}`}>
{imgConn.ok ? "✓ sd-server reachable" : `✕ ${imgConn.error}`}
</span>
)}
</div>
<p className="text-[10px] text-[var(--color-text-dim)]">
New to this? Open the <strong>Image</strong> tab → "First time? Set up image generation" for a full step-by-step.
</p>
</div>
<h3 className="font-heading text-[var(--color-gold-bright)] text-xs font-semibold uppercase tracking-wider border-b border-[var(--color-border-subtle)] pb-1 mb-1">Embedding Model (Lore RAG)</h3>