diff --git a/app.py b/app.py index c92c024..9e74ec9 100644 --- a/app.py +++ b/app.py @@ -20,7 +20,7 @@ from fastapi import FastAPI, HTTPException from fastapi.responses import FileResponse, JSONResponse, Response from fastapi.staticfiles import StaticFiles -from routers import jobs, maintenance, models, system, cookbook, integration, news +from routers import jobs, maintenance, memory, models, system, cookbook, integration, news app = FastAPI(title="Mission Control") @@ -43,6 +43,7 @@ app.include_router(system.router) app.include_router(cookbook.router) app.include_router(integration.router) app.include_router(news.router) +app.include_router(memory.router) _STATIC = Path(__file__).parent / "static" diff --git a/config.py b/config.py index 55d6b04..b8993b1 100644 --- a/config.py +++ b/config.py @@ -20,6 +20,7 @@ MODELS_DIR = Path(os.environ.get("MC_MODELS_DIR", "/srv/models")) # Eigene Cookbook-Setups (vom Nutzer angelegt). Bewusst NICHT im App-Verzeichnis, sonst # wuerde ein Deploy (rsync) sie ueberschreiben -> persistent neben den Modellen ablegen. USER_RECIPES_PATH = Path(os.environ.get("MC_USER_RECIPES", str(MODELS_DIR / "mission-control-recipes.json"))) +MEMORY_DB = Path(os.environ.get("MC_MEMORY_DB", str(MODELS_DIR / "mission-control-memory.db"))) # Cache der automatischen Modell-Entdeckung ("aktuell beste Modelle", live von HuggingFace). # Ebenfalls persistent neben den Modellen (uebersteht Deploys). TTL = wie lange der Cache # als frisch gilt, bevor lazy neu von den Quellen geladen wird (Default 12 h). diff --git a/frontend/src/main.ts b/frontend/src/main.ts index c3f87e4..c17287f 100644 --- a/frontend/src/main.ts +++ b/frontend/src/main.ts @@ -15,6 +15,7 @@ import CookbookPanel from './panels/CookbookPanel.svelte' import ConnectPanel from './panels/ConnectPanel.svelte' import NewsPanel from './panels/NewsPanel.svelte' import GuidesPanel from './panels/GuidesPanel.svelte' +import MemoryPanel from './panels/MemoryPanel.svelte' let prevModelStates: Record = {} @@ -156,6 +157,7 @@ const panels: [string, any][] = [ ['connect', ConnectPanel], ['news', NewsPanel], ['guides', GuidesPanel], + ['memory', MemoryPanel], ] for (const [view, Panel] of panels) { const el = document.querySelector(`.view[data-view="${view}"]`) diff --git a/frontend/src/panels/ConnectPanel.svelte b/frontend/src/panels/ConnectPanel.svelte index bc1fb86..f318200 100644 --- a/frontend/src/panels/ConnectPanel.svelte +++ b/frontend/src/panels/ConnectPanel.svelte @@ -11,6 +11,8 @@ let selectedModelIds = $state([]) let testResult = $state('') let testOk = $state(false) + let selectedMemTool = $state('cline') + const memBlock = $derived(memMcpBlock(selectedMemTool)) function baseUrl() { return `http://${location.hostname}:8080/v1` } function isLanIp(h: string) { return /^\d{1,3}(\.\d{1,3}){3}$/.test(h) } @@ -71,6 +73,16 @@ function copyVal(inp: HTMLInputElement) { navigator.clipboard?.writeText(inp.value) } + + function memMcpBlock(tool: string) { + const pyPath = tool === 'bosgame' + ? '/opt/mission-control/.venv/bin/python' + : 'python' + const scriptPath = tool === 'bosgame' + ? '/opt/mission-control/mcp_memory.py' + : 'C:\\\\Users\\\\TobisPC\\\\mission-control\\\\mcp_memory.py' + return `{\n "mcpServers": {\n "mission-control-memory": {\n "command": "${pyPath}",\n "args": ["${scriptPath}"],\n "env": {\n "MC_URL": "http://192.168.178.151:9000"\n }\n }\n }\n}` + }
@@ -308,3 +320,56 @@
{/if} + + +
+
+

Gedächtnis-MCP

+ Neu in v7 +
+
+ Damit Cline, OpenCode und Claude Code sich Projektfakten, Entscheidungen und Präferenzen + über Sessions hinweg merken — geteilt über alle Tools, verwaltet im + { e.preventDefault(); (document.querySelector(".nav-item[data-view='memory']") as HTMLElement)?.click() }} + style="color:var(--accent)">Gedächtnis-Tab. +
+ + +
+ {#each [ + ['cline', 'Cline / Claude Code', 'Windows — Tools auf dem Entwicklungs-PC'], + ['opencode', 'OpenCode', 'Windows — Terminal-Agent'], + ['bosgame', 'Direkt am Bosgame', 'Wenn das Tool am Server läuft'], + ] as [id, label, desc]} + + {/each} +
+ + +
+ +
{memBlock}
+
+ + {#if selectedMemTool === 'cline'} +

In Cline: MCP-Einstellungen öffnen (Stecker-Icon in der Cline-Sidebar) → „Add MCP Server" → diesen Block einfügen.

+

In Claude Code: Block in ~/.claude/settings.json unter "mcpServers" einfügen.

+
+ Einmalig auf dem Windows-PC: pip install mcp httpx ausführen — danach mcp_memory.py aus dem Repo-Ordner erreichbar machen (Pfad im Snippet anpassen). +
+ {:else if selectedMemTool === 'opencode'} +

Block in ~/.config/opencode/opencode.json unter "mcpServers" einfügen.

+
+ Einmalig: pip install mcp httpx — und Pfad zu mcp_memory.py im Snippet anpassen. +
+ {:else} +

Block in die MCP-Config des jeweiligen Tools einfügen. Der Bosgame-Pfad /opt/mission-control/mcp_memory.py ist bereits korrekt — kein weiteres Setup nötig.

+ {/if} +
diff --git a/frontend/src/panels/MemoryPanel.svelte b/frontend/src/panels/MemoryPanel.svelte new file mode 100644 index 0000000..b56f678 --- /dev/null +++ b/frontend/src/panels/MemoryPanel.svelte @@ -0,0 +1,237 @@ + + +
+
+

Gedächtnis

+
Fakten, Entscheidungen und Kontext — geteilt von allen KI-Tools via MCP.
+
+ +
+ + +{#if adding} +
+

Neuer Eintrag

+ + + + +
+ + + Strg+Enter zum Speichern +
+
+{/if} + + +
+
+ Filter: + {#each [ + ['all', 'Alle', '', memories.length], + ['stable', 'Stabil', 'var(--accent)', countCat('stable')], + ['versioned', 'Versioniert', '#f59e0b', countCat('versioned')], + ['ephemeral', 'Temporär', 'var(--mut)', countCat('ephemeral')], + ] as [val, lbl, clr, cnt]} + filter = val} + onkeydown={e => e.key === 'Enter' && (filter = val)}> + {lbl} {cnt} + + {/each} +
+
+ + +{#if loading} +
Lade…
+{:else if filtered.length === 0} +
+
+
{memories.length === 0 ? 'Noch keine Einträge' : 'Keine Treffer'}
+
+ {memories.length === 0 + ? 'Klicke „+ Eintrag" um manuell etwas zu speichern, oder verbinde ein KI-Tool via MCP.' + : 'Andere Kategorie wählen oder Eintrag anlegen.'} +
+ {#if memories.length === 0} + + {/if} +
+
+{:else} +
+ {#each filtered as m, i (m.id)} +
+ {#if editId === m.id} + + +
+ + +
+ {:else} +
+
+
{m.content}
+
+ + {CAT[m.category]?.label || m.category} + + {m.source} + {relTime(m.updated_at)} +
+
+
+ + +
+
+ {/if} +
+ {/each} +
+{/if} + + +
+

Wie KI-Tools dieses Gedächtnis nutzen

+
+ Cline, OpenCode und Claude Code greifen über den Memory MCP-Server auf diese Einträge zu. + Beim Start einer Session lädt der Agent automatisch alle Einträge — er kennt dann deinen Stack, + deine Präferenzen und frühere Entscheidungen. Den Setup-Guide findest du unter + { e.preventDefault(); (document.querySelector(".nav-item[data-view='connect']") as HTMLElement)?.click() }} + style="color:var(--accent)">Verbinden → Gedächtnis-MCP. +
+
+ Kategorien: Stabil = Projektfakten die sich selten ändern · + Versioniert = Tech-Versionen (bei Updates überschreiben) · + Temporär = aktuelle Aufgaben, nach 7 Tagen automatisch gelöscht +
+
diff --git a/mcp_memory.py b/mcp_memory.py new file mode 100644 index 0000000..826f265 --- /dev/null +++ b/mcp_memory.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python3 +""" +Mission Control — Memory MCP Server + +Stdio-MCP-Server fuer persistentes Gedaechtnis. +Laeuft als Subprocess von Cline / Claude Code / OpenCode auf dem Client-Rechner. +Ruft die /api/memory-Endpunkte von Mission Control via HTTP auf. + +Konfiguration via Env-Vars: + MC_URL Mission Control URL (default: http://192.168.178.151:9000) + MC_TOKEN Auth-Token (default: leer) + +Einmalig installieren (auf dem Rechner wo das KI-Tool laeuft): + pip install mcp httpx +""" + +import os +import httpx +from mcp.server.fastmcp import FastMCP + +MC_URL = os.environ.get("MC_URL", "http://192.168.178.151:9000").rstrip("/") +MC_TOKEN = os.environ.get("MC_TOKEN", "") + +mcp = FastMCP("mission-control-memory") + + +def _headers() -> dict: + return {"X-MC-Token": MC_TOKEN} if MC_TOKEN else {} + + +def _get(path: str, **params) -> list | dict: + r = httpx.get(f"{MC_URL}{path}", headers=_headers(), params=params, timeout=10) + r.raise_for_status() + return r.json() + + +def _post(path: str, data: dict) -> dict: + r = httpx.post(f"{MC_URL}{path}", headers=_headers(), json=data, timeout=10) + r.raise_for_status() + return r.json() + + +def _put(path: str, data: dict) -> dict: + r = httpx.put(f"{MC_URL}{path}", headers=_headers(), json=data, timeout=10) + r.raise_for_status() + return r.json() + + +def _delete(path: str) -> dict: + r = httpx.delete(f"{MC_URL}{path}", headers=_headers(), timeout=10) + r.raise_for_status() + return r.json() + + +@mcp.tool() +def get_memories(category: str = "") -> str: + """Laedt gespeicherte Fakten und Entscheidungen. category: stable | versioned | ephemeral | (leer = alle)""" + params = {"category": category} if category else {} + items = _get("/api/memory", **params) + if not items: + return "Keine Memories gespeichert." + cat_icon = {"stable": "🔵", "versioned": "🟡", "ephemeral": "⏱"} + return "\n".join( + f"{cat_icon.get(m['category'], '·')} [{m['category']}] {m['content']}" + f" (Quelle: {m['source']}, ID: {m['id'][:8]})" + for m in items + ) + + +@mcp.tool() +def add_memory(content: str, category: str = "stable", source: str = "agent") -> str: + """Speichert einen Fakt oder eine Entscheidung. + category: stable=Projektfakten (selten aendern), versioned=Tech-Versionen (bei Updates ueberschreiben), ephemeral=temporaerer Kontext (nach 7 Tagen geloescht). + """ + m = _post("/api/memory", {"content": content, "category": category, "source": source}) + return f"Gespeichert (ID: {m['id'][:8]}): {content}" + + +@mcp.tool() +def search_memories(q: str) -> str: + """Sucht per Stichwort in allen gespeicherten Fakten.""" + items = _get("/api/memory", q=q) + if not items: + return f"Keine Treffer fuer '{q}'." + return "\n".join( + f"[{m['category']}] {m['content']} (ID: {m['id'][:8]})" + for m in items + ) + + +@mcp.tool() +def update_memory(memory_id: str, content: str = "", category: str = "") -> str: + """Aktualisiert einen bestehenden Eintrag (z.B. nach Tech-Update). Nur gesetzte Felder werden geaendert.""" + data: dict = {} + if content: + data["content"] = content + if category: + data["category"] = category + if not data: + return "Nichts zu aktualisieren (content und category sind leer)." + m = _put(f"/api/memory/{memory_id}", data) + return f"Aktualisiert: {m['content']}" + + +@mcp.tool() +def delete_memory(memory_id: str) -> str: + """Loescht einen veralteten oder falschen Eintrag anhand seiner ID.""" + _delete(f"/api/memory/{memory_id}") + return f"Eintrag {memory_id[:8]} geloescht." + + +if __name__ == "__main__": + mcp.run() diff --git a/requirements.txt b/requirements.txt index 04e0a50..4ada5e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ httpx>=0.27 ruamel.yaml>=0.18 psutil>=5.9.0 huggingface_hub>=0.34 # liefert die `hf`-CLI fuer Modell-Downloads +mcp>=1.0 # MCP Python SDK fuer mcp_memory.py stdio-Server diff --git a/routers/memory.py b/routers/memory.py new file mode 100644 index 0000000..8f90893 --- /dev/null +++ b/routers/memory.py @@ -0,0 +1,154 @@ +""" +Memory Layer fuer Mission Control. + +Persistentes Gedaechtnis fuer lokale LLM-Agenten (Cline, Claude Code, OpenCode). +SQLite aus stdlib — kein Vektor-Overhead, keine neue Abhaengigkeit. +Alle MCP-Tools teilen denselben Speicher via mcp_memory.py-Wrapper. +""" + +import sqlite3 +import uuid +from datetime import datetime, timezone +from typing import Optional + +from fastapi import APIRouter, Depends, HTTPException +from pydantic import BaseModel + +from auth import auth +from config import MEMORY_DB + +router = APIRouter(prefix="/api", dependencies=[Depends(auth)]) + +_db_conn: Optional[sqlite3.Connection] = None + + +def _db() -> sqlite3.Connection: + global _db_conn + if _db_conn is None: + MEMORY_DB.parent.mkdir(parents=True, exist_ok=True) + _db_conn = sqlite3.connect(str(MEMORY_DB), check_same_thread=False) + _db_conn.row_factory = sqlite3.Row + _db_conn.execute(""" + CREATE TABLE IF NOT EXISTS memories ( + id TEXT PRIMARY KEY, + content TEXT NOT NULL, + category TEXT NOT NULL DEFAULT 'stable', + source TEXT NOT NULL DEFAULT 'manual', + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL + ) + """) + # Temporaere Eintraege nach 7 Tagen automatisch loeschen + _db_conn.execute( + "DELETE FROM memories WHERE category = 'ephemeral'" + " AND datetime(created_at) < datetime('now', '-7 days')" + ) + _db_conn.commit() + return _db_conn + + +class _MemIn(BaseModel): + content: str + category: str = "stable" # stable | versioned | ephemeral + source: str = "manual" + + +class _MemUp(BaseModel): + content: Optional[str] = None + category: Optional[str] = None + + +def _row(r: sqlite3.Row) -> dict: + return dict(r) + + +# Export muss vor /{mid} stehen, sonst wuerde FastAPI "export" als ID behandeln +@router.get("/memory/export") +def export_memories(): + """Alle Eintraege als strukturierter Plain-Text — direkt als System-Prompt-Kontext nutzbar.""" + db = _db() + rows = db.execute( + "SELECT * FROM memories ORDER BY category, updated_at DESC" + ).fetchall() + cat_names = { + "stable": "Stabile Fakten", + "versioned": "Versionierte Infos", + "ephemeral": "Temporaerer Kontext", + } + lines = ["# Mission Control — Gedaechtnis\n"] + current = "" + for r in rows: + cat = cat_names.get(r["category"], r["category"]) + if cat != current: + lines.append(f"\n## {cat}\n") + current = cat + lines.append( + f"- {r['content']} _(Quelle: {r['source']}, {r['updated_at'][:10]})_" + ) + return {"text": "\n".join(lines), "count": len(rows)} + + +@router.get("/memory") +def list_memories(q: str = "", category: str = ""): + db = _db() + sql = "SELECT * FROM memories" + params: list = [] + conds: list = [] + if q: + conds.append("content LIKE ?") + params.append(f"%{q}%") + if category: + conds.append("category = ?") + params.append(category) + if conds: + sql += " WHERE " + " AND ".join(conds) + sql += " ORDER BY created_at DESC" + return [_row(r) for r in db.execute(sql, params).fetchall()] + + +@router.post("/memory", status_code=201) +def add_memory(body: _MemIn): + now = datetime.now(timezone.utc).isoformat() + mid = str(uuid.uuid4()) + db = _db() + db.execute( + "INSERT INTO memories (id, content, category, source, created_at, updated_at)" + " VALUES (?,?,?,?,?,?)", + (mid, body.content.strip(), body.category, body.source, now, now), + ) + db.commit() + return { + "id": mid, "content": body.content.strip(), + "category": body.category, "source": body.source, + "created_at": now, "updated_at": now, + } + + +@router.put("/memory/{mid}") +def update_memory(mid: str, body: _MemUp): + db = _db() + row = db.execute("SELECT * FROM memories WHERE id = ?", (mid,)).fetchone() + if not row: + raise HTTPException(404, "Eintrag nicht gefunden") + now = datetime.now(timezone.utc).isoformat() + content = body.content.strip() if body.content is not None else row["content"] + category = body.category if body.category is not None else row["category"] + db.execute( + "UPDATE memories SET content=?, category=?, updated_at=? WHERE id=?", + (content, category, now, mid), + ) + db.commit() + return { + "id": mid, "content": content, "category": category, + "source": row["source"], "created_at": row["created_at"], "updated_at": now, + } + + +@router.delete("/memory/{mid}") +def delete_memory(mid: str): + db = _db() + if not db.execute("SELECT id FROM memories WHERE id = ?", (mid,)).fetchone(): + raise HTTPException(404, "Eintrag nicht gefunden") + db.execute("DELETE FROM memories WHERE id = ?", (mid,)) + db.commit() + return {"ok": True} diff --git a/static/dist/main.js b/static/dist/main.js index e68a594..253992e 100644 --- a/static/dist/main.js +++ b/static/dist/main.js @@ -1,64 +1,75 @@ -var rl=Object.defineProperty;var Pr=e=>{throw TypeError(e)};var sl=(e,n,a)=>n in e?rl(e,n,{enumerable:!0,configurable:!0,writable:!0,value:a}):e[n]=a;var rn=(e,n,a)=>sl(e,typeof n!="symbol"?n+"":n,a),Ui=(e,n,a)=>n.has(e)||Pr("Cannot "+a);var p=(e,n,a)=>(Ui(e,n,"read from private field"),a?a.call(e):n.get(e)),pe=(e,n,a)=>n.has(e)?Pr("Cannot add the same private member more than once"):n instanceof WeakSet?n.add(e):n.set(e,a),ve=(e,n,a,i)=>(Ui(e,n,"write to private field"),i?i.call(e,a):n.set(e,a),a),Re=(e,n,a)=>(Ui(e,n,"access private method"),a);var br=Array.isArray,ll=Array.prototype.indexOf,Ci=Array.prototype.includes,Ri=Array.from,ol=Object.defineProperty,ei=Object.getOwnPropertyDescriptor,dl=Object.getOwnPropertyDescriptors,cl=Object.prototype,ul=Array.prototype,ds=Object.getPrototypeOf,$r=Object.isExtensible;const vl=()=>{};function pl(e){for(var n=0;n{e=i,n=r});return{promise:a,resolve:e,reject:n}}function Ca(e,n){if(Array.isArray(e))return e;if(n===void 0||!(Symbol.iterator in e))return Array.from(e);const a=[];for(const i of e)if(a.push(i),a.length===n)break;return a}const jt=2,Oa=4,Oi=8,us=1<<24,xn=16,Mn=32,ta=64,ir=128,hn=512,Ot=1024,Vt=2048,Ln=4096,Zt=8192,gn=16384,Wa=32768,rr=1<<25,Fa=65536,Ti=1<<17,fl=1<<18,Va=1<<19,hl=1<<20,Dn=1<<25,ka=65536,zi=1<<21,Ta=1<<22,ea=1<<23,za=Symbol("$state"),gl=Symbol(""),yi=Symbol("attributes"),sr=Symbol("class"),lr=Symbol("style"),Ja=Symbol("text"),xi=Symbol("form reset"),Fi=new class extends Error{constructor(){super(...arguments);rn(this,"name","StaleReactionError");rn(this,"message","The reaction that called `getAbortSignal()` was re-run or destroyed")}};var rs;const ml=!!((rs=globalThis.document)!=null&&rs.contentType)&&globalThis.document.contentType.includes("xml");function vs(e){throw new Error("https://svelte.dev/e/lifecycle_outside_component")}function bl(){throw new Error("https://svelte.dev/e/async_derived_orphan")}function _l(e,n,a){throw new Error("https://svelte.dev/e/each_key_duplicate")}function kl(e){throw new Error("https://svelte.dev/e/effect_in_teardown")}function wl(){throw new Error("https://svelte.dev/e/effect_in_unowned_derived")}function yl(e){throw new Error("https://svelte.dev/e/effect_orphan")}function xl(){throw new Error("https://svelte.dev/e/effect_update_depth_exceeded")}function Sl(){throw new Error("https://svelte.dev/e/state_descriptors_fixed")}function Ml(){throw new Error("https://svelte.dev/e/state_prototype_fixed")}function El(){throw new Error("https://svelte.dev/e/state_unsafe_mutation")}function Al(){throw new Error("https://svelte.dev/e/svelte_boundary_reset_onerror")}const Cl=1,Tl=2,ps=4,zl=8,Dl=16,Pl=1,$l=2,Rt=Symbol("uninitialized"),fs="http://www.w3.org/1999/xhtml",Ll="http://www.w3.org/2000/svg",Il="http://www.w3.org/1998/Math/MathML";function Bl(){console.warn("https://svelte.dev/e/derived_inert")}function Rl(){console.warn("https://svelte.dev/e/select_multiple_invalid_value")}function Ol(){console.warn("https://svelte.dev/e/svelte_boundary_reset_noop")}function hs(e){return e===this.v}function Fl(e,n){return e!=e?n==n:e!==n||e!==null&&typeof e=="object"||typeof e=="function"}function gs(e){return!Fl(e,this.v)}let Ut=null;function qa(e){Ut=e}function aa(e,n=!1,a){Ut={p:Ut,i:!1,c:null,e:null,s:e,x:null,r:ye,l:null}}function ia(e){var n=Ut,a=n.e;if(a!==null){n.e=null;for(var i of a)Os(i)}return n.i=!0,Ut=n.p,{}}function ms(){return!0}let la=[];function bs(){var e=la;la=[],pl(e)}function ga(e){if(la.length===0&&!ni){var n=la;queueMicrotask(()=>{n===la&&bs()})}la.push(e)}function ql(){for(;la.length>0;)bs()}function _s(e){var n=ye;if(n===null)return _e.f|=ea,e;if((n.f&Wa)===0&&(n.f&Oa)===0)throw e;Yn(e,n)}function Yn(e,n){if(!(n!==null&&(n.f&gn)!==0)){for(;n!==null;){if((n.f&ir)!==0){if((n.f&Wa)===0)throw e;try{n.b.error(e);return}catch(a){e=a}}n=n.parent}throw e}}const Nl=-7169;function Dt(e,n){e.f=e.f&Nl|n}function _r(e){(e.f&hn)!==0||e.deps===null?Dt(e,Ot):Dt(e,Ln)}function ks(e){if(e!==null)for(const n of e)(n.f&jt)===0||(n.f&ka)===0||(n.f^=ka,ks(n.deps))}function ws(e,n,a){(e.f&Vt)!==0?n.add(e):(e.f&Ln)!==0&&a.add(e),ks(e.deps),Dt(e,Ot)}function Kl(e){let n=0,a=ya(0),i;return()=>{Er()&&(t(a),qi(()=>(n===0&&(i=Ua(()=>e(()=>ai(a)))),n+=1,()=>{ga(()=>{n-=1,n===0&&(i==null||i(),i=void 0,ai(a))})})))}}var Gl=Fa|Va;function Wl(e,n,a,i){new Vl(e,n,a,i)}var cn,mr,un,ua,Xt,vn,Qt,ln,On,va,Qn,Da,ui,vi,Fn,Li,xt,Ul,jl,Hl,or,Si,Mi,dr,cr;class Vl{constructor(n,a,i,r){pe(this,xt);rn(this,"parent");rn(this,"is_pending",!1);rn(this,"transform_error");pe(this,cn);pe(this,mr,null);pe(this,un);pe(this,ua);pe(this,Xt);pe(this,vn,null);pe(this,Qt,null);pe(this,ln,null);pe(this,On,null);pe(this,va,0);pe(this,Qn,0);pe(this,Da,!1);pe(this,ui,new Set);pe(this,vi,new Set);pe(this,Fn,null);pe(this,Li,Kl(()=>(ve(this,Fn,ya(p(this,va))),()=>{ve(this,Fn,null)})));var o;ve(this,cn,n),ve(this,un,a),ve(this,ua,d=>{var c=ye;c.b=this,c.f|=ir,i(d)}),this.parent=ye.b,this.transform_error=r??((o=this.parent)==null?void 0:o.transform_error)??(d=>d),ve(this,Xt,Cr(()=>{Re(this,xt,or).call(this)},Gl))}defer_effect(n){ws(n,p(this,ui),p(this,vi))}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!p(this,un).pending}update_pending_count(n,a){Re(this,xt,dr).call(this,n,a),ve(this,va,p(this,va)+n),!(!p(this,Fn)||p(this,Da))&&(ve(this,Da,!0),ga(()=>{ve(this,Da,!1),p(this,Fn)&&Na(p(this,Fn),p(this,va))}))}get_effect_pending(){return p(this,Li).call(this),t(p(this,Fn))}error(n){if(!p(this,un).onerror&&!p(this,un).failed)throw n;X!=null&&X.is_fork?(p(this,vn)&&X.skip_effect(p(this,vn)),p(this,Qt)&&X.skip_effect(p(this,Qt)),p(this,ln)&&X.skip_effect(p(this,ln)),X.oncommit(()=>{Re(this,xt,cr).call(this,n)})):Re(this,xt,cr).call(this,n)}}cn=new WeakMap,mr=new WeakMap,un=new WeakMap,ua=new WeakMap,Xt=new WeakMap,vn=new WeakMap,Qt=new WeakMap,ln=new WeakMap,On=new WeakMap,va=new WeakMap,Qn=new WeakMap,Da=new WeakMap,ui=new WeakMap,vi=new WeakMap,Fn=new WeakMap,Li=new WeakMap,xt=new WeakSet,Ul=function(){try{ve(this,vn,pn(()=>p(this,ua).call(this,p(this,cn))))}catch(n){this.error(n)}},jl=function(n){const a=p(this,un).failed;a&&ve(this,ln,pn(()=>{a(p(this,cn),()=>n,()=>()=>{})}))},Hl=function(){const n=p(this,un).pending;n&&(this.is_pending=!0,ve(this,Qt,pn(()=>n(p(this,cn)))),ga(()=>{var a=ve(this,On,document.createDocumentFragment()),i=Kn();a.append(i),ve(this,vn,Re(this,xt,Mi).call(this,()=>pn(()=>p(this,ua).call(this,i)))),p(this,Qn)===0&&(p(this,cn).before(a),ve(this,On,null),ba(p(this,Qt),()=>{ve(this,Qt,null)}),Re(this,xt,Si).call(this,X))}))},or=function(){try{if(this.is_pending=this.has_pending_snippet(),ve(this,Qn,0),ve(this,va,0),ve(this,vn,pn(()=>{p(this,ua).call(this,p(this,cn))})),p(this,Qn)>0){var n=ve(this,On,document.createDocumentFragment());zr(p(this,vn),n);const a=p(this,un).pending;ve(this,Qt,pn(()=>a(p(this,cn))))}else Re(this,xt,Si).call(this,X)}catch(a){this.error(a)}},Si=function(n){this.is_pending=!1,n.transfer_effects(p(this,ui),p(this,vi))},Mi=function(n){var a=ye,i=_e,r=Ut;In(p(this,Xt)),mn(p(this,Xt)),qa(p(this,Xt).ctx);try{return wa.ensure(),n()}catch(o){return _s(o),null}finally{In(a),mn(i),qa(r)}},dr=function(n,a){var i;if(!this.has_pending_snippet()){this.parent&&Re(i=this.parent,xt,dr).call(i,n,a);return}ve(this,Qn,p(this,Qn)+n),p(this,Qn)===0&&(Re(this,xt,Si).call(this,a),p(this,Qt)&&ba(p(this,Qt),()=>{ve(this,Qt,null)}),p(this,On)&&(p(this,cn).before(p(this,On)),ve(this,On,null)))},cr=function(n){p(this,vn)&&(nn(p(this,vn)),ve(this,vn,null)),p(this,Qt)&&(nn(p(this,Qt)),ve(this,Qt,null)),p(this,ln)&&(nn(p(this,ln)),ve(this,ln,null));var a=p(this,un).onerror;let i=p(this,un).failed;var r=!1,o=!1;const d=()=>{if(r){Ol();return}r=!0,o&&Al(),p(this,ln)!==null&&ba(p(this,ln),()=>{ve(this,ln,null)}),Re(this,xt,Mi).call(this,()=>{Re(this,xt,or).call(this)})},c=u=>{try{o=!0,a==null||a(u,d),o=!1}catch(v){Yn(v,p(this,Xt)&&p(this,Xt).parent)}i&&ve(this,ln,Re(this,xt,Mi).call(this,()=>{try{return pn(()=>{var v=ye;v.b=this,v.f|=ir,i(p(this,cn),()=>u,()=>d)})}catch(v){return Yn(v,p(this,Xt).parent),null}}))};ga(()=>{var u;try{u=this.transform_error(n)}catch(v){Yn(v,p(this,Xt)&&p(this,Xt).parent);return}u!==null&&typeof u=="object"&&typeof u.then=="function"?u.then(c,v=>Yn(v,p(this,Xt)&&p(this,Xt).parent)):c(u)})};function Jl(e,n,a,i){const r=kr;var o=e.filter(y=>!y.settled),d=n.map(r);if(a.length===0&&o.length===0){i(d);return}var c=ye,u=Ql(),v=o.length===1?o[0].promise:o.length>1?Promise.all(o.map(y=>y.promise)):null;function g(y){if((c.f&gn)===0){u();try{i([...d,...y])}catch(T){Yn(T,c)}Di()}}var E=ys();if(a.length===0){v.then(()=>g([])).finally(E);return}function f(){Promise.all(a.map(y=>Zl(y))).then(g).catch(y=>Yn(y,c)).finally(E)}v?v.then(()=>{u(),f(),Di()}):f()}function Ql(){var e=ye,n=_e,a=Ut,i=X;return function(o=!0){In(e),mn(n),qa(a),o&&(e.f&gn)===0&&(i==null||i.activate(),i==null||i.apply())}}function Di(e=!0){In(null),mn(null),qa(null),e&&(X==null||X.deactivate())}function ys(){var e=ye,n=e.b,a=X,i=!!(n!=null&&n.is_rendered());return n==null||n.update_pending_count(1,a),a.increment(i,e),()=>{n==null||n.update_pending_count(-1,a),a.decrement(i,e)}}function kr(e){var n=jt|Vt;return ye!==null&&(ye.f|=Va),{ctx:Ut,deps:null,effects:null,equals:hs,f:n,fn:e,reactions:null,rv:0,v:Rt,wv:0,parent:ye,ac:null}}const Qa=Symbol("obsolete");function Zl(e,n,a){let i=ye;i===null&&bl();var r=void 0,o=ya(Rt),d=!_e,c=new Set;return ho(()=>{var y,T;var u=ye,v=cs();r=v.promise;try{Promise.resolve(e()).then(v.resolve,D=>{D!==Fi&&v.reject(D)}).finally(Di)}catch(D){v.reject(D),Di()}var g=X;if(d){if((u.f&Wa)!==0)var E=ys();if((y=i.b)!=null&&y.is_rendered())(T=g.async_deriveds.get(u))==null||T.reject(Qa);else for(const D of c.values())D.reject(Qa);c.add(v),g.async_deriveds.set(u,v)}const f=(D,S=void 0)=>{E==null||E(),c.delete(v),S!==Qa&&(g.activate(),S?(o.f|=ea,Na(o,S)):((o.f&ea)!==0&&(o.f^=ea),Na(o,D)),g.deactivate())};v.promise.then(f,D=>f(null,D||"unknown"))}),Rs(()=>{for(const u of c)u.reject(Qa)}),new Promise(u=>{function v(g){function E(){g===r?u(o):v(r)}g.then(E,E)}v(r)})}function I(e){const n=kr(e);return Vs(n),n}function Yl(e){const n=kr(e);return n.equals=gs,n}function Xl(e){var n=e.effects;if(n!==null){e.effects=null;for(var a=0;athis.schedule(i)){var i=p(this,Tn).get(n);if(i){p(this,Tn).delete(n);for(var r of i.d)Dt(r,Vt),a(r);for(r of i.m)Dt(r,Ln),a(r)}p(this,Ra).add(n)}capture(n,a,i=!1){n.v!==Rt&&!this.previous.has(n)&&this.previous.set(n,n.v),(n.f&ea)===0&&(this.current.set(n,[a,i]),Wt==null||Wt.set(n,a)),this.is_fork||(n.v=a)}activate(){X=this}deactivate(){X=null,Wt=null}flush(){try{Hi=!0,X=this,Re(this,Ve,Za).call(this)}finally{Lr=0,ur=null,Aa=null,Ei=null,Hi=!1,X=null,Wt=null,ma.clear()}}discard(){var n;for(const a of p(this,La))a(this);p(this,La).clear();for(const a of this.async_deriveds.values())a.reject(Qa);Re(this,Ve,Ya).call(this),(n=p(this,Ba))==null||n.resolve()}register_created_effect(n){p(this,pi).push(n)}increment(n,a){if(ve(this,Ia,p(this,Ia)+1),n){let i=p(this,qn).get(a)??0;p(this,qn).set(a,i+1)}}decrement(n,a){if(ve(this,Ia,p(this,Ia)-1),n){let i=p(this,qn).get(a)??0;i===1?p(this,qn).delete(a):p(this,qn).set(a,i-1)}p(this,fa)||(ve(this,fa,!0),ga(()=>{ve(this,fa,!1),this.linked&&this.flush()}))}transfer_effects(n,a){for(const i of n)p(this,Nn).add(i);for(const i of a)p(this,kn).add(i);n.clear(),a.clear()}oncommit(n){p(this,$a).add(n)}ondiscard(n){p(this,La).add(n)}settled(){return(p(this,Ba)??ve(this,Ba,cs())).promise}static ensure(){if(X===null){const n=X=new Ii;!Hi&&!ni&&ga(()=>{p(n,Pa)||n.flush()})}return X}apply(){{Wt=null;return}}schedule(n){var r;if(ur=n,(r=n.b)!=null&&r.is_pending&&(n.f&(Oa|Oi|us))!==0&&(n.f&Wa)===0){n.b.defer_effect(n);return}for(var a=n;a.parent!==null;){a=a.parent;var i=a.f;if(Aa!==null&&a===ye&&(_e===null||(_e.f&jt)===0))return;if((i&(ta|Mn))!==0){if((i&Ot)===0)return;a.f^=Ot}}p(this,en).push(a)}};Pa=new WeakMap,Zn=new WeakMap,pa=new WeakMap,$a=new WeakMap,La=new WeakMap,Ia=new WeakMap,qn=new WeakMap,Ba=new WeakMap,en=new WeakMap,pi=new WeakMap,Nn=new WeakMap,kn=new WeakMap,Tn=new WeakMap,Ra=new WeakMap,fa=new WeakMap,Ve=new WeakSet,vr=function(){if(this.is_fork)return!0;for(const i of p(this,qn).keys()){for(var n=i,a=!1;n.parent!==null;){if(p(this,Tn).has(n)){a=!0;break}n=n.parent}if(!a)return!0}return!1},Za=function(){var u,v,g,E;ve(this,Pa,!0),Lr++>1e3&&(Re(this,Ve,Ya).call(this),io());for(const f of p(this,Nn))p(this,kn).delete(f),Dt(f,Vt),this.schedule(f);for(const f of p(this,kn))Dt(f,Ln),this.schedule(f);const n=p(this,en);ve(this,en,[]),this.apply();var a=Aa=[],i=[],r=Ei=[];for(const f of n)try{Re(this,Ve,pr).call(this,f,a,i)}catch(y){throw Ts(f),Re(this,Ve,vr).call(this)||this.discard(),y}if(X=null,r.length>0){var o=Ii.ensure();for(const f of r)o.schedule(f)}if(Aa=null,Ei=null,Re(this,Ve,vr).call(this)){Re(this,Ve,Ea).call(this,i),Re(this,Ve,Ea).call(this,a);for(const[f,y]of p(this,Tn))Cs(f,y);r.length>0&&Re(u=X,Ve,Za).call(u);return}const d=Re(this,Ve,Ms).call(this);if(d){Re(this,Ve,Ea).call(this,i),Re(this,Ve,Ea).call(this,a),Re(v=d,Ve,Es).call(v,this);return}p(this,Nn).clear(),p(this,kn).clear();for(const f of p(this,$a))f(this);p(this,$a).clear(),ti=this,Ir(i),Ir(a),ti=null,(g=p(this,Ba))==null||g.resolve();var c=X;if(p(this,Ia)===0&&(p(this,en).length===0||c!==null)&&Re(this,Ve,Ya).call(this),p(this,en).length>0)if(c!==null){const f=c;p(f,en).push(...p(this,en).filter(y=>!p(f,en).includes(y)))}else c=this;c!==null&&Re(E=c,Ve,Za).call(E)},pr=function(n,a,i){n.f^=Ot;for(var r=n.first;r!==null;){var o=r.f,d=(o&(Mn|ta))!==0,c=d&&(o&Ot)!==0,u=c||(o&Zt)!==0||p(this,Tn).has(r);if(!u&&r.fn!==null){d?r.f^=Ot:(o&Oa)!==0?a.push(r):mi(r)&&((o&xn)!==0&&p(this,kn).add(r),Ka(r));var v=r.first;if(v!==null){r=v;continue}}for(;r!==null;){var g=r.next;if(g!==null){r=g;break}r=r.parent}}},Ms=function(){for(var n=p(this,Zn);n!==null;){if(!n.is_fork){for(const[a,[,i]]of this.current)if(n.current.has(a)&&!i)return n}n=p(n,Zn)}return null},Es=function(n){var i;for(const[r,o]of n.current)!this.previous.has(r)&&n.previous.has(r)&&this.previous.set(r,n.previous.get(r)),this.current.set(r,o);for(const[r,o]of n.async_deriveds){const d=this.async_deriveds.get(r);d&&o.promise.then(d.resolve).catch(d.reject)}n.async_deriveds.clear(),this.transfer_effects(p(n,Nn),p(n,kn));const a=r=>{var o=r.reactions;if(o!==null)for(const u of o){var d=u.f;if((d&jt)!==0)a(u);else{var c=u;d&(Ta|xn)&&!this.async_deriveds.has(c)&&(p(this,kn).delete(c),Dt(c,Vt),this.schedule(c))}}};for(const r of this.current.keys())a(r);this.oncommit(()=>n.discard()),Re(i=n,Ve,Ya).call(i),X=this,Re(this,Ve,Za).call(this)},Ea=function(n){for(var a=0;a!f.current.get(y)[1]);if(!(!p(f,Pa)||r.length===0)){var o=r.filter(y=>!this.current.has(y));if(o.length===0)n&&f.discard();else if(a.length>0){if(n)for(const y of p(this,Ra))f.unskip_effect(y,T=>{var D;(T.f&(xn|Ta))!==0?f.schedule(T):Re(D=f,Ve,Ea).call(D,[T])});f.activate();var d=new Set,c=new Map;for(var u of a)As(u,o,d,c);c=new Map;var v=[...f.current].filter(([y,T])=>{const D=this.current.get(y);return D?D[0]!==T[0]||D[1]!==T[1]:!0}).map(([y])=>y);if(v.length>0)for(const y of p(this,pi))(y.f&(gn|Zt|Ti))===0&&yr(y,v,c)&&((y.f&(Ta|xn))!==0?(Dt(y,Vt),f.schedule(y)):p(f,Nn).add(y));if(p(f,en).length>0&&!p(f,fa)){f.apply();for(var g of p(f,en))Re(E=f,Ve,pr).call(E,g,[],[]);ve(f,en,[])}f.deactivate()}}}},Ya=function(){if(this.linked){var n=p(this,Zn),a=p(this,pa);n===null?ji=a:ve(n,pa,a),a===null?Ma=n:ve(a,Zn,n),this.linked=!1}};let wa=Ii;function ao(e){var n=ni;ni=!0;try{for(var a;;){if(ql(),X===null)return a;X.flush()}}finally{ni=n}}function io(){try{xl()}catch(e){Yn(e,ur)}}let _n=null;function Ir(e){var n=e.length;if(n!==0){for(var a=0;a0)){ma.clear();for(const r of _n){if((r.f&(gn|Zt))!==0)continue;const o=[r];let d=r.parent;for(;d!==null;)_n.has(d)&&(_n.delete(d),o.push(d)),d=d.parent;for(let c=o.length-1;c>=0;c--){const u=o[c];(u.f&(gn|Zt))===0&&Ka(u)}}_n.clear()}}_n=null}}function As(e,n,a,i){if(!a.has(e)&&(a.add(e),e.reactions!==null))for(const r of e.reactions){const o=r.f;(o&jt)!==0?As(r,n,a,i):(o&(Ta|xn))!==0&&(o&Vt)===0&&yr(r,n,i)&&(Dt(r,Vt),xr(r))}}function yr(e,n,a){const i=a.get(e);if(i!==void 0)return i;if(e.deps!==null)for(const r of e.deps){if(Ci.call(n,r))return!0;if((r.f&jt)!==0&&yr(r,n,a))return a.set(r,!0),!0}return a.set(e,!1),!1}function xr(e){X.schedule(e)}function Cs(e,n){if(!((e.f&Mn)!==0&&(e.f&Ot)!==0)){(e.f&Vt)!==0?n.d.push(e):(e.f&Ln)!==0&&n.m.push(e),Dt(e,Ot);for(var a=e.first;a!==null;)Cs(a,n),a=a.next}}function Ts(e){Dt(e,Ot);for(var n=e.first;n!==null;)Ts(n),n=n.next}let Pi=new Set;const ma=new Map;let zs=!1;function ya(e,n){var a={f:0,v:e,reactions:null,equals:hs,rv:0,wv:0};return a}function O(e,n){const a=ya(e);return Vs(a),a}function ro(e,n=!1,a=!0){const i=ya(e);return n||(i.equals=gs),i}function h(e,n,a=!1){_e!==null&&(!Sn||(_e.f&Ti)!==0)&&ms()&&(_e.f&(jt|xn|Ta|Ti))!==0&&(Pn===null||!Pn.has(e))&&El();let i=a?Ht(n):n;return Na(e,i,Ei)}function Na(e,n,a=null){if(!e.equals(n)){ma.set(e,na?n:e.v);var i=wa.ensure();if(i.capture(e,n),(e.f&jt)!==0){const r=e;(e.f&Vt)!==0&&wr(r),Wt===null&&_r(r)}e.wv=js(),Ds(e,Vt,a),ye!==null&&(ye.f&Ot)!==0&&(ye.f&(Mn|ta))===0&&(dn===null?mo([e]):dn.push(e)),!i.is_fork&&Pi.size>0&&!zs&&so()}return n}function so(){zs=!1;for(const e of Pi){(e.f&Ot)!==0&&Dt(e,Ln);let n;try{n=mi(e)}catch{n=!0}n&&Ka(e)}Pi.clear()}function ai(e){h(e,e.v+1)}function Ds(e,n,a){var i=e.reactions;if(i!==null)for(var r=i.length,o=0;o{if(_a===o)return c();var u=_e,v=_a;mn(null),qr(o);var g=c();return mn(u),qr(v),g};return i&&a.set("length",O(e.length)),new Proxy(e,{defineProperty(c,u,v){(!("value"in v)||v.configurable===!1||v.enumerable===!1||v.writable===!1)&&Sl();var g=a.get(u);return g===void 0?d(()=>{var E=O(v.value);return a.set(u,E),E}):h(g,v.value,!0),!0},deleteProperty(c,u){var v=a.get(u);if(v===void 0){if(u in c){const g=d(()=>O(Rt));a.set(u,g),ai(r)}}else h(v,Rt),ai(r);return!0},get(c,u,v){var y;if(u===za)return e;var g=a.get(u),E=u in c;if(g===void 0&&(!E||(y=ei(c,u))!=null&&y.writable)&&(g=d(()=>{var T=Ht(E?c[u]:Rt),D=O(T);return D}),a.set(u,g)),g!==void 0){var f=t(g);return f===Rt?void 0:f}return Reflect.get(c,u,v)},getOwnPropertyDescriptor(c,u){var v=Reflect.getOwnPropertyDescriptor(c,u);if(v&&"value"in v){var g=a.get(u);g&&(v.value=t(g))}else if(v===void 0){var E=a.get(u),f=E==null?void 0:E.v;if(E!==void 0&&f!==Rt)return{enumerable:!0,configurable:!0,value:f,writable:!0}}return v},has(c,u){var f;if(u===za)return!0;var v=a.get(u),g=v!==void 0&&v.v!==Rt||Reflect.has(c,u);if(v!==void 0||ye!==null&&(!g||(f=ei(c,u))!=null&&f.writable)){v===void 0&&(v=d(()=>{var y=g?Ht(c[u]):Rt,T=O(y);return T}),a.set(u,v));var E=t(v);if(E===Rt)return!1}return g},set(c,u,v,g){var oe;var E=a.get(u),f=u in c;if(i&&u==="length")for(var y=v;yO(Rt)),a.set(y+"",T))}if(E===void 0)(!f||(oe=ei(c,u))!=null&&oe.writable)&&(E=d(()=>O(void 0)),h(E,Ht(v)),a.set(u,E));else{f=E.v!==Rt;var D=d(()=>Ht(v));h(E,D)}var S=Reflect.getOwnPropertyDescriptor(c,u);if(S!=null&&S.set&&S.set.call(g,v),!f){if(i&&typeof u=="string"){var $=a.get("length"),Ce=Number(u);Number.isInteger(Ce)&&Ce>=$.v&&h($,Ce+1)}ai(r)}return!0},ownKeys(c){t(r);var u=Reflect.ownKeys(c).filter(E=>{var f=a.get(E);return f===void 0||f.v!==Rt});for(var[v,g]of a)g.v!==Rt&&!(v in c)&&u.push(v);return u},setPrototypeOf(){Ml()}})}function Br(e){try{if(e!==null&&typeof e=="object"&&za in e)return e[za]}catch{}return e}function lo(e,n){return Object.is(Br(e),Br(n))}var Rr,Ps,$s,Ls;function oo(){if(Rr===void 0){Rr=window,Ps=/Firefox/.test(navigator.userAgent);var e=Element.prototype,n=Node.prototype,a=Text.prototype;$s=ei(n,"firstChild").get,Ls=ei(n,"nextSibling").get,$r(e)&&(e[sr]=void 0,e[yi]=null,e[lr]=void 0,e.__e=void 0),$r(a)&&(a[Ja]=void 0)}}function Kn(e=""){return document.createTextNode(e)}function Xn(e){return $s.call(e)}function gi(e){return Ls.call(e)}function l(e,n){return Xn(e)}function We(e,n=!1){{var a=Xn(e);return a instanceof Comment&&a.data===""?gi(a):a}}function s(e,n=1,a=!1){let i=e;for(;n--;)i=gi(i);return i}function co(e){e.textContent=""}function Is(){return!1}function Bs(e,n,a){return n==null||n===fs?a?document.createElement(e,{is:a}):document.createElement(e):a?document.createElementNS(n,e,{is:a}):document.createElementNS(n,e)}let Or=!1;function uo(){Or||(Or=!0,document.addEventListener("reset",e=>{Promise.resolve().then(()=>{var n;if(!e.defaultPrevented)for(const a of e.target.elements)(n=a[xi])==null||n.call(a)})},{capture:!0}))}function Sr(e){var n=_e,a=ye;mn(null),In(null);try{return e()}finally{mn(n),In(a)}}function Mr(e,n,a,i=a){e.addEventListener(n,()=>Sr(a));const r=e[xi];r?e[xi]=()=>{r(),i(!0)}:e[xi]=()=>i(!0),uo()}function vo(e){ye===null&&(_e===null&&yl(),wl()),na&&kl()}function po(e,n){var a=n.last;a===null?n.last=n.first=e:(a.next=e,e.prev=a,n.last=e)}function Gn(e,n){var a=ye;a!==null&&(a.f&Zt)!==0&&(e|=Zt);var i={ctx:Ut,deps:null,nodes:null,f:e|Vt|hn,first:null,fn:n,last:null,next:null,parent:a,b:a&&a.b,prev:null,teardown:null,wv:0,ac:null};X==null||X.register_created_effect(i);var r=i;if((e&Oa)!==0)Aa!==null?Aa.push(i):wa.ensure().schedule(i);else if(n!==null){try{Ka(i)}catch(d){throw nn(i),d}r.deps===null&&r.teardown===null&&r.nodes===null&&r.first===r.last&&(r.f&Va)===0&&(r=r.first,(e&xn)!==0&&(e&Fa)!==0&&r!==null&&(r.f|=Fa))}if(r!==null&&(r.parent=a,a!==null&&po(r,a),_e!==null&&(_e.f&jt)!==0&&(e&ta)===0)){var o=_e;(o.effects??(o.effects=[])).push(r)}return i}function Er(){return _e!==null&&!Sn}function Rs(e){const n=Gn(Oi,null);return Dt(n,Ot),n.teardown=e,n}function Ar(e){vo();var n=ye.f,a=!_e&&(n&Mn)!==0&&Ut!==null&&!Ut.i;if(a){var i=Ut;(i.e??(i.e=[])).push(e)}else return Os(e)}function Os(e){return Gn(Oa|hl,e)}function fo(e){wa.ensure();const n=Gn(ta|Va,e);return(a={})=>new Promise(i=>{a.outro?ba(n,()=>{nn(n),i(void 0)}):(nn(n),i(void 0))})}function Fs(e){return Gn(Oa,e)}function ho(e){return Gn(Ta|Va,e)}function qi(e,n=0){return Gn(Oi|n,e)}function P(e,n=[],a=[],i=[]){Jl(i,n,a,r=>{Gn(Oi,()=>{e(...r.map(t))})})}function Cr(e,n=0){var a=Gn(xn|n,e);return a}function pn(e){return Gn(Mn|Va,e)}function qs(e){var n=e.teardown;if(n!==null){const a=na,i=_e;Fr(!0),mn(null);try{n.call(null)}finally{Fr(a),mn(i)}}}function Tr(e,n=!1){var a=e.first;for(e.first=e.last=null;a!==null;){const r=a.ac;r!==null&&Sr(()=>{r.abort(Fi)});var i=a.next;(a.f&ta)!==0?a.parent=null:nn(a,n),a=i}}function go(e){for(var n=e.first;n!==null;){var a=n.next;(n.f&Mn)===0&&nn(n),n=a}}function nn(e,n=!0){var a=!1;(n||(e.f&fl)!==0)&&e.nodes!==null&&e.nodes.end!==null&&(Ns(e.nodes.start,e.nodes.end),a=!0),e.f|=rr,Tr(e,n&&!a),oi(e,0);var i=e.nodes&&e.nodes.t;if(i!==null)for(const o of i)o.stop();qs(e),e.f^=rr,e.f|=gn;var r=e.parent;r!==null&&r.first!==null&&Ks(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Ns(e,n){for(;e!==null;){var a=e===n?null:gi(e);e.remove(),e=a}}function Ks(e){var n=e.parent,a=e.prev,i=e.next;a!==null&&(a.next=i),i!==null&&(i.prev=a),n!==null&&(n.first===e&&(n.first=i),n.last===e&&(n.last=a))}function ba(e,n,a=!0){var i=[];Gs(e,i,!0);var r=()=>{a&&nn(e),n&&n()},o=i.length;if(o>0){var d=()=>--o||r();for(var c of i)c.out(d)}else r()}function Gs(e,n,a){if((e.f&Zt)===0){e.f^=Zt;var i=e.nodes&&e.nodes.t;if(i!==null)for(const c of i)(c.is_global||a)&&n.push(c);for(var r=e.first;r!==null;){var o=r.next;if((r.f&ta)===0){var d=(r.f&Fa)!==0||(r.f&Mn)!==0&&(e.f&xn)!==0;Gs(r,n,d?a:!1)}r=o}}}function $i(e){Ws(e,!0)}function Ws(e,n){if((e.f&Zt)!==0){e.f^=Zt,(e.f&Ot)===0&&(Dt(e,Vt),wa.ensure().schedule(e));for(var a=e.first;a!==null;){var i=a.next,r=(a.f&Fa)!==0||(a.f&Mn)!==0;Ws(a,r?n:!1),a=i}var o=e.nodes&&e.nodes.t;if(o!==null)for(const d of o)(d.is_global||n)&&d.in()}}function zr(e,n){if(e.nodes)for(var a=e.nodes.start,i=e.nodes.end;a!==null;){var r=a===i?null:gi(a);n.append(a),a=r}}let Ai=!1,na=!1;function Fr(e){na=e}let _e=null,Sn=!1;function mn(e){_e=e}let ye=null;function In(e){ye=e}let Pn=null;function Vs(e){_e!==null&&(Pn??(Pn=new Set)).add(e)}let tn=null,sn=0,dn=null;function mo(e){dn=e}let Us=1,oa=0,_a=oa;function qr(e){_a=e}function js(){return++Us}function mi(e){var n=e.f;if((n&Vt)!==0)return!0;if(n&jt&&(e.f&=~ka),(n&Ln)!==0){for(var a=e.deps,i=a.length,r=0;re.wv)return!0}(n&hn)!==0&&Wt===null&&Dt(e,Ot)}return!1}function Hs(e,n,a=!0){var i=e.reactions;if(i!==null&&!(Pn!==null&&Pn.has(e)))for(var r=0;r{e.ac.abort(Fi)}),e.ac=null);try{e.f|=zi;var g=e.fn,E=g();e.f|=Wa;var f=e.deps,y=X==null?void 0:X.is_fork;if(tn!==null){var T;if(y||oi(e,sn),f!==null&&sn>0)for(f.length=sn+tn.length,T=0;T{throw $});throw f}}finally{e[da]=n,delete e.currentTarget,mn(g),In(E)}}}var ss;const Ji=((ss=globalThis==null?void 0:globalThis.window)==null?void 0:ss.trustedTypes)&&globalThis.window.trustedTypes.createPolicy("svelte-trusted-html",{createHTML:e=>e});function yo(e){return(Ji==null?void 0:Ji.createHTML(e))??e}function xo(e){var n=Bs("template");return n.innerHTML=yo(e.replaceAll("","")),n.content}function Ga(e,n){var a=ye;a.nodes===null&&(a.nodes={start:e,end:n,a:null,t:null})}function w(e,n){var a=(n&Pl)!==0,i=(n&$l)!==0,r,o=!e.startsWith("");return()=>{r===void 0&&(r=xo(o?e:""+e),a||(r=Xn(r)));var d=i||Ps?document.importNode(r,!0):r.cloneNode(!0);if(a){var c=Xn(d),u=d.lastChild;Ga(c,u)}else Ga(d,d);return d}}function ii(e=""){{var n=Kn(e+"");return Ga(n,n),n}}function di(){var e=document.createDocumentFragment(),n=document.createComment(""),a=Kn();return e.append(n,a),Ga(n,a),e}function m(e,n){e!==null&&e.before(n)}function b(e,n){var a=n==null?"":typeof n=="object"?`${n}`:n;a!==(e[Ja]??(e[Ja]=e.nodeValue))&&(e[Ja]=a,e.nodeValue=`${a}`)}function So(e,n){return Mo(e,n)}const wi=new Map;function Mo(e,{target:n,anchor:a,props:i={},events:r,context:o,intro:d=!0,transformError:c}){oo();var u=void 0,v=fo(()=>{var g=a??n.appendChild(Kn());Wl(g,{pending:()=>{}},y=>{aa({});var T=Ut;o&&(T.c=o),r&&(i.$$events=r),u=e(y,i)||{},ia()},c);var E=new Set,f=y=>{for(var T=0;T{var S;for(var y of E)for(const $ of[n,document]){var T=wi.get($),D=T.get(y);--D==0?($.removeEventListener(y,Kr),T.delete(y),T.size===0&&wi.delete($)):T.set(y,D)}fr.delete(f),g!==a&&((S=g.parentNode)==null||S.removeChild(g))}});return Eo.set(u,v),u}let Eo=new WeakMap;var wn,zn,on,ha,fi,hi,Bi;class Ao{constructor(n,a=!0){rn(this,"anchor");pe(this,wn,new Map);pe(this,zn,new Map);pe(this,on,new Map);pe(this,ha,new Set);pe(this,fi,!0);pe(this,hi,n=>{if(p(this,wn).has(n)){var a=p(this,wn).get(n),i=p(this,zn).get(a);if(i)$i(i),p(this,ha).delete(a);else{var r=p(this,on).get(a);r&&($i(r.effect),p(this,zn).set(a,r.effect),p(this,on).delete(a),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),i=r.effect)}for(const[o,d]of p(this,wn)){if(p(this,wn).delete(o),o===n)break;const c=p(this,on).get(d);c&&(nn(c.effect),p(this,on).delete(d))}for(const[o,d]of p(this,zn)){if(o===a||p(this,ha).has(o))continue;const c=()=>{if(Array.from(p(this,wn).values()).includes(o)){var v=document.createDocumentFragment();zr(d,v),v.append(Kn()),p(this,on).set(o,{effect:d,fragment:v})}else nn(d);p(this,ha).delete(o),p(this,zn).delete(o)};p(this,fi)||!i?(p(this,ha).add(o),ba(d,c,!1)):c()}}});pe(this,Bi,n=>{p(this,wn).delete(n);const a=Array.from(p(this,wn).values());for(const[i,r]of p(this,on))a.includes(i)||(nn(r.effect),p(this,on).delete(i))});this.anchor=n,ve(this,fi,a)}ensure(n,a){var i=X,r=Is();if(a&&!p(this,zn).has(n)&&!p(this,on).has(n))if(r){var o=document.createDocumentFragment(),d=Kn();o.append(d),p(this,on).set(n,{effect:pn(()=>a(d)),fragment:o})}else p(this,zn).set(n,pn(()=>a(this.anchor)));if(p(this,wn).set(i,n),r){for(const[c,u]of p(this,zn))c===n?i.unskip_effect(u):i.skip_effect(u);for(const[c,u]of p(this,on))c===n?i.unskip_effect(u.effect):i.skip_effect(u.effect);i.oncommit(p(this,hi)),i.ondiscard(p(this,Bi))}else p(this,hi).call(this,i)}}wn=new WeakMap,zn=new WeakMap,on=new WeakMap,ha=new WeakMap,fi=new WeakMap,hi=new WeakMap,Bi=new WeakMap;function K(e,n,a=!1){var i=new Ao(e),r=a?Fa:0;function o(d,c){i.ensure(d,c)}Cr(()=>{var d=!1;n((c,u=0)=>{d=!0,o(u,c)}),d||o(-1,null)},r)}function rt(e,n){return n}function Co(e,n,a){for(var i=[],r=n.length,o,d=n.length,c=0;c{if(o){if(o.pending.delete(E),o.done.add(E),o.pending.size===0){var f=e.outrogroups;hr(e,Ri(o.done)),f.delete(o),f.size===0&&(e.outrogroups=null)}}else d-=1},!1)}if(d===0){var u=i.length===0&&a!==null;if(u){var v=a,g=v.parentNode;co(g),g.append(v),e.items.clear()}hr(e,n,!u)}else o={pending:new Set(n),done:new Set},(e.outrogroups??(e.outrogroups=new Set)).add(o)}function hr(e,n,a=!0){var i;if(e.pending.size>0){i=new Set;for(const d of e.pending.values())for(const c of d)i.add(e.items.get(c).e)}for(var r=0;r{var oe=a();return br(oe)?oe:oe==null?[]:Ri(oe)}),f,y=new Map,T=!0;function D(oe){(Ce.effect.f&gn)===0&&(Ce.pending.delete(oe),Ce.fallback=g,To(Ce,f,d,n,i),g!==null&&(f.length===0?(g.f&Dn)===0?$i(g):(g.f^=Dn,Xa(g,null,d)):ba(g,()=>{g=null})))}function S(oe){Ce.pending.delete(oe)}var $=Cr(()=>{f=t(E);for(var oe=f.length,ae=new Set,xe=X,V=Is(),Q=0;Qo(d)):(g=pn(()=>o(Gr??(Gr=Kn()))),g.f|=Dn)),oe>ae.size&&_l(),!T)if(y.set(xe,ae),V){for(const[Ne,bt]of c)ae.has(Ne)||xe.skip_effect(bt.e);xe.oncommit(D),xe.ondiscard(S)}else D(xe);t(E)}),Ce={effect:$,items:c,pending:y,outrogroups:null,fallback:g};T=!1}function Ha(e){for(;e!==null&&(e.f&Mn)===0;)e=e.next;return e}function To(e,n,a,i,r){var Se,Ne,bt,C,Y,ue,Ue,te,Te;var o=(i&zl)!==0,d=n.length,c=e.items,u=Ha(e.effect.first),v,g=null,E,f=[],y=[],T,D,S,$;if(o)for($=0;$0){var be=(i&ps)!==0&&d===0?a:null;if(o){for($=0;${var ie,lt;if(E!==void 0)for(S of E)(lt=(ie=S.nodes)==null?void 0:ie.a)==null||lt.apply()})}function zo(e,n,a,i,r,o,d,c){var u=(d&Cl)!==0?(d&Dl)===0?ro(a,!1,!1):ya(a):null,v=(d&Tl)!==0?ya(r):null;return{v:u,i:v,e:pn(()=>(o(n,u??a,v??r,c),()=>{e.delete(i)}))}}function Xa(e,n,a){if(e.nodes)for(var i=e.nodes.start,r=e.nodes.end,o=n&&(n.f&Dn)===0?n.nodes.start:a;i!==null;){var d=gi(i);if(o.before(i),i===r)return;i=d}}function jn(e,n,a){n===null?e.effect.first=a:n.next=a,a===null?e.effect.last=n:a.prev=n}function Ae(e,n,a=!1,i=!1,r=!1,o=!1){var d=e,c="";if(a)var u=e;P(()=>{var v=ye;if(c!==(c=n()??"")){if(a){v.nodes=null,u.innerHTML=c,c!==""&&Ga(Xn(u),u.lastChild);return}if(v.nodes!==null&&(Ns(v.nodes.start,v.nodes.end),v.nodes=null),c!==""){var g=i?Ll:r?Il:void 0,E=Bs(i?"svg":r?"math":"template",g);E.innerHTML=c;var f=i||r?E:E.content;if(Ga(Xn(f),f.lastChild),i||r)for(;Xn(f);)d.before(Xn(f));else d.before(f)}}})}function Do(e,n,a){var i=e==null?"":""+e;return i===""?null:i}function Po(e,n){return e==null?null:String(e)}function kt(e,n,a,i,r,o){var d=e[sr];if(d!==a||d===void 0){var c=Do(a);c==null?e.removeAttribute("class"):e.className=c,e[sr]=a}return o}function fn(e,n,a,i){var r=e[lr];if(r!==n){var o=Po(n);o==null?e.removeAttribute("style"):e.style.cssText=o,e[lr]=n}return i}function Xs(e,n,a=!1){if(e.multiple){if(n==null)return;if(!br(n))return Rl();for(var i of e.options)i.selected=n.includes(si(i));return}for(i of e.options){var r=si(i);if(lo(r,n)){i.selected=!0;return}}(!a||n!==void 0)&&(e.selectedIndex=-1)}function $o(e){var n=new MutationObserver(()=>{Xs(e,e.__value)});n.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["value"]}),Rs(()=>{n.disconnect()})}function ri(e,n,a=n){var i=new WeakSet,r=!0;Mr(e,"change",o=>{var d=o?"[selected]":":checked",c;if(e.multiple)c=[].map.call(e.querySelectorAll(d),si);else{var u=e.querySelector(d)??e.querySelector("option:not([disabled])");c=u&&si(u)}a(c),e.__value=c,X!==null&&i.add(X)}),Fs(()=>{var o=n();if(e===document.activeElement){var d=X;if(i.has(d))return}if(Xs(e,o,r),r&&o===void 0){var c=e.querySelector(":checked");c!==null&&(o=si(c),a(o))}e.__value=o,r=!1}),$o(e)}function si(e){return"__value"in e?e.__value:e.value}const Lo=Symbol("is custom element"),Io=Symbol("is html"),Bo=ml?"progress":"PROGRESS";function Hn(e,n){var a=el(e);a.value===(a.value=n??void 0)||e.value===n&&(n!==0||e.nodeName!==Bo)||(e.value=n??"")}function Ni(e,n,a,i){var r=el(e);r[n]!==(r[n]=a)&&(n==="loading"&&(e[gl]=a),a==null?e.removeAttribute(n):typeof a!="string"&&Ro(e).includes(n)?e[n]=a:e.setAttribute(n,a))}function el(e){return e[yi]??(e[yi]={[Lo]:e.nodeName.includes("-"),[Io]:e.namespaceURI===fs})}var Wr=new Map;function Ro(e){var n=e.getAttribute("is")||e.nodeName,a=Wr.get(n);if(a)return a;Wr.set(n,a=[]);for(var i,r=e,o=Element.prototype;o!==r;){i=dl(r);for(var d in i)i[d].set&&d!=="innerHTML"&&d!=="textContent"&&d!=="innerText"&&a.push(d);r=ds(r)}return a}function Cn(e,n,a=n){var i=new WeakSet;Mr(e,"input",async r=>{var o=r?e.defaultValue:e.value;if(o=Qi(e)?Zi(o):o,a(o),X!==null&&i.add(X),await _o(),o!==(o=n())){var d=e.selectionStart,c=e.selectionEnd,u=e.value.length;if(e.value=o??"",c!==null){var v=e.value.length;d===c&&c===u&&v>u?(e.selectionStart=v,e.selectionEnd=v):(e.selectionStart=d,e.selectionEnd=Math.min(c,v))}}}),Ua(n)==null&&e.value&&(a(Qi(e)?Zi(e.value):e.value),X!==null&&i.add(X)),qi(()=>{var r=n();if(e===document.activeElement){var o=X;if(i.has(o))return}Qi(e)&&r===Zi(e.value)||e.type==="date"&&!r&&!e.value||r!==e.value&&(e.value=r??"")})}function Oo(e,n,a=n){Mr(e,"change",i=>{var r=i?e.defaultChecked:e.checked;a(r)}),Ua(n)==null&&a(e.checked),qi(()=>{var i=n();e.checked=!!i})}function Qi(e){var n=e.type;return n==="number"||n==="range"}function Zi(e){return e===""?null:+e}function Yi(e,n){return e===n||(e==null?void 0:e[za])===n}function Fo(e={},n,a,i){var r=Ut.r,o=ye;return Fs(()=>{var d,c;return qi(()=>{d=c,c=[],Ua(()=>{Yi(a(...c),e)||(n(e,...c),d&&Yi(a(...d),e)&&n(null,...d))})}),()=>{let u=o;for(;u!==r&&u.parent!==null&&u.parent.f&rr;)u=u.parent;const v=()=>{c&&Yi(a(...c),e)&&n(null,...c)},g=u.teardown;u.teardown=()=>{v(),g==null||g()}}}),e}function bi(e){Ut===null&&vs(),Ar(()=>{const n=Ua(e);if(typeof n=="function")return n})}function qo(e){Ut===null&&vs(),bi(()=>()=>Ua(e))}let ci=localStorage.getItem("mc_token")||"";function tl(){return ci}function No(e){ci=(e||"").trim(),localStorage.setItem("mc_token",ci)}function Ko(){const e={"Content-Type":"application/json"};return ci&&(e["X-MC-Token"]=ci),e}function li(){return localStorage.getItem("mc_hf_token")||""}function Go(e){localStorage.setItem("mc_hf_token",(e||"").trim())}async function we(e,n={}){const a=await fetch(e,{headers:Ko(),...n}),i=await a.json().catch(()=>({}));if(!a.ok)throw new Error(i.error||"HTTP "+a.status);return i}const Wo=(e,n=document)=>n.querySelector(e),Vr=(e,n=document)=>[...n.querySelectorAll(e)];function $n(e){return String(e??"").replace(/[&<>]/g,n=>({"&":"&","<":"<",">":">"})[n])}let Ur;function se(e,n=!1){const a=Wo("#toast");a&&(a.textContent=e,a.className="toast show"+(n?" err":""),clearTimeout(Ur),Ur=setTimeout(()=>a.className="toast",3200))}function Vo(e,n){return e==="running"||e==="ready"?'geladen':e==="loading"||e==="starting"?'lädt…':e==="downloading"?`↓ Download${n!=null?` ${Math.round(n)}%`:""}`:'bereit'}const Ge=e=>`${e}`,Ki={logo:Ge(''),grid:Ge(''),cpu:Ge(''),pulse:Ge(''),server:Ge(''),book:Ge(''),help:Ge(''),settings:Ge(''),swap:Ge(''),monitor:Ge(''),layers:Ge(''),alert:Ge(''),gauge:Ge(''),search:Ge(''),compass:Ge(''),code:Ge(''),eye:Ge(''),refresh:Ge(''),file:Ge(''),database:Ge(''),thermo:Ge(''),shield:Ge(''),info:Ge(''),chevron:Ge(''),bolt:Ge(''),x:Ge(''),check:Ge(''),download:Ge(''),clock:Ge('')};function Bt(e){return Ki[e]||""}function gr(e){return`${Ki.info}`}function sa(e){if(!e&&e!==0)return"–";const n=e/1024/1024/1024;return n>=1?n.toFixed(1)+" GB":Math.round(e/1024/1024)+" MB"}function yn({title:e,body:n,confirmLabel:a="Bestätigen",cancelLabel:i="Abbrechen",danger:r=!1}){return new Promise(o=>{const d=document.createElement("div");d.className="modal-overlay",d.innerHTML=``;const c=u=>{d.remove(),o(u)};d.addEventListener("click",u=>{if(u.target===d)return c(!1);const v=u.target.closest("[data-x]");v&&c(v.getAttribute("data-x")==="1")}),document.body.appendChild(d),d.querySelector('[data-x="1"]').focus()})}function jr({title:e,body:n="",placeholder:a="",password:i=!1,confirmLabel:l="Weiter",danger:o=!1}){return new Promise(d=>{const c=document.createElement("div");c.className="modal-overlay",c.innerHTML=``;const u=c.querySelector("input"),v=g=>{c.remove(),d(g)};c.addEventListener("click",g=>{if(g.target===c)return v(null);const E=g.target.closest("[data-x]");E&&v(E.getAttribute("data-x")==="1"?u.value||"":null)}),u.addEventListener("keydown",g=>{g.key==="Enter"&&v(u.value||""),g.key==="Escape"&&v(null)}),document.body.appendChild(c),u.focus()})}function Uo(e="overview"){const n=Vr(".nav-item[data-view]:not(.disabled)"),a=Vr(".view[data-view]"),i=new Set(a.map(o=>o.dataset.view));function r(o){i.has(o)||(o=e),a.forEach(d=>d.hidden=d.dataset.view!==o),n.forEach(d=>d.classList.toggle("active",d.dataset.view===o)),location.hash!=="#/"+o&&(location.hash="#/"+o)}return n.forEach(o=>o.addEventListener("click",d=>{d.preventDefault(),r(o.dataset.view)})),window.addEventListener("hashchange",()=>r(location.hash.replace("#/",""))),r(location.hash.replace("#/","")||e),{show:r}}let Hr=O(null);const _i={get value(){return t(Hr)},set(e){h(Hr,e,!0)}};let Jr=O(Ht([])),Jn=O(Ht([]));const ca={get value(){return t(Jr)},set(e){h(Jr,e||[],!0)},get tracked(){return t(Jn)},track(e){t(Jn).includes(e)||h(Jn,[...t(Jn),e],!0)},toggle(e){h(Jn,t(Jn).includes(e)?t(Jn).filter(n=>n!==e):[...t(Jn),e],!0)}};let Qr=O(null);const Dr={get value(){return t(Qr)},set(e){h(Qr,e,!0)}},jo="5";var ls;typeof window<"u"&&((ls=window.__svelte??(window.__svelte={})).v??(ls.v=new Set)).add(jo);var Ho=w('— bereit für Anfragen'),Jo=w('
Temperatur (GPU)
Freier Speicher
GB
',1),Qo=w('
Temperatur
messe…
Freier Speicher
messe…
',1),Zo=w('
'),Yo=w('
Warte auf Messwerte…
'),Xo=w('
Noch kein Modell eingerichtet — starte hier:
',1),ed=w('
Die häufigsten Aufgaben — ein Klick.
',1),td=w('Bild'),nd=w('Code'),ad=w('Text'),id=w('∞ aktiv'),rd=w(''),sd=w('
'),Zr=w('
'),ld=w('
Noch keine Modelle
Hol dir unter „Cookbook" ein Modell, das auf deine Hardware passt.
'),od=w('
'),dd=w('
News gerade nicht ladbar.
'),cd=w('

LLM-Engine
Aktives Modell

System-Gesundheit

Auslastung in Echtzeit.

Schnellstart

Dein Stack

Top-News

Alle →
',1);function ud(e,n){aa(n,!0);const a=I(()=>_i.value),i=I(()=>Dr.value),r=I(()=>{var M;return((M=t(a))==null?void 0:M.models)||[]}),o=I(()=>{var M;return((M=t(a))==null?void 0:M.swap_ok)??!1}),d=["running","ready","loading","starting"],c=I(()=>t(r).find(M=>d.includes(M.state))),u=I(()=>t(r).filter(M=>!M.incomplete)),v=I(()=>t(a)?t(o)?t(i)&&t(i).ram.percent>=90?"Achtung: Speicher wird knapp.":"Alles läuft rund.":"LLM-Engine offline":"Verbinde…"),g=I(()=>t(a)?t(o)?t(i)&&t(i).ram.percent>=90?`Arbeitsspeicher bei ${Math.round(t(i).ram.percent)} % — eventuell Speicher freigeben.`:`${t(u).length} ${t(u).length===1?"Modell":"Modelle"} konfiguriert · ${t(c)?`„${t(c).name}" geladen`:"keines geladen"} · keine Warnungen.`:"Der llama-swap-Dienst antwortet gerade nicht.":""),E=I(()=>()=>{var H;const M=(H=t(i))==null?void 0:H.gpu;return M&&M.vram.total+M.gtt.total>0?(M.vram.used+M.gtt.used)/(M.vram.total+M.gtt.total)*100:0});let f=O(Ht([])),y=O(null);bi(async()=>{try{h(f,((await we("/api/news")).items||[]).slice(0,4),!0)}catch{}});async function T(){await yn({title:"Speicher freigeben?",body:"Alle aktuell geladenen Modelle werden aus dem Grafikspeicher geworfen. Sie laden beim nächsten Aufruf automatisch neu.",confirmLabel:"Speicher freigeben"})&&(await we("/api/unload",{method:"POST"}),S())}async function D(M){h(y,M,!0);try{await we("/api/preload?model="+encodeURIComponent(M),{method:"POST"})}catch(H){se("Laden fehlgeschlagen: "+(H.message||"Engine nicht erreichbar?"),!0)}h(y,null),S()}function S(){document.dispatchEvent(new Event("mc:refresh"))}function $(M){var H;(H=document.querySelector(`.nav-item[data-view="${M}"]`))==null||H.dispatchEvent(new MouseEvent("click"))}function Ce(M){return M>=90?"red":M>=75?"":"green"}function oe(M){return M==null?"":M>=75?"red":M>=55?"":"green"}function ae(M){return M>=90?"red":M>=70?"":"green"}var xe=cd(),V=We(xe),Q=l(V),fe=l(Q),be=l(fe),Se=s(be);{var Ne=M=>{var H=Ho();m(M,H)};K(Se,M=>{t(o)&&!t(c)&&M(Ne)})}var bt=s(fe,2),C=l(bt),Y=s(V,2),ue=l(Y),Ue=l(ue),te=s(l(Ue),2);Ae(te,()=>Bt("server"),!0);var Te=s(Ue,2),ie=l(Te),lt=s(Te,2),je=l(lt),B=s(ue,2),U=l(B),ce=s(l(U),2);Ae(ce,()=>Bt("cpu"),!0);var Oe=s(U,2),he=l(Oe),St=s(Oe,2),ht=l(St);{var Mt=M=>{var H=ii();P(De=>b(H,`${De??""} · ${t(c).state??""}`),[()=>{var De;return(De=t(c).meta)!=null&&De.ctx?Math.round(t(c).meta.ctx/1024)+"k ctx":""}]),m(M,H)},Et=M=>{var H=ii("lädt bei erster Anfrage");m(M,H)};K(ht,M=>{t(c)?M(Mt):M(Et,-1)})}var At=s(B,2);{var It=M=>{const H=I(()=>{var Vn;return t(i).gpu_temp??((Vn=t(i).cpu)==null?void 0:Vn.temp)??null}),De=I(()=>oe(t(H))),le=I(()=>t(i).ram.total-t(i).ram.used),Le=I(()=>100-t(i).ram.percent);var Ze=Jo(),tt=We(Ze),ke=l(tt),Ee=s(l(ke));Ae(Ee,()=>Bt("thermo"),!0);var Pe=s(ke,2),Ft=l(Pe),Nt=s(Pe,2),Jt=l(Nt),an=s(tt,2),bn=l(an),Fe=s(l(bn));Ae(Fe,()=>Bt("database"),!0);var gt=s(bn,2),Bn=l(gt),Wn=s(gt,2),ra=l(Wn);P((Vn,ja,k,_)=>{kt(tt,1,`kpi ${t(De)??""}`),b(Ft,Vn),b(Jt,t(H)==null?"messe…":t(H)<55?"kühl":t(H)<75?"normal":"⚠ heiß"),kt(an,1,`kpi ${t(Le)<15?"red":t(Le)<30?"":"green"}`),b(Bn,ja),b(ra,`von ${k??""} GB · ${_??""} % frei`)},[()=>t(H)!=null?`${Math.round(t(H))}°C`:"–",()=>Math.round(t(le)/1073741824),()=>Math.round(t(i).ram.total/1073741824),()=>Math.round(t(Le))]),m(M,Ze)},qt=M=>{var H=Qo();m(M,H)};K(At,M=>{t(i)?M(It):M(qt,-1)})}var z=s(Y,2),N=l(z),Me=s(l(N),4);{var ut=M=>{const H=I(()=>t(E)());var De=di(),le=We(De);st(le,17,()=>{var Le;return[["Prozessor (CPU)",((Le=t(i).cpu)==null?void 0:Le.percent)??0,""],["Arbeitsspeicher (RAM)",t(i).ram.percent,Ce(t(i).ram.percent)],["Grafikspeicher (VRAM)",t(H),ae(t(H))]]},rt,(Le,Ze)=>{var tt=I(()=>Ca(t(Ze),3));let ke=()=>t(tt)[0],Ee=()=>t(tt)[1];const Pe=I(()=>Math.max(0,Math.min(100,Ee()||0)));var Ft=Zo(),Nt=l(Ft),Jt=l(Nt),an=l(Jt),bn=s(Jt),Fe=l(bn),gt=s(Nt,2),Bn=l(gt);P((Wn,ra)=>{b(an,ke()),b(Fe,`${Wn??""} %`),kt(gt,1,`bar ${t(Pe)>=90?"bad":t(Pe)>=75?"warn":""}`),fn(Bn,`width:${ra??""}%`)},[()=>Math.round(t(Pe)),()=>Math.max(2,t(Pe))]),m(Le,Ft)}),m(M,De)},G=M=>{var H=Yo();m(M,H)};K(Me,M=>{t(i)?M(ut):M(G,-1)})}var ze=s(N,2),He=s(l(ze),2);{var Pt=M=>{var H=Xo(),De=s(We(H),2),le=l(De);Ae(le,()=>Bt("search"),!0);var Le=s(le,4);Ae(Le,()=>Bt("chevron"),!0);var Ze=s(De,2),tt=l(Ze);Ae(tt,()=>Bt("swap"),!0);var ke=s(tt,4);Ae(ke,()=>Bt("chevron"),!0);var Ee=s(Ze,2),Pe=l(Ee);Ae(Pe,()=>Bt("file"),!0);var Ft=s(Pe,4);Ae(Ft,()=>Bt("chevron"),!0),A("click",De,()=>$("cookbook")),A("click",Ze,()=>$("connect")),A("click",Ee,()=>$("guides")),m(M,H)},$t=M=>{var H=ed(),De=s(We(H),2),le=l(De);Ae(le,()=>Bt("search"),!0);var Le=s(le,4);Ae(Le,()=>Bt("chevron"),!0);var Ze=s(De,2),tt=l(Ze);Ae(tt,()=>Bt("refresh"),!0);var ke=s(tt,4);Ae(ke,()=>Bt("chevron"),!0);var Ee=s(Ze,2),Pe=l(Ee);Ae(Pe,()=>Bt("file"),!0);var Ft=s(Pe,4);Ae(Ft,()=>Bt("chevron"),!0);var Nt=s(Ee,2),Jt=l(Nt);Ae(Jt,()=>Bt("swap"),!0);var an=s(Jt,4);Ae(an,()=>Bt("chevron"),!0),A("click",De,()=>$("cookbook")),A("click",Ze,T),A("click",Ee,()=>$("server")),A("click",Nt,()=>$("connect")),m(M,H)};K(He,M=>{t(u).length?M($t,-1):M(Pt)})}var vt=s(z,2),_t=l(vt),j=l(_t),ee=s(l(j),2),W=l(ee),J=s(j,2);{var x=M=>{var H=Zr();st(H,21,()=>t(u),rt,(De,le)=>{const Le=I(()=>d.includes(t(le).state)),Ze=I(()=>t(le).state==="downloading"),tt=I(()=>t(le).state==="loading"||t(le).state==="starting"||t(Ze)?"load":t(Le)?"on":""),ke=I(()=>t(Ze)?`↓ ${t(le).download_progress!=null?Math.round(t(le).download_progress)+"%":"..."}`:t(le).state==="loading"||t(le).state==="starting"?"lädt…":t(Le)?"geladen ✓":"bereit");var Ee=sd(),Pe=l(Ee),Ft=s(Pe,2),Nt=l(Ft),Jt=l(Nt),an=l(Jt),bn=s(Jt,2);{var Fe=re=>{var me=td();m(re,me)},gt=I(()=>{var re,me;return(me=(re=t(le).meta)==null?void 0:re.caps)==null?void 0:me.includes("Bild")}),Bn=re=>{var me=nd();m(re,me)},Wn=I(()=>{var re,me;return(me=(re=t(le).meta)==null?void 0:re.caps)==null?void 0:me.includes("Code")}),ra=re=>{var me=ad();m(re,me)};K(bn,re=>{t(gt)?re(Fe):t(Wn)?re(Bn,1):re(ra,-1)})}var Vn=s(bn,2);{var ja=re=>{var me=id();m(re,me)};K(Vn,re=>{t(le).ttl>=99999&&re(ja)})}var k=s(Nt,2),_=l(k),q=s(Ft,2),F=l(q),de=l(F),nt=s(F,2);{var ot=re=>{var me=rd(),$e=l(me);P(()=>{fn(me,`padding:3px 9px;font-size:12px;opacity:${t(y)===t(le).name?".5":"1"}`),me.disabled=t(y)===t(le).name,b($e,t(y)===t(le).name?"…":"Laden")}),A("click",me,()=>D(t(le).name)),m(re,me)};K(nt,re=>{!t(Le)&&!t(Ze)&&t(o)&&re(ot)})}P((re,me)=>{var $e;kt(Pe,1,`li-dot ${t(tt)??""}`),fn(Jt,t(Le)?"color:var(--accent)":""),b(an,t(le).name),b(_,`${re??""} - ${($e=t(le).meta)!=null&&$e.quant?" · "+t(le).meta.quant:""} - ${me??""}`),fn(F,`white-space:nowrap;color:${t(Le)?"var(--on)":"var(--mut)"}`),b(de,t(ke))},[()=>{var re;return(re=t(le).meta)!=null&&re.ctx?Math.round(t(le).meta.ctx/1024)+"k ctx":""},()=>{var re;return(re=t(le).meta)!=null&&re.size_bytes?" · "+(t(le).meta.size_bytes/1073741824).toFixed(1)+" GB":""}]),m(De,Ee)}),m(M,H)},L=M=>{var H=ld(),De=s(l(H),4);A("click",De,()=>$("cookbook")),m(M,H)};K(J,M=>{t(u).length?M(x):M(L,-1)})}var R=s(_t,2),ne=l(R),Z=s(l(ne),2),Je=s(ne,2);{var Qe=M=>{var H=Zr();st(H,21,()=>t(f),rt,(De,le)=>{var Le=od(),Ze=l(Le),tt=l(Ze),ke=l(tt),Ee=s(tt,2),Pe=l(Ee);P(()=>{Ni(Le,"href",t(le).link),b(ke,t(le).title),b(Pe,`${t(le).source??""}${t(le).relevant?" · für dich":""}`)}),m(De,Le)}),m(M,H)},et=M=>{var H=dd();m(M,H)};K(Je,M=>{t(f).length?M(Qe):M(et,-1)})}P(M=>{b(be,`${t(v)??""} `),b(C,t(g)),kt(ue,1,`kpi ${t(o)?"green":"red"}`),b(ie,t(o)?"Online":"Offline"),b(je,M),kt(B,1,`kpi ${t(c)?"blue":"muted"}`),b(he,t(c)?t(c).name:"Keins"),b(W,t(u).length?t(u).length+" konfiguriert":"")},[()=>{var M,H;return((H=(M=t(a))==null?void 0:M.swap_url)==null?void 0:H.replace(/^https?:\/\//,""))??"—"}]),A("click",Z,()=>$("news")),A("keydown",Z,M=>M.key==="Enter"&&$("news")),m(e,xe),ia()}xa(["click","keydown"]);var vd=w(""),pd=w('
'),fd=w('
Noch keine Modelle konfiguriert
Hol dir unter „Cookbook" ein passendes Modell.
'),hd=w('
kein Modell hinterlegt
leere Rolleleer '),gd=w(' '),md=w('
'),bd=w(' '),_d=w('
API-Name:
'),kd=w('
ModellKannDetailsStatusPortAktionen
'),wd=w('
Empfohlen für deine Hardware

'),yd=w(''),xd=w(''),Sd=w(''),Md=w('

Modelle

Deine konfigurierten Modelle — testen, Kontext anpassen oder aus dem Speicher werfen.

Schnelltest

Schreib eine Nachricht — das gewählte Modell wird automatisch geweckt.

Modelle & Ports

Modelle laden automatisch, sobald eine Anfrage kommt — du musst nichts manuell starten.
',1);function Ed(e,n){aa(n,!0);const a="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr (längere Dateien/Chats), braucht aber mehr Speicher und wird etwas langsamer.",i="Die Rolle ist ein zusätzlicher, sprechender Name (z.B. coder). Du kannst in deinen Tools entweder den echten Modellnamen ODER die Rolle angeben — beides führt zum selben Modell.",r=[{id:"coder",label:"Coder",desc:"Programmieren & Code"},{id:"vision",label:"Vision",desc:"Bilder verstehen"},{id:"scout",label:"Scout",desc:"Schneller Allrounder"},{id:"reviewer",label:"Reviewer",desc:"Code/Texte prüfen"},{id:"manager",label:"Manager",desc:"Planen & koordinieren"}],o=I(()=>{var z;return((z=_i.value)==null?void 0:z.models)||[]});function d(){document.dispatchEvent(new Event("mc:refresh"))}let c=O(""),u=O(""),v=O(""),g=O(!1);const E=I(()=>t(o).filter(z=>!z.incomplete));async function f(){var N;const z=t(c)||((N=t(E)[0])==null?void 0:N.name);if(!(!z||!t(u).trim())){h(g,!0),h(v,"(wecke Modell, kann beim Laden kurz dauern…)");try{const Me=await we("/api/chat",{method:"POST",body:JSON.stringify({model:z,message:t(u)})});h(v,Me.reply,!0)}catch(Me){h(v,"Fehler: "+Me.message)}h(g,!1),d()}}const y=300;let T=O(!1),D=O(null),S=O(8192),$=O(!1);function Ce(z){var N;h(D,t(o).find(Me=>Me.name===z),!0),t(D)&&(h(S,((N=t(D).meta)==null?void 0:N.ctx)||8192,!0),h($,(t(D).ttl??y)>=99999),h(T,!0))}async function oe(){const z=t($)?99999:y;try{await we("/api/update_model",{method:"POST",body:JSON.stringify({alias:t(D).name,ctx:t(S),ttl:z})}),se("Gespeichert — aktiv beim nächsten Modell-Start."),h(T,!1),d()}catch(N){se(N.message,!0)}}let ae=O(!1),xe=O(""),V=O(""),Q=O("");function fe(z){const N=t(o).find(Me=>Me.name===z);h(xe,z,!0),h(Q,(N==null?void 0:N.role)||"",!0),h(V,""),h(ae,!0)}async function be(z){try{await we("/api/set_role",{method:"POST",body:JSON.stringify({alias:t(xe),role:z})}),se(z?`Rolle gesetzt: ${z}`:"Rolle entfernt."),h(ae,!1),d()}catch(N){se(N.message,!0)}}async function Se(z){if(await yn({title:`„${z}" entladen?`,body:"Das Modell wird aus dem Grafikspeicher geworfen und lädt beim nächsten Aufruf automatisch neu.",confirmLabel:"Entladen"}))try{await we("/api/unload?model="+encodeURIComponent(z),{method:"POST"}),se("Entladen: "+z),setTimeout(d,600)}catch(N){se(N.message,!0)}}async function Ne(z){if(await yn({title:`„${z}" wirklich löschen?`,body:"Das Modell wird aus der Konfiguration ausgetragen und seine Dateien werden von der Festplatte gelöscht, um Speicher freizugeben. Das lässt sich nicht rückgängig machen — später brauchst du dafür einen neuen Download.",confirmLabel:"Endgültig löschen",danger:!0}))try{const N=await we("/api/delete_model",{method:"POST",body:JSON.stringify({alias:z})});se(N.note||"Gelöscht: "+z),setTimeout(d,600)}catch(N){se(N.message,!0)}}function bt(z){return z!=null&&z.length?z.map(N=>N==="Code"?'Code':N==="Bild"?'Bild':'Text').join(" "):"–"}function C(z){if(!z)return"–";const N=z.quant||"?",Me=z.ctx?Math.round(z.ctx/1024)+"K":"?",ut=z.size_bytes?(z.size_bytes/1024**3).toFixed(1)+" GB":"?";return`${N} · ${Me} · ${ut}`}function Y(z){var N;(N=navigator.clipboard)==null||N.writeText(z),se("Kopiert: "+z)}var ue=Md(),Ue=s(We(ue),2),te=s(l(Ue),6);st(te,21,()=>t(E),rt,(z,N)=>{var Me=vd(),ut=l(Me),G={};P(()=>{b(ut,t(N).name),G!==(G=t(N).name)&&(Me.value=(Me.__value=t(N).name)??"")}),m(z,Me)});var Te=s(te,4),ie=s(Te,2),lt=l(ie),je=s(ie,2);{var B=z=>{var N=pd(),Me=l(N);P(()=>b(Me,t(v))),m(z,N)};K(je,z=>{t(v)&&z(B)})}var U=s(Ue,2),ce=l(U),Oe=s(l(ce)),he=l(Oe),St=s(ce,4);{var ht=z=>{var N=fd();m(z,N)},Mt=z=>{var N=kd(),Me=s(l(N));st(Me,21,()=>t(o),rt,(ut,G)=>{var ze=di(),He=We(ze);{var Pt=vt=>{var _t=hd(),j=l(_t),ee=l(j),W=s(j,5),J=l(W),x=s(J,2);P(()=>b(ee,t(G).name)),A("click",J,()=>{var L;se("Lade im Cookbook ein Modell und setze den Alias auf: "+t(G).name),(L=document.querySelector(".nav-item[data-view='cookbook']"))==null||L.dispatchEvent(new MouseEvent("click"))}),A("click",x,()=>Ne(t(G).name)),m(vt,_t)},$t=vt=>{var _t=_d(),j=l(_t),ee=l(j),W=l(ee),J=s(W);{var x=ke=>{var Ee=gd(),Pe=l(Ee);P(()=>b(Pe,t(G).role)),m(ke,Ee)};K(J,ke=>{t(G).role&&ke(x)})}var L=s(ee,2);{var R=ke=>{var Ee=md(),Pe=l(Ee);P(()=>b(Pe,t(G).meta.filename)),m(ke,Ee)};K(L,ke=>{var Ee;(Ee=t(G).meta)!=null&&Ee.filename&&ke(R)})}var ne=s(L,2),Z=s(l(ne),2);st(Z,17,()=>{var ke;return(ke=t(G).api_ids)!=null&&ke.length?t(G).api_ids:[t(G).name]},rt,(ke,Ee)=>{var Pe=bd(),Ft=l(Pe);P(()=>b(Ft,t(Ee))),A("click",Pe,()=>Y(t(Ee))),m(ke,Pe)});var Je=s(j);Ae(Je,()=>{var ke;return bt((ke=t(G).meta)==null?void 0:ke.caps)},!0);var Qe=s(Je);Ae(Qe,()=>C(t(G).meta),!0);var et=s(Qe);Ae(et,()=>Vo(t(G).state,t(G).download_progress),!0);var M=s(et),H=l(M),De=s(M),le=l(De),Le=s(le,2),Ze=s(Le,2),tt=s(Ze,2);P(()=>{b(W,`${t(G).name??""} `),b(H,t(G).port??"auto")}),A("click",le,()=>fe(t(G).name)),A("click",Le,()=>Ce(t(G).name)),A("click",Ze,()=>Se(t(G).name)),A("click",tt,()=>Ne(t(G).name)),m(vt,_t)};K(He,vt=>{t(G).incomplete?vt(Pt):vt($t,-1)})}m(ut,ze)}),m(z,N)};K(St,z=>{t(o).length?z(Mt,-1):z(ht)})}var Et=s(U,2);{var At=z=>{var N=yd(),Me=l(N),ut=l(Me),G=s(ut,4),ze=l(G),He=s(G,2),Pt=s(l(He));Ae(Pt,()=>gr(a));var $t=s(He,2),vt=s($t,2);{var _t=R=>{var ne=wd(),Z=l(ne),Je=s(l(Z),2),Qe=l(Je),et=s(Qe,2),M=s(Z,2);P((H,De)=>{b(Qe,`Optimal ~${H??""}k → ~${t(D).meta.peak_ram_optimal_gb??""} GB Spitzenbedarf.`),b(et,` Aktuell ~${De??""}k → ~${t(D).meta.peak_ram_gb??""} GB.`)},[()=>Math.round(t(D).meta.optimal_ctx/1024),()=>Math.round((t(D).meta.ctx||0)/1024)]),A("click",M,()=>h(S,t(D).meta.optimal_ctx,!0)),m(R,ne)};K(vt,R=>{var ne;(ne=t(D).meta)!=null&&ne.optimal_ctx&&R(_t)})}var j=s(vt,4),ee=s(l(j),2),W=l(ee),J=s(W,2),x=l(J),L=s(j,2);P(()=>{b(ze,t(D).name),fn(J,`color:${t($)?"var(--accent)":"var(--mut)"}`),b(x,t($)?"An (TTL = ∞)":"Aus (TTL = 5 min)")}),A("click",N,R=>{R.target.classList.contains("modal-overlay")&&h(T,!1)}),A("click",ut,()=>h(T,!1)),Cn($t,()=>t(S),R=>h(S,R)),Oo(W,()=>t($),R=>h($,R)),A("click",L,oe),m(z,N)};K(Et,z=>{t(T)&&t(D)&&z(At)})}var It=s(Et,2);{var qt=z=>{var N=Sd(),Me=l(N),ut=l(Me),G=s(ut,2),ze=s(l(G));Ae(ze,()=>gr(i));var He=s(G,2),Pt=l(He),$t=s(He,4);st($t,21,()=>r,rt,(W,J)=>{var x=xd(),L=l(x);P(()=>{kt(x,1,t(Q)===t(J).id?"primary":"ghost"),Ni(x,"title",t(J).desc),b(L,t(J).label)}),A("click",x,()=>be(t(J).id)),m(W,x)});var vt=s($t,4),_t=s(vt,2),j=l(_t),ee=s(j,2);P(()=>b(Pt,t(xe))),A("click",N,W=>{W.target.classList.contains("modal-overlay")&&h(ae,!1)}),A("click",ut,()=>h(ae,!1)),Cn(vt,()=>t(V),W=>h(V,W)),A("click",j,()=>be("")),A("click",ee,()=>be(t(V).trim().toLowerCase())),m(z,N)};K(It,z=>{t(ae)&&z(qt)})}P(()=>{ie.disabled=t(g),b(lt,t(g)?"…":"Senden"),b(he,t(o).length?t(o).length+" konfiguriert":"")}),ri(te,()=>t(c),z=>h(c,z)),Cn(Te,()=>t(u),z=>h(u,z)),A("click",ie,f),m(e,ue),ia()}xa(["click"]);var Ad=w('
Prozessor (CPU)
%
Arbeitsspeicher
%
Grafikspeicher
%

System-Metriken (Bosgame)

Live-Auslastung deines Mini-PCs, alle 0,5 Sekunden.
Arbeitsspeicher (RAM)
Grafikspeicher (VRAM + GTT)
Speicherplatz (Disk)
Temperatur (GPU / CPU)
CPU-Verlauf
RAM-Verlauf
VRAM-Verlauf
',1),Cd=w(''),Td=w('
Gerade nichts los.
Alles ruhig — keine laufenden Aufgaben.
'),zd=w(' '),Dd=w(''),Pd=w(''),$d=w('
'),Ld=w('
'),Id=w('
'),Bd=w('

Aktivität

Live-Auslastung und laufende Aufgaben (Downloads, Updates) mit Protokoll.

Hintergrund-Aufgaben

Downloads & Updates erscheinen hier mit Live-Protokoll — zum Aufklappen klicken.
',1);function Rd(e,n){aa(n,!0);const a=I(()=>ca.value),i=I(()=>ca.tracked),r=I(()=>Dr.value);let o=Ht({cpu:[],ram:[],gpu:[]});Ar(()=>{var ue;if(!t(r))return;const C=t(r).gpu,Y=C&&C.vram.total+C.gtt.total>0?(C.vram.used+C.gtt.used)/(C.vram.total+C.gtt.total)*100:0;o.cpu=[...o.cpu,((ue=t(r).cpu)==null?void 0:ue.percent)??0].slice(-60),o.ram=[...o.ram,t(r).ram.percent].slice(-60),o.gpu=[...o.gpu,Y].slice(-60)});const d=I(()=>()=>{var Y;const C=(Y=t(r))==null?void 0:Y.gpu;return C&&C.vram.total+C.gtt.total>0?(C.vram.used+C.gtt.used)/(C.vram.total+C.gtt.total)*100:0}),c=I(()=>t(a).filter(C=>C.state!=="running"&&C.state!=="queued").length),u=I(()=>t(a).filter(C=>C.state==="failed").length);function v(C){if(C.state!=="running")return null;if(typeof C.progress=="number")return Math.min(100,C.progress);const ue=((C.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return ue?Math.min(100,parseFloat(ue[1])):null}function g(C){return C==null||C<0?"":C>=90?`noch ~${Math.round(C/60)} min`:`noch ~${Math.max(1,Math.round(C))} s`}function E(C){return C==="done"?'fertig':C==="failed"?'fehler':C==="canceled"?'abgebrochen':'läuft…'}function f(C){return C==="done"?"on":C==="failed"||C==="canceled"?"":"load"}async function y(C){try{await we(`/api/jobs/${C}/cancel`,{method:"POST"}),se("Abbruch angefordert…")}catch(Y){se(Y.message,!0)}}async function T(C){try{await we(`/api/jobs/${C}`,{method:"DELETE"})}catch(Y){se(Y.message,!0)}}async function D(){try{const C=await we("/api/jobs/clear",{method:"POST"});se(`${C.removed} Einträge entfernt.`)}catch(C){se(C.message,!0)}}function S(C,Y){return C.map(ue=>`
`).join("")}var $=Bd(),Ce=s(We($),2);{var oe=C=>{const Y=I(()=>t(d)());var ue=Ad(),Ue=We(ue),te=l(Ue),Te=s(l(te),2),ie=l(Te),lt=s(Te,2),je=l(lt),B=s(te,2),U=s(l(B),2),ce=l(U),Oe=s(U,2),he=l(Oe),St=s(B,2),ht=s(l(St),2),Mt=l(ht),Et=s(ht,2),At=l(Et),It=s(Ue,2),qt=s(l(It),4),z=l(qt),N=s(l(z)),Me=l(N),ut=s(z,2),G=s(l(ut),2),ze=l(G),He=s(ut,2),Pt=s(l(He)),$t=l(Pt),vt=s(He,2),_t=s(l(vt),2),j=l(_t),ee=s(qt,2),W=l(ee),J=s(l(W));Ae(J,()=>S(o.cpu,"--accent"),!0);var x=s(W,2),L=s(l(x));Ae(L,()=>S(o.ram,"--purple"),!0);var R=s(x,2),ne=s(l(R));Ae(ne,()=>S(o.gpu,"--on"),!0),P((Z,Je,Qe,et,M,H,De,le,Le,Ze,tt,ke,Ee)=>{b(ie,Z),b(je,Je),b(ce,Qe),b(he,`${et??""} / ${M??""}`),b(Mt,H),b(At,De),b(Me,`${le??""} / ${Le??""}`),b(ze,Ze),b($t,`${tt??""} % belegt`),b(j,`${ke??""} / ${Ee??""}`)},[()=>{var Z;return Math.round(((Z=t(r).cpu)==null?void 0:Z.percent)??0)},()=>{var Z;return((Z=t(r).cpu)==null?void 0:Z.temp)!=null?`${Math.round(t(r).cpu.temp)}° CPU-Temp`:"Auslastung"},()=>Math.round(t(r).ram.percent),()=>sa(t(r).ram.used),()=>sa(t(r).ram.total),()=>Math.round(t(Y)),()=>t(r).gpu_temp!=null?`${Math.round(t(r).gpu_temp)}° GPU-Temp`:"VRAM + GTT",()=>sa(t(r).ram.used),()=>sa(t(r).ram.total),()=>t(r).gpu?`${sa(t(r).gpu.vram.used+t(r).gpu.gtt.used)} / ${sa(t(r).gpu.vram.total+t(r).gpu.gtt.total)}`:"–",()=>{var Z;return Math.round(((Z=t(r).disk)==null?void 0:Z.percent)??0)},()=>t(r).gpu_temp!=null?Math.round(t(r).gpu_temp)+"°":"–",()=>{var Z;return((Z=t(r).cpu)==null?void 0:Z.temp)!=null?Math.round(t(r).cpu.temp)+"°":"–"}]),m(C,ue)};K(Ce,C=>{t(r)&&C(oe)})}var ae=s(Ce,2),xe=l(ae),V=s(l(xe),2),Q=l(V),fe=s(V,2);{var be=C=>{var Y=Cd();A("click",Y,D),m(C,Y)};K(fe,C=>{t(c)&&C(be)})}var Se=s(xe,4);{var Ne=C=>{var Y=Td();m(C,Y)},bt=C=>{var Y=di(),ue=We(Y);st(ue,17,()=>t(a),rt,(Ue,te)=>{const Te=I(()=>v(t(te))),ie=I(()=>t(te).state==="running"?g(t(te).eta_s):""),lt=I(()=>t(te).state==="running"&&t(te).rate_bps?sa(t(te).rate_bps)+"/s":""),je=I(()=>[t(ie),t(lt)].filter(Boolean).join(" · ")),B=I(()=>t(i).includes(t(te).id));var U=Id(),ce=l(U),Oe=l(ce),he=s(Oe,2),St=l(he),ht=s(he,2);{var Mt=G=>{var ze=zd(),He=l(ze);P(Pt=>b(He,`${Pt??""} %${t(je)?` · ${t(je)}`:""}`),[()=>Math.round(t(Te))]),m(G,ze)};K(ht,G=>{t(Te)!=null&&G(Mt)})}var Et=s(ht,2);{var At=G=>{var ze=Dd();P(()=>fn(ze,`${t(Te)==null?"margin-left:auto;":""}margin-right:2px;padding:2px 9px;font-size:12px`)),A("click",ze,He=>{He.stopPropagation(),y(t(te).id)}),m(G,ze)},It=G=>{var ze=Pd();A("click",ze,He=>{He.stopPropagation(),T(t(te).id)}),m(G,ze)};K(Et,G=>{t(te).state==="running"?G(At):G(It,-1)})}var qt=s(Et,2);Ae(qt,()=>E(t(te).state));var z=s(ce,2);{var N=G=>{var ze=$d(),He=l(ze);P(()=>fn(He,`width:${t(Te)??""}%`)),m(G,ze)};K(z,G=>{t(Te)!=null&&t(te).state==="running"&&G(N)})}var Me=s(z,2);{var ut=G=>{var ze=Ld(),He=l(ze);P(Pt=>b(He,Pt),[()=>(t(te).log||[]).join(` -`)]),m(G,ze)};K(Me,G=>{t(B)&&G(ut)})}P(G=>{kt(Oe,1,`li-dot ${G??""}`),b(St,t(te).label)},[()=>f(t(te).state)]),A("click",ce,()=>ca.toggle(t(te).id)),A("keydown",ce,G=>G.key==="Enter"&&ca.toggle(t(te).id)),m(Ue,U)}),m(C,Y)};K(Se,C=>{t(a).length?C(bt,-1):C(Ne)})}P(()=>b(Q,t(a).length?t(u)?t(u)+" Fehler":t(a).length+" gesamt":"")),m(e,$),ia()}xa(["click","keydown"]);var Od=w(' '),Fd=w(''),qd=w('✓ fertig'),Nd=w('✗ fehlgeschlagen'),Kd=w('abgebrochen'),Gd=w('läuft…'),Wd=w('
'),Vd=w('

Aktueller Vorgang

'),Ud=w('

Server & Wartung

Dienste steuern, Updates einspielen und live mitlesen — ganz ohne SSH oder Terminal.

LLM-Engine (llama-swap)

Das Herzstück: lädt bei jeder Anfrage automatisch das passende Modell.
Adresse (für deine Tools)
Aktuell geladen
Konfigurierte Modelle

Dienste & Applikation

Diese Aktionen sind harmlos und passwortlos — es geht nichts dabei verloren.

Betriebssystem (Bosgame)

Tiefe Eingriffe — das Dashboard fragt einmalig nach deinem sudo-Passwort.

Live-Konsole

Live mitlesen, was der Dienst gerade tut.
',1);function jd(e,n){aa(n,!0);const a=I(()=>_i.value),i=I(()=>ca.value);let r=null,o=O(`Verbinde… -`),d=O("llama-swap"),c,u=O(null),v=O("");const g=new Set,E=I(()=>t(u)?t(i).find(x=>x.id===t(u)):null);Ar(()=>{if(!t(E))return;const x=t(E),L=x.state==="done",R=x.state==="failed",ne=x.state==="canceled";(L||R||ne)&&!g.has(x.id)&&(g.add(x.id),se(L?`✓ ${t(v)} abgeschlossen.`:ne?`${t(v)} abgebrochen.`:`✗ ${t(v)} fehlgeschlagen.`,R),L&&setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),800))});function f(x,L){h(u,x,!0),h(v,L,!0),ca.track(x)}bi(()=>{y()}),qo(()=>{r==null||r.close()});function y(){r==null||r.close();const x=t(d);h(o,`Verbinde mit ${x}… -`);const L=location.protocol==="https:"?"wss:":"ws:";r=new WebSocket(`${L}//${location.host}/api/logs/${x}?token=${encodeURIComponent(tl())}`),r.onmessage=R=>{h(o,t(o)+R.data),c&&(c.scrollTop=c.scrollHeight)},r.onclose=()=>{h(o,t(o)+` -— Verbindung getrennt —`)},r.onerror=()=>r==null?void 0:r.close()}async function T(x,L,R){if(await yn({title:L,body:R,confirmLabel:"Neustarten"}))try{await we(`/api/service/${x}/restart`,{method:"POST"}),se("Neustart ausgelöst: "+x),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),2e3)}catch(ne){se(ne.message,!0)}}async function D(){if(await yn({title:"Mission Control aktualisieren?",body:"Holt die neueste Dashboard-Version aus Gitea und startet automatisch neu. Die Seite trennt kurz und verbindet von selbst wieder (~10 Sek)."}))try{const x=await we("/api/self-update",{method:"POST"});se("Update läuft — Dashboard startet gleich neu."),f(x.job_id,"Mission Control Update")}catch(x){se(x.message,!0)}}async function S(){if(await yn({title:"LLM-Engine aktualisieren?",body:"Lädt die neueste llama.cpp-ROCm-Version und installiert sie. Die Engine ist während des Updates kurz nicht erreichbar."}))try{const x=await we("/api/update",{method:"POST"});se("LLM-Engine-Update läuft."),f(x.job_id,"LLM-Engine-Update")}catch(x){se(x.message,!0)}}async function $(){if(await yn({title:"Grafikspeicher leeren?",body:"Alle geladenen Modelle werden entladen. Sie laden beim nächsten Aufruf automatisch neu — es geht nichts verloren.",confirmLabel:"Leeren"}))try{await we("/api/unload",{method:"POST"}),se("Grafikspeicher geleert."),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),600)}catch(x){se(x.message,!0)}}async function Ce(){if(!await yn({title:"OS-Updates installieren?",body:"Führt apt update & upgrade aus. Das kann ein paar Minuten dauern; der Fortschritt erscheint in der Aktivität."}))return;const x=await jr({title:"sudo-Passwort",body:"Für die System-Updates wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Installieren"});if(x)try{const L=await we("/api/os-update",{method:"POST",body:JSON.stringify({password:x})});se("OS-Update gestartet."),f(L.job_id,"OS-Update")}catch(L){se(L.message,!0)}}async function oe(){if(!await yn({title:"Server wirklich neu starten?",body:"Der ganze Bosgame startet physisch neu. Alles ist für ~1 Minute offline — auch dieses Dashboard.",confirmLabel:"Reboot",danger:!0}))return;const x=await jr({title:"sudo-Passwort",body:"Für den Reboot wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Jetzt neustarten",danger:!0});if(x)try{await we("/api/reboot",{method:"POST",body:JSON.stringify({password:x})}),se("Reboot ausgelöst — bis gleich.")}catch(L){se(L.message,!0)}}async function ae(){h(xe,"prüfe…");try{const x=await we("/api/integration/test");h(xe,x.ok?`✓ Engine antwortet — ${x.models.length} Modell(e): ${x.models.join(", ")}`:`✗ keine Verbindung: ${x.error}`,!0),h(V,x.ok,!0)}catch(x){h(xe,"✗ "+x.message),h(V,!1)}}let xe=O(""),V=O(!1);const Q=I(()=>{var x;return((x=t(a))==null?void 0:x.models)||[]}),fe=["running","ready","loading","starting"],be=I(()=>t(Q).find(x=>fe.includes(x.state)));function Se(x){if(!x||x.state!=="running")return null;if(typeof x.progress=="number")return Math.min(100,x.progress);const R=((x.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return R?Math.min(100,parseFloat(R[1])):null}var Ne=Ud(),bt=s(We(Ne),2),C=l(bt),Y=s(l(C),2),ue=l(Y),Ue=s(C,4),te=l(Ue),Te=s(l(te)),ie=l(Te),lt=s(te,2),je=s(l(lt),2),B=l(je),U=s(lt,2),ce=s(l(U),2),Oe=l(ce),he=s(Ue,2),St=l(he),ht=s(St,2);{var Mt=x=>{var L=Od(),R=l(L);P(()=>{fn(L,`color:${t(V)?"#7ee29a":"#ff9b95"}`),b(R,t(xe))}),m(x,L)};K(ht,x=>{t(xe)&&x(Mt)})}var Et=s(bt,2),At=s(l(Et),4),It=s(At,2),qt=s(It,2),z=s(qt,2),N=s(z,2),Me=s(Et,2),ut=s(l(Me),4),G=s(ut,2),ze=s(Me,2);{var He=x=>{const L=I(()=>t(E)),R=I(()=>t(L).state==="done"),ne=I(()=>t(L).state==="failed"),Z=I(()=>t(L).state==="canceled"),Je=I(()=>t(R)||t(ne)||t(Z)),Qe=I(()=>Se(t(L)));var et=Vd(),M=l(et),H=s(l(M),2);{var De=Fe=>{var gt=Fd();A("click",gt,async()=>{await yn({title:t(v)+" abbrechen?",body:"Der laufende Vorgang wird gestoppt.",confirmLabel:"Abbrechen",danger:!0})&&we(`/api/jobs/${t(L).id}/cancel`,{method:"POST"})}),m(Fe,gt)};K(H,Fe=>{t(Je)||Fe(De)})}var le=s(H,2),Le=l(le);{var Ze=Fe=>{var gt=qd();m(Fe,gt)},tt=Fe=>{var gt=Nd();m(Fe,gt)},ke=Fe=>{var gt=Kd();m(Fe,gt)},Ee=Fe=>{var gt=Gd();m(Fe,gt)};K(Le,Fe=>{t(R)?Fe(Ze):t(ne)?Fe(tt,1):t(Z)?Fe(ke,2):Fe(Ee,-1)})}var Pe=s(M,2),Ft=l(Pe),Nt=s(Pe,2);{var Jt=Fe=>{var gt=Wd(),Bn=l(gt);P(()=>fn(Bn,`width:${t(Qe)??""}%`)),m(Fe,gt)};K(Nt,Fe=>{t(Qe)!=null&&!t(Je)&&Fe(Jt)})}var an=s(Nt,2),bn=l(an);P(Fe=>{b(Ft,`${t(v)??""}${t(Je)?t(R)?" — erfolgreich.":t(Z)?" — abgebrochen.":" — fehlgeschlagen.":" läuft…"}`),b(bn,Fe)},[()=>(t(L).log||[]).join(` -`)]),m(x,et)};K(ze,x=>{t(E)&&x(He)})}var Pt=s(ze,2),$t=l(Pt),vt=s(l($t),2),_t=l(vt);_t.value=_t.__value="llama-swap";var j=s(_t);j.value=j.__value="mission-control";var ee=s(j);ee.value=ee.__value="system";var W=s($t,4),J=l(W);Fo(W,x=>c=x,()=>c),P(x=>{var L,R,ne;fn(Y,`margin-left:auto;${(L=t(a))!=null&&L.swap_ok?"background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a":"background:rgba(248,81,73,.12);border-color:rgba(248,81,73,.3);color:#ff9b95"}`),b(ue,(R=t(a))!=null&&R.swap_ok?"● erreichbar":"● offline"),b(ie,(((ne=t(a))==null?void 0:ne.swap_url)||"—")+"/v1"),b(B,t(be)?t(be).name+` (${t(be).state})`:"nichts geladen — lädt bei der nächsten Anfrage"),b(Oe,x),b(J,t(o))},[()=>t(Q).filter(x=>!x.incomplete).length||"keine"]),A("click",St,ae),A("click",At,()=>T("llama-swap","LLM-Engine neustarten?","Die Engine startet neu. Geladene Modelle werden kurz entladen (~5 Sekunden), laden danach automatisch wieder.")),A("click",It,()=>T("mission-control","Dashboard neustarten?","Diese Oberfläche trennt sich kurz und verbindet automatisch wieder.")),A("click",qt,D),A("click",z,S),A("click",N,$),A("click",ut,Ce),A("click",G,oe),A("change",vt,y),ri(vt,()=>t(d),x=>h(d,x)),m(e,Ne),ia()}xa(["click","change"]);var Hd=w('
Lade Setups…
'),Jd=w(' ×',1),Xi=w('
★ Beste Wahl für dein System
'),Qd=w('
Dein Setup
'),Zd=w(''),Yd=w('
'),Xd=w('· ⚠ Cache veraltet'),ec=w(" ",1),tc=w('
Frage Quellen ab…
'),nc=w('
'),ac=w('✓ installiert'),ic=w(''),rc=w('

'),sc=w('

'),lc=w(''),oc=w('

'),dc=w('
'),cc=w('
'),uc=w('
'),vc=w(" "),pc=w('
'),fc=w('
Größter Spitzenbedarf: . Es läuft immer nur ein Modell gleichzeitig — das größte bestimmt, ob das Setup passt.
'),hc=w('Alternative: — passt auf dein System.',1),gc=w('
⚠ Dieses Setup übersteigt deinen verfügbaren Speicher.
'),mc=w(''),bc=w('
Lade Dateien von HuggingFace…
'),Yr=w(""),_c=w('
Empfohlener Kontext für deine Hardware: übernehmen
'),kc=w('
Ressourcen-Check
'),wc=w('
⚠ Diese Datei ist zu groß für deinen Speicher. Kleinere Alternative: — einfach auswählen.
'),yc=w('
⚠ Alle Varianten dieses Modells sind zu groß für deinen Speicher. Ein kleineres Modell aus den Empfehlungen wäre die bessere Wahl.
'),xc=w('
',1),Sc=w('
Keine GGUF-Dateien im Repo gefunden.
'),Mc=w(''),Ec=w('
'),Ac=w(''),Cc=w('

Cookbook

Modelle finden, installieren und eigene Setups zusammenstellen.

1 · Anwendungsfall wählen & installieren

Hier starten: Fertige Modell-Bundles für deinen Anwendungsfall — ein Klick installiert alles. Die Hardware-Ampel zeigt vorab, ob das Setup auf deinen PC passt.

Aktuell die besten Modelle für dein System

Top-Modelle je Kategorie von HuggingFace — Hardware-Fit wird live für dein System berechnet.

Profi-Suche (HuggingFace)

Direkt HuggingFace durchsuchen — oder eine Modell-URL einfügen für den direkten Sprung.
',1);function Tc(e,n){aa(n,!0);const a="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr, braucht aber mehr Speicher und wird etwas langsamer.",i="MoE (Mixture of Experts): viele Parameter fürs Wissen, aber pro Wort ist nur ein kleiner Teil aktiv → fast große-Modell-Qualität bei hohem Tempo. Ideal für deine APU.",r={perfect:0,marginal:1,too_tight:2},o={vision:"Bilder",coder:"Coden",reasoning:"Logik",agent:"Agenten & Tools",scout:"Allrounder",reviewer:"Review",manager:"Manager"},d=[{label:"Bilder",kw:["-vl-","-vl","vision","llava","multimodal","-mm-","pixtral"]},{label:"Coden",kw:["coder","-code-","code-","codestral","starcoder"]},{label:"Logik",kw:["-r1","deepseek-r1","reasoning","qwq","magistral","-think","thinking","-o1"]},{label:"Agenten & Tools",kw:["hermes","-tool","command-r","watt","-fc-","function"]}];function c(k){const _=(k||"").toLowerCase();for(const q of d)if(q.kw.some(F=>_.includes(F)))return q.label;return"Allrounder"}function u(k=""){const _=k.toLowerCase();return/\d+x\d+(\.\d+)?b/.test(_)||new RegExp("(?{he(),St()});async function he(){h(D,!0);try{const k=await we("/api/cookbook/recipes");h(y,k.recipes||[],!0),h(T,k.recommended_id||null,!0)}catch(k){se(k.message,!0)}h(D,!1)}async function St(k=!1){h($,!0);try{const _=await we("/api/cookbook/discover"+(k?"?force=true":""));h(S,_,!0),h(Ce,_.stale,!0)}catch(_){se("Empfehlungen nicht ladbar: "+_.message,!0)}h($,!1)}function ht(k){k=k.trim();const _=k.match(/huggingface\.co\/([^\s/]+\/[^\s/?#]+)/i);return _?_[1]:/^[\w.-]+\/[\w.-]+$/.test(k)?k:null}async function Mt(){const k=t(oe).trim(),_=ht(k);let q=k;if(t(V)&&!_&&(q=q?q+" "+t(V):t(V)),!q&&!_){h(ae,[],!0);return}h(xe,!0),h(fe,[],!0),h(be,-1);try{if(_)h(ae,[{id:_,author:_.split("/")[0],downloads:0}],!0);else{const F=`https://huggingface.co/api/models?search=${encodeURIComponent(q)}&filter=gguf&sort=${encodeURIComponent(t(Q))}&direction=-1&limit=40`,de=await fetch(F);h(ae,await de.json(),!0)}t(ae).forEach((F,de)=>Et(de,F.id))}catch(F){se(F.message,!0),h(ae,[],!0)}h(xe,!1)}async function Et(k,_){var q;try{const F=await we("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:_,ctx:8192})});if(!((q=F.files)!=null&&q.length)){t(fe)[k]=null,At();return}const de=F.files.find(nt=>{var ot;return(ot=nt.quant)==null?void 0:ot.includes("Q4_K_M")})||F.files[0];t(fe)[k]=de.fit.level,At()}catch{t(fe)[k]=null,At()}}function At(){let k=-1,_=99;t(fe).forEach((q,F)=>{if(q==null)return;const de=r[q]??99;de<_&&(_=de,k=F)}),h(be,k>=0&&_<=1?k:-1,!0)}function It(k){h(Se,t(y).find(_=>_.id===k),!0)}async function qt(k){const _=document.getElementById("cb-r-install-btn");_&&(_.disabled=!0,_.textContent="Starte…");try{const q=await we("/api/cookbook/install-recipe",{method:"POST",body:JSON.stringify({recipe_id:k,hf_token:li()})});se(`${q.count} Download${q.count!==1?"s":""} läuft — Modelle erscheinen danach automatisch im Modelle-Tab.`),h(Se,null),Oe("activity")}catch(q){se(q.message,!0),_&&(_.disabled=!1,_.textContent="Installieren")}}async function z(k,_){var q,F;h(Ne,!0),h(bt,_,!0),h(C,k,!0),h(Ue,""),h(te,8192),h(Y,null),h(ie,null),h(ue,""),h(Te,!0);try{if(h(Y,await we("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:k,ctx:8192})}),!0),(F=(q=t(Y))==null?void 0:q.files)!=null&&F.length){const de=t(Y).files.find(nt=>{var ot;return(ot=nt.quant)==null?void 0:ot.includes("Q4_K_M")})||t(Y).files[0];h(ue,de.filename,!0),de.optimal_ctx&&t(te)===8192&&h(te,de.optimal_ctx,!0),N()}}catch(de){se(de.message,!0)}h(Te,!1)}function N(){var k,_,q;!((_=(k=t(Y))==null?void 0:k.files)!=null&&_.length)||!t(ue)||(h(ie,t(Y).files.find(F=>F.filename===t(ue))||null,!0),(q=t(ie))!=null&&q.optimal_ctx&&t(te)===8192&&h(te,t(ie).optimal_ctx,!0))}async function Me(){var k,_;if(!t(C)||!t(ue))return se("Bitte eine GGUF-Datei wählen.",!0);h(Te,!0);try{const q=((k=t(Y))==null?void 0:k.params_b)??7,F=((_=t(ie))==null?void 0:_.quant)??"Q4_K_M";await we("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:t(C),role:t(Ue),params_b:q,quant:F,file:t(ue),ctx:t(te),hf_token:li()})}),se("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),h(Ne,!1),Oe("activity")}catch(q){se("Fehler: "+q.message,!0)}h(Te,!1)}async function ut(k,_,q,F){F.disabled=!0,F.textContent="Starte…";try{await we("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:k,role:_,params_b:q,quant:"Q4_K_M",hf_token:li()})}),se("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),Oe("activity")}catch(de){se(de.message,!0),F.disabled=!1,F.textContent="Installieren"}}function G(){h(ce,null),h(je,""),h(B,""),h(U,[{repo:"",role:"",quant:"Q4_K_M"}],!0),h(lt,!0)}function ze(k){const _=t(y).find(q=>q.id===k);_&&(h(ce,k,!0),h(je,_.title,!0),h(B,_.desc||"",!0),h(U,_.models.map(q=>({repo:q.repo,role:q.role,quant:q.quant||"Q4_K_M"})),!0),h(lt,!0))}async function He(){if(!t(je).trim())return se("Bitte einen Titel angeben.",!0);const k=t(U).filter(_=>_.repo.trim());if(!k.length)return se("Mindestens ein Modell (Repo) angeben.",!0);try{t(ce)?(await we("/api/cookbook/user-recipe/"+encodeURIComponent(t(ce)),{method:"PUT",body:JSON.stringify({title:t(je),desc:t(B),models:k})}),se("Setup aktualisiert.")):(await we("/api/cookbook/user-recipe",{method:"POST",body:JSON.stringify({title:t(je),desc:t(B),models:k})}),se("Setup gespeichert.")),h(lt,!1),he()}catch(_){se(_.message,!0)}}async function Pt(k){const _=t(y).find(q=>q.id===k);if(await yn({title:`„${(_==null?void 0:_.title)||k}" löschen?`,body:"Dein eigenes Setup wird aus dem Cookbook entfernt. Bereits installierte Modelle bleiben unangetastet.",confirmLabel:"Löschen",danger:!0}))try{await we("/api/cookbook/user-recipe/"+encodeURIComponent(k),{method:"DELETE"}),se("Setup gelöscht."),he()}catch(q){se(q.message,!0)}}function $t(k){if(!u(k))return"";const _=v(k);return`MoE${_?` · ~${_}B aktiv`:""}`}function vt(k){return k?`${$n(k)}`:""}var _t=Cc(),j=s(We(_t),2),ee=l(j),W=s(l(ee),2),J=s(ee,4);{var x=k=>{var _=Hd();m(k,_)},L=k=>{var _=Yd();st(_,21,()=>t(y),rt,(q,F)=>{const de=I(()=>t(F).id===t(T));var nt=Zd(),ot=l(nt);{var re=ge=>{var Ye=Jd(),Gt=We(Ye),zt=s(Gt,2);A("click",Gt,wt=>{wt.stopPropagation(),ze(t(F).id)}),A("keydown",Gt,wt=>{wt.key==="Enter"&&(wt.stopPropagation(),ze(t(F).id))}),A("click",zt,wt=>{wt.stopPropagation(),Pt(t(F).id)}),A("keydown",zt,wt=>{wt.key==="Enter"&&(wt.stopPropagation(),Pt(t(F).id))}),m(ge,Ye)};K(ot,ge=>{t(F).user&&ge(re)})}var me=s(ot,2);{var $e=ge=>{var Ye=Xi();m(ge,Ye)},pt=ge=>{var Ye=Qd();m(ge,Ye)};K(me,ge=>{t(de)?ge($e):t(F).user&&ge(pt,1)})}var Ie=s(me,2),qe=l(Ie),dt=l(qe),Ct=l(dt),Yt=s(qe,2),ft=l(Yt),Be=s(Ie,2),Tt=l(Be),Kt=s(Be,2),mt=l(Kt);P((ge,Ye)=>{kt(nt,1,`card-btn${t(de)?" cb-best":""}`),b(Ct,t(F).title),kt(Yt,1,`fit-badge ${ge??""}`),b(ft,Ye),b(Tt,t(F).desc),b(mt,`${t(F).models.length??""} Modell${t(F).models.length>1?"e":""} im Setup`)},[()=>g(t(F).fit_level),()=>E(t(F).fit_level)]),A("click",nt,()=>It(t(F).id)),m(q,nt)}),m(k,_)};K(J,k=>{t(D)?k(x):k(L,-1)})}var R=s(j,2),ne=l(R),Z=s(l(ne),2),Je=l(Z);{var Qe=k=>{const _=I(()=>Math.round((Date.now()/1e3-t(S).updated)/60));var q=ec(),F=We(q);{var de=$e=>{var pt=ii();P(()=>b(pt,`Quellen befragt vor ${t(_)??""} min`)),m($e,pt)},nt=$e=>{var pt=ii();P(Ie=>b(pt,`Quellen befragt vor ${Ie??""} h`),[()=>Math.round(t(_)/60)]),m($e,pt)},ot=$e=>{var pt=ii();P(Ie=>b(pt,`Quellen befragt vor ${Ie??""} Tg.`),[()=>Math.round(t(_)/1440)]),m($e,pt)};K(F,$e=>{t(_)<60?$e(de):t(_)<1440?$e(nt,1):$e(ot,-1)})}var re=s(F,2);{var me=$e=>{var pt=Xd();m($e,pt)};K(re,$e=>{t(Ce)&&$e(me)})}m(k,q)};K(Je,k=>{var _;(_=t(S))!=null&&_.updated&&k(Qe)})}var et=s(Z,2),M=l(et),H=s(ne,4);{var De=k=>{var _=tc();m(k,_)},le=k=>{var _=di(),q=We(_);st(q,17,()=>t(S).categories,rt,(F,de)=>{var nt=sc(),ot=l(nt),re=l(ot),me=l(re),$e=s(ot,2);st($e,21,()=>t(de).models,rt,(pt,Ie)=>{const qe=I(()=>t(de).recommended&&t(Ie).repo===t(de).recommended);var dt=rc(),Ct=l(dt);{var Yt=Xe=>{var it=Xi();m(Xe,it)};K(Ct,Xe=>{t(qe)&&Xe(Yt)})}var ft=s(Ct,2),Be=l(ft),Tt=l(Be),Kt=l(Tt),mt=s(Tt,2),ge=l(mt),Ye=s(Be,2),Gt=l(Ye),zt=s(ft,2),wt=l(zt);Ae(wt,()=>vt(o[t(Ie).role]||c(t(Ie).repo)));var Rn=s(wt,2);Ae(Rn,()=>$t(t(Ie).repo));var Un=s(zt,2),En=l(Un),Sa=s(Un,2);st(Sa,17,()=>t(Ie).requirements||[],rt,(Xe,it)=>{var Lt=nc(),An=l(Lt);P(()=>b(An,`⚠ ${t(it)??""}`)),m(Xe,Lt)});var ct=s(Sa,4),Ke=l(ct);{var at=Xe=>{var it=ac();P(()=>Ni(it,"title",`bereits eingerichtet als ${t(Ie).installed??""}`)),m(Xe,it)},yt=Xe=>{var it=ic();A("click",it,Lt=>ut(t(Ie).repo,t(Ie).role,t(Ie).params_b,Lt.currentTarget)),m(Xe,it)};K(Ke,Xe=>{t(Ie).installed?Xe(at):Xe(yt,-1)})}P((Xe,it,Lt)=>{kt(dt,1,`card${t(qe)?" res-best":""}`),b(Kt,t(Ie).name),b(ge,`${t(Ie).author??""} · ${t(Ie).params_b??""}B`),kt(Ye,1,`fit-badge ${Xe??""}`),b(Gt,t(Ie).fit.text),b(En,`${it??""} · ⬇ ${Lt??""}`)},[()=>g(t(Ie).fit.level),()=>f(t(Ie).fit),()=>(t(Ie).downloads||0).toLocaleString()]),m(pt,dt)}),P(()=>b(me,t(de).title)),m(F,nt)}),m(k,_)};K(H,k=>{var _;t($)&&!t(S)?k(De):(_=t(S))!=null&&_.categories&&k(le,1)})}var Le=s(R,2),Ze=s(l(Le),4),tt=l(Ze),ke=s(tt,2),Ee=l(ke);Ee.value=Ee.__value="downloads";var Pe=s(Ee);Pe.value=Pe.__value="trending";var Ft=s(Pe);Ft.value=Ft.__value="created_at";var Nt=s(ke,2),Jt=l(Nt),an=s(Ze,2);st(an,20,()=>["","coder","vision","reasoning","chat","agent"],rt,(k,_)=>{var q=lc(),F=l(q);P(()=>{kt(q,1,t(V)===_?"primary":"ghost"),b(F,_||"Alle")}),A("click",q,()=>{h(V,_,!0),Mt()}),m(k,q)});var bn=s(an,2);{var Fe=k=>{var _=dc();st(_,21,()=>t(ae),rt,(q,F,de)=>{var nt=oc(),ot=l(nt);{var re=zt=>{var wt=Xi();m(zt,wt)};K(ot,zt=>{de===t(be)&&zt(re)})}var me=s(ot,2),$e=l(me),pt=l($e),Ie=l(pt),qe=s(pt,2),dt=l(qe),Ct=s($e,2),Yt=l(Ct),ft=s(me,2),Be=l(ft);Ae(Be,()=>vt(c(t(F).id)));var Tt=s(Be,2);Ae(Tt,()=>$t(t(F).id));var Kt=s(ft,4),mt=l(Kt),ge=l(mt),Ye=s(mt,2),Gt=l(Ye);P((zt,wt,Rn,Un,En)=>{kt(nt,1,`card${de===t(be)?" res-best":""}`),b(Ie,zt),b(dt,t(F).author||""),kt(Ct,1,`fit-badge ${wt??""}`),b(Yt,Rn),b(ge,Un),b(Gt,`⬇ ${En??""}`)},[()=>t(F).id.split("/").pop(),()=>t(fe)[de]?g(t(fe)[de]):"warn",()=>t(fe)[de]?E(t(fe)[de]):"prüfe…",()=>t(fe)[de]?f({req_gb:0,tps:0}):"Hardware-Fit…",()=>(t(F).downloads||0).toLocaleString()]),A("click",nt,()=>z(t(F).id,t(F).id.split("/").pop())),m(q,nt)}),m(k,_)};K(bn,k=>{t(ae).length&&k(Fe)})}var gt=s(Le,2);{var Bn=k=>{const _=I(()=>t(Se));var q=mc(),F=l(q),de=l(F),nt=s(de,2),ot=l(nt),re=s(nt,2),me=l(re),$e=s(re,2);st($e,21,()=>t(_).models,rt,(ft,Be)=>{var Tt=pc(),Kt=l(Tt),mt=l(Kt),ge=l(mt),Ye=l(ge),Gt=s(ge,2),zt=l(Gt),wt=s(Gt,2);Ae(wt,()=>$t(t(Be).repo));var Rn=s(mt,2);{var Un=at=>{var yt=cc(),Xe=l(yt);P(()=>b(Xe,t(Be).why)),m(at,yt)};K(Rn,at=>{t(Be).why&&at(Un)})}var En=s(Rn,2);{var Sa=at=>{var yt=uc(),Xe=l(yt);P((it,Lt,An)=>b(Xe,`~${it??""} GB · ~${Lt??""} Tok/s · optimal ~${An??""}k Kontext`),[()=>(t(Be).fit.req_gb??0).toFixed(1),()=>Math.round(t(Be).fit.tps??0),()=>Math.round((t(Be).optimal_ctx||8192)/1024)]),m(at,yt)};K(En,at=>{t(Be).fit&&at(Sa)})}var ct=s(Kt,2);{var Ke=at=>{var yt=vc(),Xe=l(yt);P(it=>{kt(yt,1,`fit-badge ${it??""}`),b(Xe,t(Be).fit.text)},[()=>g(t(Be).fit.level)]),m(at,yt)};K(ct,at=>{t(Be).fit&&at(Ke)})}P(()=>{b(Ye,t(Be).name),b(zt,t(Be).role)}),m(ft,Tt)});var pt=s($e,2);{var Ie=ft=>{const Be=I(()=>Math.max(...t(_).models.map(ge=>{var Ye;return((Ye=ge.fit)==null?void 0:Ye.req_gb)??0})));var Tt=fc(),Kt=s(l(Tt)),mt=l(Kt);P(ge=>b(mt,`~${ge??""} GB`),[()=>t(Be).toFixed(1)]),m(ft,Tt)};K(pt,ft=>{t(_).models.length&&t(_).models[0].fit&&ft(Ie)})}var qe=s(pt,2);{var dt=ft=>{const Be=I(()=>t(y).find(ge=>!ge.user&&ge.fit_level!=="too_tight"&&ge.id!==t(_).id));var Tt=gc(),Kt=s(l(Tt));{var mt=ge=>{var Ye=hc(),Gt=s(We(Ye)),zt=l(Gt);P(()=>b(zt,`„${t(Be).title??""}" ansehen`)),A("click",Gt,wt=>{wt.preventDefault(),h(Se,null),setTimeout(()=>It(t(Be).id),50)}),m(ge,Ye)};K(Kt,ge=>{t(Be)&&ge(mt)})}m(ft,Tt)};K(qe,ft=>{t(_).fit_level==="too_tight"&&ft(dt)})}var Ct=s(qe,2),Yt=l(Ct);P(()=>{b(ot,t(_).title),b(me,t(_).desc),kt(Ct,1,`primary${t(_).fit_level==="too_tight"?" warn":""}`),b(Yt,t(_).fit_level==="too_tight"?"Trotzdem installieren (nicht empfohlen)":"Komplettes Setup installieren")}),A("click",q,ft=>{ft.target.classList.contains("modal-overlay")&&h(Se,null)}),A("click",de,()=>h(Se,null)),A("click",Ct,()=>qt(t(_).id)),m(k,q)};K(gt,k=>{t(Se)&&k(Bn)})}var Wn=s(gt,2);{var ra=k=>{var _=Mc(),q=l(_),F=l(q),de=s(F,2),nt=l(de),ot=s(de,2),re=l(ot),me=s(ot,2);{var $e=qe=>{var dt=bc();m(qe,dt)},pt=qe=>{var dt=xc(),Ct=s(We(dt),2);st(Ct,21,()=>t(Y).files,rt,(ct,Ke)=>{const at=I(()=>t(Ke).fit.level==="perfect"?"●":t(Ke).fit.level==="marginal"?"◐":"○");var yt=Yr(),Xe=l(yt),it={};P(()=>{b(Xe,`${t(at)??""} ${t(Ke).filename??""}`),it!==(it=t(Ke).filename)&&(yt.value=(yt.__value=t(Ke).filename)??"")}),m(ct,yt)});var Yt=s(Ct,2),ft=l(Yt),Be=s(l(ft),2),Tt=s(ft,2),Kt=l(Tt),mt=s(l(Kt));Ae(mt,()=>gr(a));var ge=s(Kt,2),Ye=s(Yt,2);{var Gt=ct=>{var Ke=_c(),at=s(l(Ke)),yt=l(at),Xe=s(at,2);P(it=>b(yt,`~${it??""}k`),[()=>Math.round(t(ie).optimal_ctx/1024)]),A("click",Xe,it=>{it.preventDefault(),h(te,t(ie).optimal_ctx,!0)}),m(ct,Ke)};K(Ye,ct=>{var Ke;(Ke=t(ie))!=null&&Ke.optimal_ctx&&ct(Gt)})}var zt=s(Ye,2);{var wt=ct=>{var Ke=kc(),at=l(Ke),yt=s(l(at),2),Xe=l(yt),it=s(at,2),Lt=l(it);P((An,ki,Wi)=>{b(Xe,`~${An??""} GB · ~${ki??""} Tok/s · ${(t(ie).quant||"GGUF")??""}`),kt(it,1,`fit-badge ${Wi??""}`),b(Lt,t(ie).fit.text)},[()=>(t(ie).fit.req_gb??0).toFixed(1),()=>Math.round(t(ie).fit.tps??0),()=>g(t(ie).fit.level)]),m(ct,Ke)};K(zt,ct=>{t(ie)&&ct(wt)})}var Rn=s(zt,2);{var Un=ct=>{const Ke=I(()=>t(Y).files.find(Lt=>Lt.fit.level!=="too_tight"&&Lt.filename!==t(ue)));var at=di(),yt=We(at);{var Xe=Lt=>{var An=wc(),ki=s(l(An)),Wi=l(ki);P(Vi=>b(Wi,`${t(Ke).filename??""} (${Vi??""})`),[()=>E(t(Ke).fit.level)]),A("click",ki,Vi=>{Vi.preventDefault(),h(ue,t(Ke).filename,!0),N()}),m(Lt,An)},it=Lt=>{var An=yc();m(Lt,An)};K(yt,Lt=>{t(Ke)?Lt(Xe):Lt(it,-1)})}m(ct,at)};K(Rn,ct=>{var Ke,at;((Ke=t(ie))==null?void 0:Ke.fit.level)==="too_tight"&&((at=t(Y))!=null&&at.files)&&ct(Un)})}var En=s(Rn,2),Sa=l(En);P(()=>{var ct,Ke;kt(En,1,`primary${((ct=t(ie))==null?void 0:ct.fit.level)==="too_tight"?" warn":""}`),En.disabled=t(Te),b(Sa,t(Te)?"Starte…":((Ke=t(ie))==null?void 0:Ke.fit.level)==="too_tight"?"Trotzdem holen (zu groß — nicht empfohlen)":"Herunterladen & Einpflegen")}),A("change",Ct,N),ri(Ct,()=>t(ue),ct=>h(ue,ct)),Cn(Be,()=>t(Ue),ct=>h(Ue,ct)),Cn(ge,()=>t(te),ct=>h(te,ct)),A("click",En,Me),m(qe,dt)},Ie=qe=>{var dt=Sc();m(qe,dt)};K(me,qe=>{var dt,Ct;t(Te)&&!t(Y)?qe($e):(Ct=(dt=t(Y))==null?void 0:dt.files)!=null&&Ct.length?qe(pt,1):t(Te)||qe(Ie,2)})}P(()=>{b(nt,t(bt)),b(re,t(C))}),A("click",_,qe=>{qe.target.classList.contains("modal-overlay")&&h(Ne,!1)}),A("click",F,()=>h(Ne,!1)),m(k,_)};K(Wn,k=>{t(Ne)&&k(ra)})}var Vn=s(Wn,2);{var ja=k=>{var _=Ac(),q=l(_),F=l(q),de=s(F,2),nt=l(de),ot=s(de,6),re=s(ot,4),me=s(re,4);st(me,17,()=>t(U),rt,(qe,dt,Ct)=>{var Yt=Ec(),ft=l(Yt),Be=s(ft,2),Tt=s(Be,2);st(Tt,20,()=>["Q4_K_M","Q5_K_M","Q6_K","Q8_0","Q3_K_M"],rt,(mt,ge)=>{var Ye=Yr(),Gt=l(Ye),zt={};P(()=>{b(Gt,ge),zt!==(zt=ge)&&(Ye.__value=ge)}),m(mt,Ye)});var Kt=s(Tt,2);Cn(ft,()=>t(dt).repo,mt=>t(dt).repo=mt),Cn(Be,()=>t(dt).role,mt=>t(dt).role=mt),ri(Tt,()=>t(dt).quant,mt=>t(dt).quant=mt),A("click",Kt,()=>h(U,t(U).filter((mt,ge)=>ge!==Ct),!0)),m(qe,Yt)});var $e=s(me,2),pt=s($e,4),Ie=l(pt);P(()=>{b(nt,t(ce)?"Setup bearbeiten":"Eigenes Setup erstellen"),b(Ie,t(ce)?"Änderungen speichern":"Setup speichern")}),A("click",_,qe=>{qe.target.classList.contains("modal-overlay")&&h(lt,!1)}),A("click",F,()=>h(lt,!1)),Cn(ot,()=>t(je),qe=>h(je,qe)),Cn(re,()=>t(B),qe=>h(B,qe)),A("click",$e,()=>h(U,[...t(U),{repo:"",role:"",quant:"Q4_K_M"}],!0)),A("click",pt,He),m(k,_)};K(Vn,k=>{t(lt)&&k(ja)})}P(()=>{et.disabled=t($),b(M,t($)?"Suche…":"Aktualisieren"),Nt.disabled=t(xe),b(Jt,t(xe)?"Lade…":"Suchen")}),A("click",W,G),A("click",et,()=>St(!0)),A("keydown",tt,k=>k.key==="Enter"&&Mt()),Cn(tt,()=>t(oe),k=>h(oe,k)),ri(ke,()=>t(Q),k=>h(Q,k)),A("click",Nt,Mt),m(e,_t),ia()}xa(["click","keydown","change"]);var zc=w(`
Du öffnest Mission Control über einen Proxy/Namen. Die Engine läuft auf Port 8080 ohne HTTPS direkt am Bosgame. - Trag in deinen Tools die LAN-IP ein: http://192.168.178.151:8080/v1 — nicht den Proxy-Namen.
`),Dc=w(' '),Pc=w('
'),$c=w(' '),Lc=w(''),Xr=w(''),Ic=w('

Jan AI ist eine Desktop-App — kein Browser, kein Server, kein Admin-Panel. Einfach installieren und loslegen.

Jan AI öffnen → linke Leiste → Remote-Modelle+ Modell hinzufügen:

API-Key: ein beliebiger Wert (z.B. local). Jan AI fragt danach beim Einrichten.
Jan AI herunterladen: jan.ai — kostenlos, open source, Windows/macOS/Linux.
',1),Bc=w('

Datei anlegen oder öffnen: ~/.continue/config.json

Falls bereits eine config.json vorhanden: nur den "models"-Eintrag ergänzen, nicht die ganze Datei ersetzen.

Danach Continue in VS Code neu starten → im Chat-Panel das Modell wählen.

Continue: continue.dev — kostenlose VS Code / JetBrains Extension. Hinweis: 2026 von Cursor akquiriert — aktuell weiter aktiv und kostenlos.
',1),Rc=w('

Antigravity (Googles agentic IDE, VS Code-basiert) unterstützt OpenAI-kompatible Endpoints direkt:

Settings → Models → Custom Endpoint+ hinzufügen:

API-Key: ein beliebiger Wert (z.B. local). Danach das Modell in der Model-Liste auswählen.
Antigravity herunterladen: antigravityide.net — kostenlose Einzelperson-Tier, VS Code-basiert.
',1),Oc=w('

Öffne die Zed-Settings mit Cmd/Strg + , und füge diesen Block in deine bestehende settings.json ein. Falls bereits ein "bosgame"-Eintrag existiert: vorher löschen.

Nur diesen Block einfügen, nicht die ganze Datei ersetzen — sonst gehen andere Einstellungen verloren.

API-Key: Öffne den Agent-Panel → Anbieter bosgame → trag irgendeinen Wert ein (z.B. local).

Danach im Agent-Panel das Modell auswählen.
',1),Fc=w('

Datei anlegen oder öffnen:

Windows: %USERPROFILE%\\.config\\opencode\\opencode.json

Nur den "provider"-Block einfügen. Falls bereits ein "llama-swap"-Eintrag vorhanden: vorher löschen, sonst erscheinen Modelle doppelt.

Danach in OpenCode /models wählen.

',1),qc=w('

In Cline/Cursor den Provider „OpenAI Compatible" wählen:

API-Key: ein beliebiger Wert (z.B. local).
',1),Nc=w('

Settings → Admin Panel → Connections → neue OpenAI-Verbindung:

',1),Kc=w('

Bilder einbinden (Vision)

Mit Vision-Modellen kannst du Screenshots oder Fehlerbilder direkt mitschicken.
'),Gc=w('

2 · Modelle auswählen

Wähle, welche Modelle im Config-Snippet erscheinen sollen.

3 · Tool wählen

Für welches Werkzeug brauchst du die Konfiguration?
Chat
Coding-Assistenten

4 · Config-Snippet

',1),Wc=w('

2 · Erst ein Modell installieren

Noch kein Modell eingerichtet
Bevor du ein Tool verbinden kannst, braucht die Engine mindestens ein Modell. Das Config-Snippet wird dann automatisch mit deinen echten Modellnamen befüllt.
'),Vc=w('

Verbinden

Schritt für Schritt: KI-Modelle in deine Tools einbinden — getestet, erklärt, mit Copy-Paste-Config.

1 · Verbindung prüfen

Stelle sicher, dass die LLM-Engine erreichbar ist, bevor du Tools konfigurierst.

Wie funktioniert das Auto-Swap?

',1);function Uc(e,n){aa(n,!0);const a=I(()=>_i.value),i=I(()=>{var B;return(((B=t(a))==null?void 0:B.models)||[]).filter(U=>!U.incomplete)}),r=I(v);let o=O("zed"),d=O(Ht([])),c=O(""),u=O(!1);function v(){return`http://${location.hostname}:8080/v1`}function g(B){return/^\d{1,3}(\.\d{1,3}){3}$/.test(B)}function E(){return location.protocol==="https:"||!g(location.hostname)}const f=I(()=>t(d).length?t(d):t(i).map(B=>B.name)),y=I(()=>t(f)[0]||"coder"),T=I(()=>{var B;return(B=t(i).find(U=>{var ce,Oe;return(Oe=(ce=U.meta)==null?void 0:ce.caps)==null?void 0:Oe.includes("Bild")}))==null?void 0:B.name});function D(B,U){const Oe=(U.length?t(i).filter(he=>U.includes(he.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(he=>{var Mt,Et;const St=(((Mt=he.meta)==null?void 0:Mt.caps)||[]).some(At=>/Bild|Vision/i.test(At)),ht=((Et=he.meta)==null?void 0:Et.ctx)||131072;return` { "name": "${he.name}", "display_name": "${he.name}", "max_tokens": ${ht}${St?', "capabilities": { "tools": true, "images": true }':""} }`}).join(`, + + `;const u=c.querySelector("input"),v=b=>{c.remove(),d(b)};c.addEventListener("click",b=>{if(b.target===c)return v(null);const A=b.target.closest("[data-x]");A&&v(A.getAttribute("data-x")==="1"?u.value||"":null)}),u.addEventListener("keydown",b=>{b.key==="Enter"&&v(u.value||""),b.key==="Escape"&&v(null)}),document.body.appendChild(c),u.focus()})}function Uo(e="overview"){const n=Wr(".nav-item[data-view]:not(.disabled)"),a=Wr(".view[data-view]"),i=new Set(a.map(o=>o.dataset.view));function l(o){i.has(o)||(o=e),a.forEach(d=>d.hidden=d.dataset.view!==o),n.forEach(d=>d.classList.toggle("active",d.dataset.view===o)),location.hash!=="#/"+o&&(location.hash="#/"+o)}return n.forEach(o=>o.addEventListener("click",d=>{d.preventDefault(),l(o.dataset.view)})),window.addEventListener("hashchange",()=>l(location.hash.replace("#/",""))),l(location.hash.replace("#/","")||e),{show:l}}let Hr=B(null);const _i={get value(){return t(Hr)},set(e){f(Hr,e,!0)}};let Jr=B(jt([])),Zn=B(jt([]));const va={get value(){return t(Jr)},set(e){f(Jr,e||[],!0)},get tracked(){return t(Zn)},track(e){t(Zn).includes(e)||f(Zn,[...t(Zn),e],!0)},toggle(e){f(Zn,t(Zn).includes(e)?t(Zn).filter(n=>n!==e):[...t(Zn),e],!0)}};let Qr=B(null);const Pr={get value(){return t(Qr)},set(e){f(Qr,e,!0)}},jo="5";var ls;typeof window<"u"&&((ls=window.__svelte??(window.__svelte={})).v??(ls.v=new Set)).add(jo);var Ho=_('— bereit für Anfragen'),Jo=_('
Temperatur (GPU)
Freier Speicher
GB
',1),Qo=_('
Temperatur
messe…
Freier Speicher
messe…
',1),Zo=_('
'),Yo=_('
Warte auf Messwerte…
'),Xo=_('
Noch kein Modell eingerichtet — starte hier:
',1),ed=_('
Die häufigsten Aufgaben — ein Klick.
',1),td=_('Bild'),nd=_('Code'),ad=_('Text'),id=_('∞ aktiv'),rd=_(''),sd=_('
'),Zr=_('
'),ld=_('
Noch keine Modelle
Hol dir unter „Cookbook" ein Modell, das auf deine Hardware passt.
'),od=_('
'),dd=_('
News gerade nicht ladbar.
'),cd=_('

LLM-Engine
Aktives Modell

System-Gesundheit

Auslastung in Echtzeit.

Schnellstart

Dein Stack

Top-News

Alle →
',1);function ud(e,n){Gn(n,!0);const a=O(()=>_i.value),i=O(()=>Pr.value),l=O(()=>{var E;return((E=t(a))==null?void 0:E.models)||[]}),o=O(()=>{var E;return((E=t(a))==null?void 0:E.swap_ok)??!1}),d=["running","ready","loading","starting"],c=O(()=>t(l).find(E=>d.includes(E.state))),u=O(()=>t(l).filter(E=>!E.incomplete)),v=O(()=>t(a)?t(o)?t(i)&&t(i).ram.percent>=90?"Achtung: Speicher wird knapp.":"Alles läuft rund.":"LLM-Engine offline":"Verbinde…"),b=O(()=>t(a)?t(o)?t(i)&&t(i).ram.percent>=90?`Arbeitsspeicher bei ${Math.round(t(i).ram.percent)} % — eventuell Speicher freigeben.`:`${t(u).length} ${t(u).length===1?"Modell":"Modelle"} konfiguriert · ${t(c)?`„${t(c).name}" geladen`:"keines geladen"} · keine Warnungen.`:"Der llama-swap-Dienst antwortet gerade nicht.":""),A=O(()=>()=>{var H;const E=(H=t(i))==null?void 0:H.gpu;return E&&E.vram.total+E.gtt.total>0?(E.vram.used+E.gtt.used)/(E.vram.total+E.gtt.total)*100:0});let m=B(jt([])),x=B(null);bi(async()=>{try{f(m,((await Se("/api/news")).items||[]).slice(0,4),!0)}catch{}});async function C(){await mn({title:"Speicher freigeben?",body:"Alle aktuell geladenen Modelle werden aus dem Grafikspeicher geworfen. Sie laden beim nächsten Aufruf automatisch neu.",confirmLabel:"Speicher freigeben"})&&(await Se("/api/unload",{method:"POST"}),M())}async function z(E){f(x,E,!0);try{await Se("/api/preload?model="+encodeURIComponent(E),{method:"POST"})}catch(H){ee("Laden fehlgeschlagen: "+(H.message||"Engine nicht erreichbar?"),!0)}f(x,null),M()}function M(){document.dispatchEvent(new Event("mc:refresh"))}function I(E){var H;(H=document.querySelector(`.nav-item[data-view="${E}"]`))==null||H.dispatchEvent(new MouseEvent("click"))}function Ie(E){return E>=90?"red":E>=75?"":"green"}function fe(E){return E==null?"":E>=75?"red":E>=55?"":"green"}function me(E){return E>=90?"red":E>=70?"":"green"}var ke=cd(),K=Ze(ke),Y=s(K),he=s(Y),xe=s(he),Te=r(xe);{var Ve=E=>{var H=Ho();h(E,H)};q(Te,E=>{t(o)&&!t(c)&&E(Ve)})}var yt=r(he,2),T=s(yt),X=r(K,2),ve=s(X),Ye=s(ve),ae=r(s(Ye),2);qe(ae,()=>Ft("server"),!0);var Be=r(Ye,2),re=s(Be),F=r(Be,2),Z=s(F),oe=r(ve,2),se=s(oe),Oe=r(s(se),2);qe(Oe,()=>Ft("cpu"),!0);var He=r(se,2),mt=s(He),ut=r(He,2),vt=s(ut);{var Je=E=>{var H=ri();$(Ne=>g(H,`${Ne??""} · ${t(c).state??""}`),[()=>{var Ne;return(Ne=t(c).meta)!=null&&Ne.ctx?Math.round(t(c).meta.ctx/1024)+"k ctx":""}]),h(E,H)},ze=E=>{var H=ri("lädt bei erster Anfrage");h(E,H)};q(vt,E=>{t(c)?E(Je):E(ze,-1)})}var Et=r(oe,2);{var Tt=E=>{const H=O(()=>{var jn;return t(i).gpu_temp??((jn=t(i).cpu)==null?void 0:jn.temp)??null}),Ne=O(()=>fe(t(H))),ce=O(()=>t(i).ram.total-t(i).ram.used),G=O(()=>100-t(i).ram.percent);var j=Jo(),W=Ze(j),R=s(W),J=r(s(R));qe(J,()=>Ft("thermo"),!0);var Q=r(R,2),le=s(Q),Ae=r(Q,2),be=s(Ae),pt=r(W,2),xt=s(pt),_e=r(s(xt));qe(_e,()=>Ft("database"),!0);var bt=r(xt,2),Bn=s(bt),Un=r(bt,2),la=s(Un);$((jn,Ha,y,w)=>{Ct(W,1,`kpi ${t(Ne)??""}`),g(le,jn),g(be,t(H)==null?"messe…":t(H)<55?"kühl":t(H)<75?"normal":"⚠ heiß"),Ct(pt,1,`kpi ${t(G)<15?"red":t(G)<30?"":"green"}`),g(Bn,Ha),g(la,`von ${y??""} GB · ${w??""} % frei`)},[()=>t(H)!=null?`${Math.round(t(H))}°C`:"–",()=>Math.round(t(ce)/1073741824),()=>Math.round(t(i).ram.total/1073741824),()=>Math.round(t(G))]),h(E,j)},$t=E=>{var H=Qo();h(E,H)};q(Et,E=>{t(i)?E(Tt):E($t,-1)})}var D=r(X,2),N=s(D),Me=r(s(N),4);{var Qe=E=>{const H=O(()=>t(A)());var Ne=di(),ce=Ze(Ne);nt(ce,17,()=>{var G;return[["Prozessor (CPU)",((G=t(i).cpu)==null?void 0:G.percent)??0,""],["Arbeitsspeicher (RAM)",t(i).ram.percent,Ie(t(i).ram.percent)],["Grafikspeicher (VRAM)",t(H),me(t(H))]]},rt,(G,j)=>{var W=O(()=>ea(t(j),3));let R=()=>t(W)[0],J=()=>t(W)[1];const Q=O(()=>Math.max(0,Math.min(100,J()||0)));var le=Zo(),Ae=s(le),be=s(Ae),pt=s(be),xt=r(be),_e=s(xt),bt=r(Ae,2),Bn=s(bt);$((Un,la)=>{g(pt,R()),g(_e,`${Un??""} %`),Ct(bt,1,`bar ${t(Q)>=90?"bad":t(Q)>=75?"warn":""}`),Xt(Bn,`width:${la??""}%`)},[()=>Math.round(t(Q)),()=>Math.max(2,t(Q))]),h(G,le)}),h(E,Ne)},k=E=>{var H=Yo();h(E,H)};q(Me,E=>{t(i)?E(Qe):E(k,-1)})}var L=r(N,2),te=r(s(L),2);{var Pe=E=>{var H=Xo(),Ne=r(Ze(H),2),ce=s(Ne);qe(ce,()=>Ft("search"),!0);var G=r(ce,4);qe(G,()=>Ft("chevron"),!0);var j=r(Ne,2),W=s(j);qe(W,()=>Ft("swap"),!0);var R=r(W,4);qe(R,()=>Ft("chevron"),!0);var J=r(j,2),Q=s(J);qe(Q,()=>Ft("file"),!0);var le=r(Q,4);qe(le,()=>Ft("chevron"),!0),S("click",Ne,()=>I("cookbook")),S("click",j,()=>I("connect")),S("click",J,()=>I("guides")),h(E,H)},de=E=>{var H=ed(),Ne=r(Ze(H),2),ce=s(Ne);qe(ce,()=>Ft("search"),!0);var G=r(ce,4);qe(G,()=>Ft("chevron"),!0);var j=r(Ne,2),W=s(j);qe(W,()=>Ft("refresh"),!0);var R=r(W,4);qe(R,()=>Ft("chevron"),!0);var J=r(j,2),Q=s(J);qe(Q,()=>Ft("file"),!0);var le=r(Q,4);qe(le,()=>Ft("chevron"),!0);var Ae=r(J,2),be=s(Ae);qe(be,()=>Ft("swap"),!0);var pt=r(be,4);qe(pt,()=>Ft("chevron"),!0),S("click",Ne,()=>I("cookbook")),S("click",j,C),S("click",J,()=>I("server")),S("click",Ae,()=>I("connect")),h(E,H)};q(te,E=>{t(u).length?E(de,-1):E(Pe)})}var Fe=r(D,2),Ee=s(Fe),$e=s(Ee),Xe=r(s($e),2),Ke=s(Xe),lt=r($e,2);{var P=E=>{var H=Zr();nt(H,21,()=>t(u),rt,(Ne,ce)=>{const G=O(()=>d.includes(t(ce).state)),j=O(()=>t(ce).state==="downloading"),W=O(()=>t(ce).state==="loading"||t(ce).state==="starting"||t(j)?"load":t(G)?"on":""),R=O(()=>t(j)?`↓ ${t(ce).download_progress!=null?Math.round(t(ce).download_progress)+"%":"..."}`:t(ce).state==="loading"||t(ce).state==="starting"?"lädt…":t(G)?"geladen ✓":"bereit");var J=sd(),Q=s(J),le=r(Q,2),Ae=s(le),be=s(Ae),pt=s(be),xt=r(be,2);{var _e=ue=>{var De=td();h(ue,De)},bt=O(()=>{var ue,De;return(De=(ue=t(ce).meta)==null?void 0:ue.caps)==null?void 0:De.includes("Bild")}),Bn=ue=>{var De=nd();h(ue,De)},Un=O(()=>{var ue,De;return(De=(ue=t(ce).meta)==null?void 0:ue.caps)==null?void 0:De.includes("Code")}),la=ue=>{var De=ad();h(ue,De)};q(xt,ue=>{t(bt)?ue(_e):t(Un)?ue(Bn,1):ue(la,-1)})}var jn=r(xt,2);{var Ha=ue=>{var De=id();h(ue,De)};q(jn,ue=>{t(ce).ttl>=99999&&ue(Ha)})}var y=r(Ae,2),w=s(y),U=r(le,2),V=s(U),pe=s(V),ft=r(V,2);{var _t=ue=>{var De=rd(),Ge=s(De);$(()=>{Xt(De,`padding:3px 9px;font-size:12px;opacity:${t(x)===t(ce).name?".5":"1"}`),De.disabled=t(x)===t(ce).name,g(Ge,t(x)===t(ce).name?"…":"Laden")}),S("click",De,()=>z(t(ce).name)),h(ue,De)};q(ft,ue=>{!t(G)&&!t(j)&&t(o)&&ue(_t)})}$((ue,De)=>{var Ge;Ct(Q,1,`li-dot ${t(W)??""}`),Xt(be,t(G)?"color:var(--accent)":""),g(pt,t(ce).name),g(w,`${ue??""} + ${(Ge=t(ce).meta)!=null&&Ge.quant?" · "+t(ce).meta.quant:""} + ${De??""}`),Xt(V,`white-space:nowrap;color:${t(G)?"var(--on)":"var(--mut)"}`),g(pe,t(R))},[()=>{var ue;return(ue=t(ce).meta)!=null&&ue.ctx?Math.round(t(ce).meta.ctx/1024)+"k ctx":""},()=>{var ue;return(ue=t(ce).meta)!=null&&ue.size_bytes?" · "+(t(ce).meta.size_bytes/1073741824).toFixed(1)+" GB":""}]),h(Ne,J)}),h(E,H)},ie=E=>{var H=ld(),Ne=r(s(H),4);S("click",Ne,()=>I("cookbook")),h(E,H)};q(lt,E=>{t(u).length?E(P):E(ie,-1)})}var we=r(Ee,2),ot=s(we),et=r(s(ot),2),Qt=r(ot,2);{var Zt=E=>{var H=Zr();nt(H,21,()=>t(m),rt,(Ne,ce)=>{var G=od(),j=s(G),W=s(j),R=s(W),J=r(W,2),Q=s(J);$(()=>{qi(G,"href",t(ce).link),g(R,t(ce).title),g(Q,`${t(ce).source??""}${t(ce).relevant?" · für dich":""}`)}),h(Ne,G)}),h(E,H)},qt=E=>{var H=dd();h(E,H)};q(Qt,E=>{t(m).length?E(Zt):E(qt,-1)})}$(E=>{g(xe,`${t(v)??""} `),g(T,t(b)),Ct(ve,1,`kpi ${t(o)?"green":"red"}`),g(re,t(o)?"Online":"Offline"),g(Z,E),Ct(oe,1,`kpi ${t(c)?"blue":"muted"}`),g(mt,t(c)?t(c).name:"Keins"),g(Ke,t(u).length?t(u).length+" konfiguriert":"")},[()=>{var E,H;return((H=(E=t(a))==null?void 0:E.swap_url)==null?void 0:H.replace(/^https?:\/\//,""))??"—"}]),S("click",et,()=>I("news")),S("keydown",et,E=>E.key==="Enter"&&I("news")),h(e,ke),Vn()}sa(["click","keydown"]);var vd=_(""),pd=_('
'),fd=_('
Noch keine Modelle konfiguriert
Hol dir unter „Cookbook" ein passendes Modell.
'),hd=_('
kein Modell hinterlegt
leere Rolleleer '),gd=_(' '),md=_('
'),bd=_(' '),_d=_('
API-Name:
'),kd=_('
ModellKannDetailsStatusPortAktionen
'),wd=_('
Empfohlen für deine Hardware

'),yd=_(''),xd=_(''),Sd=_(''),Md=_('

Modelle

Deine konfigurierten Modelle — testen, Kontext anpassen oder aus dem Speicher werfen.

Schnelltest

Schreib eine Nachricht — das gewählte Modell wird automatisch geweckt.

Modelle & Ports

Modelle laden automatisch, sobald eine Anfrage kommt — du musst nichts manuell starten.
',1);function Ed(e,n){Gn(n,!0);const a="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr (längere Dateien/Chats), braucht aber mehr Speicher und wird etwas langsamer.",i="Die Rolle ist ein zusätzlicher, sprechender Name (z.B. coder). Du kannst in deinen Tools entweder den echten Modellnamen ODER die Rolle angeben — beides führt zum selben Modell.",l=[{id:"coder",label:"Coder",desc:"Programmieren & Code"},{id:"vision",label:"Vision",desc:"Bilder verstehen"},{id:"scout",label:"Scout",desc:"Schneller Allrounder"},{id:"reviewer",label:"Reviewer",desc:"Code/Texte prüfen"},{id:"manager",label:"Manager",desc:"Planen & koordinieren"}],o=O(()=>{var D;return((D=_i.value)==null?void 0:D.models)||[]});function d(){document.dispatchEvent(new Event("mc:refresh"))}let c=B(""),u=B(""),v=B(""),b=B(!1);const A=O(()=>t(o).filter(D=>!D.incomplete));async function m(){var N;const D=t(c)||((N=t(A)[0])==null?void 0:N.name);if(!(!D||!t(u).trim())){f(b,!0),f(v,"(wecke Modell, kann beim Laden kurz dauern…)");try{const Me=await Se("/api/chat",{method:"POST",body:JSON.stringify({model:D,message:t(u)})});f(v,Me.reply,!0)}catch(Me){f(v,"Fehler: "+Me.message)}f(b,!1),d()}}const x=300;let C=B(!1),z=B(null),M=B(8192),I=B(!1);function Ie(D){var N;f(z,t(o).find(Me=>Me.name===D),!0),t(z)&&(f(M,((N=t(z).meta)==null?void 0:N.ctx)||8192,!0),f(I,(t(z).ttl??x)>=99999),f(C,!0))}async function fe(){const D=t(I)?99999:x;try{await Se("/api/update_model",{method:"POST",body:JSON.stringify({alias:t(z).name,ctx:t(M),ttl:D})}),ee("Gespeichert — aktiv beim nächsten Modell-Start."),f(C,!1),d()}catch(N){ee(N.message,!0)}}let me=B(!1),ke=B(""),K=B(""),Y=B("");function he(D){const N=t(o).find(Me=>Me.name===D);f(ke,D,!0),f(Y,(N==null?void 0:N.role)||"",!0),f(K,""),f(me,!0)}async function xe(D){try{await Se("/api/set_role",{method:"POST",body:JSON.stringify({alias:t(ke),role:D})}),ee(D?`Rolle gesetzt: ${D}`:"Rolle entfernt."),f(me,!1),d()}catch(N){ee(N.message,!0)}}async function Te(D){if(await mn({title:`„${D}" entladen?`,body:"Das Modell wird aus dem Grafikspeicher geworfen und lädt beim nächsten Aufruf automatisch neu.",confirmLabel:"Entladen"}))try{await Se("/api/unload?model="+encodeURIComponent(D),{method:"POST"}),ee("Entladen: "+D),setTimeout(d,600)}catch(N){ee(N.message,!0)}}async function Ve(D){if(await mn({title:`„${D}" wirklich löschen?`,body:"Das Modell wird aus der Konfiguration ausgetragen und seine Dateien werden von der Festplatte gelöscht, um Speicher freizugeben. Das lässt sich nicht rückgängig machen — später brauchst du dafür einen neuen Download.",confirmLabel:"Endgültig löschen",danger:!0}))try{const N=await Se("/api/delete_model",{method:"POST",body:JSON.stringify({alias:D})});ee(N.note||"Gelöscht: "+D),setTimeout(d,600)}catch(N){ee(N.message,!0)}}function yt(D){return D!=null&&D.length?D.map(N=>N==="Code"?'Code':N==="Bild"?'Bild':'Text').join(" "):"–"}function T(D){if(!D)return"–";const N=D.quant||"?",Me=D.ctx?Math.round(D.ctx/1024)+"K":"?",Qe=D.size_bytes?(D.size_bytes/1024**3).toFixed(1)+" GB":"?";return`${N} · ${Me} · ${Qe}`}function X(D){var N;(N=navigator.clipboard)==null||N.writeText(D),ee("Kopiert: "+D)}var ve=Md(),Ye=r(Ze(ve),2),ae=r(s(Ye),6);nt(ae,21,()=>t(A),rt,(D,N)=>{var Me=vd(),Qe=s(Me),k={};$(()=>{g(Qe,t(N).name),k!==(k=t(N).name)&&(Me.value=(Me.__value=t(N).name)??"")}),h(D,Me)});var Be=r(ae,4),re=r(Be,2),F=s(re),Z=r(re,2);{var oe=D=>{var N=pd(),Me=s(N);$(()=>g(Me,t(v))),h(D,N)};q(Z,D=>{t(v)&&D(oe)})}var se=r(Ye,2),Oe=s(se),He=r(s(Oe)),mt=s(He),ut=r(Oe,4);{var vt=D=>{var N=fd();h(D,N)},Je=D=>{var N=kd(),Me=r(s(N));nt(Me,21,()=>t(o),rt,(Qe,k)=>{var L=di(),te=Ze(L);{var Pe=Fe=>{var Ee=hd(),$e=s(Ee),Xe=s($e),Ke=r($e,5),lt=s(Ke),P=r(lt,2);$(()=>g(Xe,t(k).name)),S("click",lt,()=>{var ie;ee("Lade im Cookbook ein Modell und setze den Alias auf: "+t(k).name),(ie=document.querySelector(".nav-item[data-view='cookbook']"))==null||ie.dispatchEvent(new MouseEvent("click"))}),S("click",P,()=>Ve(t(k).name)),h(Fe,Ee)},de=Fe=>{var Ee=_d(),$e=s(Ee),Xe=s($e),Ke=s(Xe),lt=r(Ke);{var P=R=>{var J=gd(),Q=s(J);$(()=>g(Q,t(k).role)),h(R,J)};q(lt,R=>{t(k).role&&R(P)})}var ie=r(Xe,2);{var we=R=>{var J=md(),Q=s(J);$(()=>g(Q,t(k).meta.filename)),h(R,J)};q(ie,R=>{var J;(J=t(k).meta)!=null&&J.filename&&R(we)})}var ot=r(ie,2),et=r(s(ot),2);nt(et,17,()=>{var R;return(R=t(k).api_ids)!=null&&R.length?t(k).api_ids:[t(k).name]},rt,(R,J)=>{var Q=bd(),le=s(Q);$(()=>g(le,t(J))),S("click",Q,()=>X(t(J))),h(R,Q)});var Qt=r($e);qe(Qt,()=>{var R;return yt((R=t(k).meta)==null?void 0:R.caps)},!0);var Zt=r(Qt);qe(Zt,()=>T(t(k).meta),!0);var qt=r(Zt);qe(qt,()=>Wo(t(k).state,t(k).download_progress),!0);var E=r(qt),H=s(E),Ne=r(E),ce=s(Ne),G=r(ce,2),j=r(G,2),W=r(j,2);$(()=>{g(Ke,`${t(k).name??""} `),g(H,t(k).port??"auto")}),S("click",ce,()=>he(t(k).name)),S("click",G,()=>Ie(t(k).name)),S("click",j,()=>Te(t(k).name)),S("click",W,()=>Ve(t(k).name)),h(Fe,Ee)};q(te,Fe=>{t(k).incomplete?Fe(Pe):Fe(de,-1)})}h(Qe,L)}),h(D,N)};q(ut,D=>{t(o).length?D(Je,-1):D(vt)})}var ze=r(se,2);{var Et=D=>{var N=yd(),Me=s(N),Qe=s(Me),k=r(Qe,4),L=s(k),te=r(k,2),Pe=r(s(te));qe(Pe,()=>mr(a));var de=r(te,2),Fe=r(de,2);{var Ee=we=>{var ot=wd(),et=s(ot),Qt=r(s(et),2),Zt=s(Qt),qt=r(Zt,2),E=r(et,2);$((H,Ne)=>{g(Zt,`Optimal ~${H??""}k → ~${t(z).meta.peak_ram_optimal_gb??""} GB Spitzenbedarf.`),g(qt,` Aktuell ~${Ne??""}k → ~${t(z).meta.peak_ram_gb??""} GB.`)},[()=>Math.round(t(z).meta.optimal_ctx/1024),()=>Math.round((t(z).meta.ctx||0)/1024)]),S("click",E,()=>f(M,t(z).meta.optimal_ctx,!0)),h(we,ot)};q(Fe,we=>{var ot;(ot=t(z).meta)!=null&&ot.optimal_ctx&&we(Ee)})}var $e=r(Fe,4),Xe=r(s($e),2),Ke=s(Xe),lt=r(Ke,2),P=s(lt),ie=r($e,2);$(()=>{g(L,t(z).name),Xt(lt,`color:${t(I)?"var(--accent)":"var(--mut)"}`),g(P,t(I)?"An (TTL = ∞)":"Aus (TTL = 5 min)")}),S("click",N,we=>{we.target.classList.contains("modal-overlay")&&f(C,!1)}),S("click",Qe,()=>f(C,!1)),gn(de,()=>t(M),we=>f(M,we)),Ro(Ke,()=>t(I),we=>f(I,we)),S("click",ie,fe),h(D,N)};q(ze,D=>{t(C)&&t(z)&&D(Et)})}var Tt=r(ze,2);{var $t=D=>{var N=Sd(),Me=s(N),Qe=s(Me),k=r(Qe,2),L=r(s(k));qe(L,()=>mr(i));var te=r(k,2),Pe=s(te),de=r(te,4);nt(de,21,()=>l,rt,(Ke,lt)=>{var P=xd(),ie=s(P);$(()=>{Ct(P,1,t(Y)===t(lt).id?"primary":"ghost"),qi(P,"title",t(lt).desc),g(ie,t(lt).label)}),S("click",P,()=>xe(t(lt).id)),h(Ke,P)});var Fe=r(de,4),Ee=r(Fe,2),$e=s(Ee),Xe=r($e,2);$(()=>g(Pe,t(ke))),S("click",N,Ke=>{Ke.target.classList.contains("modal-overlay")&&f(me,!1)}),S("click",Qe,()=>f(me,!1)),gn(Fe,()=>t(K),Ke=>f(K,Ke)),S("click",$e,()=>xe("")),S("click",Xe,()=>xe(t(K).trim().toLowerCase())),h(D,N)};q(Tt,D=>{t(me)&&D($t)})}$(()=>{re.disabled=t(b),g(F,t(b)?"…":"Senden"),g(mt,t(o).length?t(o).length+" konfiguriert":"")}),ya(ae,()=>t(c),D=>f(c,D)),gn(Be,()=>t(u),D=>f(u,D)),S("click",re,m),h(e,ve),Vn()}sa(["click"]);var Ad=_('
Prozessor (CPU)
%
Arbeitsspeicher
%
Grafikspeicher
%

System-Metriken (Bosgame)

Live-Auslastung deines Mini-PCs, alle 0,5 Sekunden.
Arbeitsspeicher (RAM)
Grafikspeicher (VRAM + GTT)
Speicherplatz (Disk)
Temperatur (GPU / CPU)
CPU-Verlauf
RAM-Verlauf
VRAM-Verlauf
',1),Cd=_(''),Td=_('
Gerade nichts los.
Alles ruhig — keine laufenden Aufgaben.
'),zd=_(' '),Pd=_(''),Dd=_(''),$d=_('
'),Ld=_('
'),Id=_('
'),Bd=_('

Aktivität

Live-Auslastung und laufende Aufgaben (Downloads, Updates) mit Protokoll.

Hintergrund-Aufgaben

Downloads & Updates erscheinen hier mit Live-Protokoll — zum Aufklappen klicken.
',1);function Od(e,n){Gn(n,!0);const a=O(()=>va.value),i=O(()=>va.tracked),l=O(()=>Pr.value);let o=jt({cpu:[],ram:[],gpu:[]});Ki(()=>{var ve;if(!t(l))return;const T=t(l).gpu,X=T&&T.vram.total+T.gtt.total>0?(T.vram.used+T.gtt.used)/(T.vram.total+T.gtt.total)*100:0;o.cpu=[...o.cpu,((ve=t(l).cpu)==null?void 0:ve.percent)??0].slice(-60),o.ram=[...o.ram,t(l).ram.percent].slice(-60),o.gpu=[...o.gpu,X].slice(-60)});const d=O(()=>()=>{var X;const T=(X=t(l))==null?void 0:X.gpu;return T&&T.vram.total+T.gtt.total>0?(T.vram.used+T.gtt.used)/(T.vram.total+T.gtt.total)*100:0}),c=O(()=>t(a).filter(T=>T.state!=="running"&&T.state!=="queued").length),u=O(()=>t(a).filter(T=>T.state==="failed").length);function v(T){if(T.state!=="running")return null;if(typeof T.progress=="number")return Math.min(100,T.progress);const ve=((T.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return ve?Math.min(100,parseFloat(ve[1])):null}function b(T){return T==null||T<0?"":T>=90?`noch ~${Math.round(T/60)} min`:`noch ~${Math.max(1,Math.round(T))} s`}function A(T){return T==="done"?'fertig':T==="failed"?'fehler':T==="canceled"?'abgebrochen':'läuft…'}function m(T){return T==="done"?"on":T==="failed"||T==="canceled"?"":"load"}async function x(T){try{await Se(`/api/jobs/${T}/cancel`,{method:"POST"}),ee("Abbruch angefordert…")}catch(X){ee(X.message,!0)}}async function C(T){try{await Se(`/api/jobs/${T}`,{method:"DELETE"})}catch(X){ee(X.message,!0)}}async function z(){try{const T=await Se("/api/jobs/clear",{method:"POST"});ee(`${T.removed} Einträge entfernt.`)}catch(T){ee(T.message,!0)}}function M(T,X){return T.map(ve=>`
`).join("")}var I=Bd(),Ie=r(Ze(I),2);{var fe=T=>{const X=O(()=>t(d)());var ve=Ad(),Ye=Ze(ve),ae=s(Ye),Be=r(s(ae),2),re=s(Be),F=r(Be,2),Z=s(F),oe=r(ae,2),se=r(s(oe),2),Oe=s(se),He=r(se,2),mt=s(He),ut=r(oe,2),vt=r(s(ut),2),Je=s(vt),ze=r(vt,2),Et=s(ze),Tt=r(Ye,2),$t=r(s(Tt),4),D=s($t),N=r(s(D)),Me=s(N),Qe=r(D,2),k=r(s(Qe),2),L=s(k),te=r(Qe,2),Pe=r(s(te)),de=s(Pe),Fe=r(te,2),Ee=r(s(Fe),2),$e=s(Ee),Xe=r($t,2),Ke=s(Xe),lt=r(s(Ke));qe(lt,()=>M(o.cpu,"--accent"),!0);var P=r(Ke,2),ie=r(s(P));qe(ie,()=>M(o.ram,"--purple"),!0);var we=r(P,2),ot=r(s(we));qe(ot,()=>M(o.gpu,"--on"),!0),$((et,Qt,Zt,qt,E,H,Ne,ce,G,j,W,R,J)=>{g(re,et),g(Z,Qt),g(Oe,Zt),g(mt,`${qt??""} / ${E??""}`),g(Je,H),g(Et,Ne),g(Me,`${ce??""} / ${G??""}`),g(L,j),g(de,`${W??""} % belegt`),g($e,`${R??""} / ${J??""}`)},[()=>{var et;return Math.round(((et=t(l).cpu)==null?void 0:et.percent)??0)},()=>{var et;return((et=t(l).cpu)==null?void 0:et.temp)!=null?`${Math.round(t(l).cpu.temp)}° CPU-Temp`:"Auslastung"},()=>Math.round(t(l).ram.percent),()=>oa(t(l).ram.used),()=>oa(t(l).ram.total),()=>Math.round(t(X)),()=>t(l).gpu_temp!=null?`${Math.round(t(l).gpu_temp)}° GPU-Temp`:"VRAM + GTT",()=>oa(t(l).ram.used),()=>oa(t(l).ram.total),()=>t(l).gpu?`${oa(t(l).gpu.vram.used+t(l).gpu.gtt.used)} / ${oa(t(l).gpu.vram.total+t(l).gpu.gtt.total)}`:"–",()=>{var et;return Math.round(((et=t(l).disk)==null?void 0:et.percent)??0)},()=>t(l).gpu_temp!=null?Math.round(t(l).gpu_temp)+"°":"–",()=>{var et;return((et=t(l).cpu)==null?void 0:et.temp)!=null?Math.round(t(l).cpu.temp)+"°":"–"}]),h(T,ve)};q(Ie,T=>{t(l)&&T(fe)})}var me=r(Ie,2),ke=s(me),K=r(s(ke),2),Y=s(K),he=r(K,2);{var xe=T=>{var X=Cd();S("click",X,z),h(T,X)};q(he,T=>{t(c)&&T(xe)})}var Te=r(ke,4);{var Ve=T=>{var X=Td();h(T,X)},yt=T=>{var X=di(),ve=Ze(X);nt(ve,17,()=>t(a),rt,(Ye,ae)=>{const Be=O(()=>v(t(ae))),re=O(()=>t(ae).state==="running"?b(t(ae).eta_s):""),F=O(()=>t(ae).state==="running"&&t(ae).rate_bps?oa(t(ae).rate_bps)+"/s":""),Z=O(()=>[t(re),t(F)].filter(Boolean).join(" · ")),oe=O(()=>t(i).includes(t(ae).id));var se=Id(),Oe=s(se),He=s(Oe),mt=r(He,2),ut=s(mt),vt=r(mt,2);{var Je=k=>{var L=zd(),te=s(L);$(Pe=>g(te,`${Pe??""} %${t(Z)?` · ${t(Z)}`:""}`),[()=>Math.round(t(Be))]),h(k,L)};q(vt,k=>{t(Be)!=null&&k(Je)})}var ze=r(vt,2);{var Et=k=>{var L=Pd();$(()=>Xt(L,`${t(Be)==null?"margin-left:auto;":""}margin-right:2px;padding:2px 9px;font-size:12px`)),S("click",L,te=>{te.stopPropagation(),x(t(ae).id)}),h(k,L)},Tt=k=>{var L=Dd();S("click",L,te=>{te.stopPropagation(),C(t(ae).id)}),h(k,L)};q(ze,k=>{t(ae).state==="running"?k(Et):k(Tt,-1)})}var $t=r(ze,2);qe($t,()=>A(t(ae).state));var D=r(Oe,2);{var N=k=>{var L=$d(),te=s(L);$(()=>Xt(te,`width:${t(Be)??""}%`)),h(k,L)};q(D,k=>{t(Be)!=null&&t(ae).state==="running"&&k(N)})}var Me=r(D,2);{var Qe=k=>{var L=Ld(),te=s(L);$(Pe=>g(te,Pe),[()=>(t(ae).log||[]).join(` +`)]),h(k,L)};q(Me,k=>{t(oe)&&k(Qe)})}$(k=>{Ct(He,1,`li-dot ${k??""}`),g(ut,t(ae).label)},[()=>m(t(ae).state)]),S("click",Oe,()=>va.toggle(t(ae).id)),S("keydown",Oe,k=>k.key==="Enter"&&va.toggle(t(ae).id)),h(Ye,se)}),h(T,X)};q(Te,T=>{t(a).length?T(yt,-1):T(Ve)})}$(()=>g(Y,t(a).length?t(u)?t(u)+" Fehler":t(a).length+" gesamt":"")),h(e,I),Vn()}sa(["click","keydown"]);var Rd=_(' '),Fd=_(''),Kd=_('✓ fertig'),Nd=_('✗ fehlgeschlagen'),qd=_('abgebrochen'),Gd=_('läuft…'),Vd=_('
'),Wd=_('

Aktueller Vorgang

'),Ud=_('

Server & Wartung

Dienste steuern, Updates einspielen und live mitlesen — ganz ohne SSH oder Terminal.

LLM-Engine (llama-swap)

Das Herzstück: lädt bei jeder Anfrage automatisch das passende Modell.
Adresse (für deine Tools)
Aktuell geladen
Konfigurierte Modelle

Dienste & Applikation

Diese Aktionen sind harmlos und passwortlos — es geht nichts dabei verloren.

Betriebssystem (Bosgame)

Tiefe Eingriffe — das Dashboard fragt einmalig nach deinem sudo-Passwort.

Live-Konsole

Live mitlesen, was der Dienst gerade tut.
',1);function jd(e,n){Gn(n,!0);const a=O(()=>_i.value),i=O(()=>va.value);let l=null,o=B(`Verbinde… +`),d=B("llama-swap"),c,u=B(null),v=B("");const b=new Set,A=O(()=>t(u)?t(i).find(P=>P.id===t(u)):null);Ki(()=>{if(!t(A))return;const P=t(A),ie=P.state==="done",we=P.state==="failed",ot=P.state==="canceled";(ie||we||ot)&&!b.has(P.id)&&(b.add(P.id),ee(ie?`✓ ${t(v)} abgeschlossen.`:ot?`${t(v)} abgebrochen.`:`✗ ${t(v)} fehlgeschlagen.`,we),ie&&setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),800))});function m(P,ie){f(u,P,!0),f(v,ie,!0),va.track(P)}bi(()=>{x()}),Ko(()=>{l==null||l.close()});function x(){l==null||l.close();const P=t(d);f(o,`Verbinde mit ${P}… +`);const ie=location.protocol==="https:"?"wss:":"ws:";l=new WebSocket(`${ie}//${location.host}/api/logs/${P}?token=${encodeURIComponent(tl())}`),l.onmessage=we=>{f(o,t(o)+we.data),c&&(c.scrollTop=c.scrollHeight)},l.onclose=()=>{f(o,t(o)+` +— Verbindung getrennt —`)},l.onerror=()=>l==null?void 0:l.close()}async function C(P,ie,we){if(await mn({title:ie,body:we,confirmLabel:"Neustarten"}))try{await Se(`/api/service/${P}/restart`,{method:"POST"}),ee("Neustart ausgelöst: "+P),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),2e3)}catch(ot){ee(ot.message,!0)}}async function z(){if(await mn({title:"Mission Control aktualisieren?",body:"Holt die neueste Dashboard-Version aus Gitea und startet automatisch neu. Die Seite trennt kurz und verbindet von selbst wieder (~10 Sek)."}))try{const P=await Se("/api/self-update",{method:"POST"});ee("Update läuft — Dashboard startet gleich neu."),m(P.job_id,"Mission Control Update")}catch(P){ee(P.message,!0)}}async function M(){if(await mn({title:"LLM-Engine aktualisieren?",body:"Lädt die neueste llama.cpp-ROCm-Version und installiert sie. Die Engine ist während des Updates kurz nicht erreichbar."}))try{const P=await Se("/api/update",{method:"POST"});ee("LLM-Engine-Update läuft."),m(P.job_id,"LLM-Engine-Update")}catch(P){ee(P.message,!0)}}async function I(){if(await mn({title:"Grafikspeicher leeren?",body:"Alle geladenen Modelle werden entladen. Sie laden beim nächsten Aufruf automatisch neu — es geht nichts verloren.",confirmLabel:"Leeren"}))try{await Se("/api/unload",{method:"POST"}),ee("Grafikspeicher geleert."),setTimeout(()=>document.dispatchEvent(new Event("mc:refresh")),600)}catch(P){ee(P.message,!0)}}async function Ie(){if(!await mn({title:"OS-Updates installieren?",body:"Führt apt update & upgrade aus. Das kann ein paar Minuten dauern; der Fortschritt erscheint in der Aktivität."}))return;const P=await jr({title:"sudo-Passwort",body:"Für die System-Updates wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Installieren"});if(P)try{const ie=await Se("/api/os-update",{method:"POST",body:JSON.stringify({password:P})});ee("OS-Update gestartet."),m(ie.job_id,"OS-Update")}catch(ie){ee(ie.message,!0)}}async function fe(){if(!await mn({title:"Server wirklich neu starten?",body:"Der ganze Bosgame startet physisch neu. Alles ist für ~1 Minute offline — auch dieses Dashboard.",confirmLabel:"Reboot",danger:!0}))return;const P=await jr({title:"sudo-Passwort",body:"Für den Reboot wird einmalig dein sudo-Passwort gebraucht.",placeholder:"sudo-Passwort",password:!0,confirmLabel:"Jetzt neustarten",danger:!0});if(P)try{await Se("/api/reboot",{method:"POST",body:JSON.stringify({password:P})}),ee("Reboot ausgelöst — bis gleich.")}catch(ie){ee(ie.message,!0)}}async function me(){f(ke,"prüfe…");try{const P=await Se("/api/integration/test");f(ke,P.ok?`✓ Engine antwortet — ${P.models.length} Modell(e): ${P.models.join(", ")}`:`✗ keine Verbindung: ${P.error}`,!0),f(K,P.ok,!0)}catch(P){f(ke,"✗ "+P.message),f(K,!1)}}let ke=B(""),K=B(!1);const Y=O(()=>{var P;return((P=t(a))==null?void 0:P.models)||[]}),he=["running","ready","loading","starting"],xe=O(()=>t(Y).find(P=>he.includes(P.state)));function Te(P){if(!P||P.state!=="running")return null;if(typeof P.progress=="number")return Math.min(100,P.progress);const we=((P.log||[]).at(-1)||"").match(/(\d+(?:\.\d+)?)\s*%/);return we?Math.min(100,parseFloat(we[1])):null}var Ve=Ud(),yt=r(Ze(Ve),2),T=s(yt),X=r(s(T),2),ve=s(X),Ye=r(T,4),ae=s(Ye),Be=r(s(ae)),re=s(Be),F=r(ae,2),Z=r(s(F),2),oe=s(Z),se=r(F,2),Oe=r(s(se),2),He=s(Oe),mt=r(Ye,2),ut=s(mt),vt=r(ut,2);{var Je=P=>{var ie=Rd(),we=s(ie);$(()=>{Xt(ie,`color:${t(K)?"#7ee29a":"#ff9b95"}`),g(we,t(ke))}),h(P,ie)};q(vt,P=>{t(ke)&&P(Je)})}var ze=r(yt,2),Et=r(s(ze),4),Tt=r(Et,2),$t=r(Tt,2),D=r($t,2),N=r(D,2),Me=r(ze,2),Qe=r(s(Me),4),k=r(Qe,2),L=r(Me,2);{var te=P=>{const ie=O(()=>t(A)),we=O(()=>t(ie).state==="done"),ot=O(()=>t(ie).state==="failed"),et=O(()=>t(ie).state==="canceled"),Qt=O(()=>t(we)||t(ot)||t(et)),Zt=O(()=>Te(t(ie)));var qt=Wd(),E=s(qt),H=r(s(E),2);{var Ne=_e=>{var bt=Fd();S("click",bt,async()=>{await mn({title:t(v)+" abbrechen?",body:"Der laufende Vorgang wird gestoppt.",confirmLabel:"Abbrechen",danger:!0})&&Se(`/api/jobs/${t(ie).id}/cancel`,{method:"POST"})}),h(_e,bt)};q(H,_e=>{t(Qt)||_e(Ne)})}var ce=r(H,2),G=s(ce);{var j=_e=>{var bt=Kd();h(_e,bt)},W=_e=>{var bt=Nd();h(_e,bt)},R=_e=>{var bt=qd();h(_e,bt)},J=_e=>{var bt=Gd();h(_e,bt)};q(G,_e=>{t(we)?_e(j):t(ot)?_e(W,1):t(et)?_e(R,2):_e(J,-1)})}var Q=r(E,2),le=s(Q),Ae=r(Q,2);{var be=_e=>{var bt=Vd(),Bn=s(bt);$(()=>Xt(Bn,`width:${t(Zt)??""}%`)),h(_e,bt)};q(Ae,_e=>{t(Zt)!=null&&!t(Qt)&&_e(be)})}var pt=r(Ae,2),xt=s(pt);$(_e=>{g(le,`${t(v)??""}${t(Qt)?t(we)?" — erfolgreich.":t(et)?" — abgebrochen.":" — fehlgeschlagen.":" läuft…"}`),g(xt,_e)},[()=>(t(ie).log||[]).join(` +`)]),h(P,qt)};q(L,P=>{t(A)&&P(te)})}var Pe=r(L,2),de=s(Pe),Fe=r(s(de),2),Ee=s(Fe);Ee.value=Ee.__value="llama-swap";var $e=r(Ee);$e.value=$e.__value="mission-control";var Xe=r($e);Xe.value=Xe.__value="system";var Ke=r(de,4),lt=s(Ke);Fo(Ke,P=>c=P,()=>c),$(P=>{var ie,we,ot;Xt(X,`margin-left:auto;${(ie=t(a))!=null&&ie.swap_ok?"background:rgba(63,185,80,.12);border-color:rgba(63,185,80,.25);color:#7ee29a":"background:rgba(248,81,73,.12);border-color:rgba(248,81,73,.3);color:#ff9b95"}`),g(ve,(we=t(a))!=null&&we.swap_ok?"● erreichbar":"● offline"),g(re,(((ot=t(a))==null?void 0:ot.swap_url)||"—")+"/v1"),g(oe,t(xe)?t(xe).name+` (${t(xe).state})`:"nichts geladen — lädt bei der nächsten Anfrage"),g(He,P),g(lt,t(o))},[()=>t(Y).filter(P=>!P.incomplete).length||"keine"]),S("click",ut,me),S("click",Et,()=>C("llama-swap","LLM-Engine neustarten?","Die Engine startet neu. Geladene Modelle werden kurz entladen (~5 Sekunden), laden danach automatisch wieder.")),S("click",Tt,()=>C("mission-control","Dashboard neustarten?","Diese Oberfläche trennt sich kurz und verbindet automatisch wieder.")),S("click",$t,z),S("click",D,M),S("click",N,I),S("click",Qe,Ie),S("click",k,fe),S("change",Fe,x),ya(Fe,()=>t(d),P=>f(d,P)),h(e,Ve),Vn()}sa(["click","change"]);var Hd=_('
Lade Setups…
'),Jd=_(' ×',1),er=_('
★ Beste Wahl für dein System
'),Qd=_('
Dein Setup
'),Zd=_(''),Yd=_('
'),Xd=_('· ⚠ Cache veraltet'),ec=_(" ",1),tc=_('
Frage Quellen ab…
'),nc=_('
'),ac=_('✓ installiert'),ic=_(''),rc=_('

'),sc=_('

'),lc=_(''),oc=_('

'),dc=_('
'),cc=_('
'),uc=_('
'),vc=_(" "),pc=_('
'),fc=_('
Größter Spitzenbedarf: . Es läuft immer nur ein Modell gleichzeitig — das größte bestimmt, ob das Setup passt.
'),hc=_('Alternative: — passt auf dein System.',1),gc=_('
⚠ Dieses Setup übersteigt deinen verfügbaren Speicher.
'),mc=_(''),bc=_('
Lade Dateien von HuggingFace…
'),Yr=_(""),_c=_('
Empfohlener Kontext für deine Hardware: übernehmen
'),kc=_('
Ressourcen-Check
'),wc=_('
⚠ Diese Datei ist zu groß für deinen Speicher. Kleinere Alternative: — einfach auswählen.
'),yc=_('
⚠ Alle Varianten dieses Modells sind zu groß für deinen Speicher. Ein kleineres Modell aus den Empfehlungen wäre die bessere Wahl.
'),xc=_('
',1),Sc=_('
Keine GGUF-Dateien im Repo gefunden.
'),Mc=_(''),Ec=_('
'),Ac=_(''),Cc=_('

Cookbook

Modelle finden, installieren und eigene Setups zusammenstellen.

1 · Anwendungsfall wählen & installieren

Hier starten: Fertige Modell-Bundles für deinen Anwendungsfall — ein Klick installiert alles. Die Hardware-Ampel zeigt vorab, ob das Setup auf deinen PC passt.

Aktuell die besten Modelle für dein System

Top-Modelle je Kategorie von HuggingFace — Hardware-Fit wird live für dein System berechnet.

Profi-Suche (HuggingFace)

Direkt HuggingFace durchsuchen — oder eine Modell-URL einfügen für den direkten Sprung.
',1);function Tc(e,n){Gn(n,!0);const a="Kontext = das Kurzzeitgedächtnis des Modells. Größer = merkt sich mehr, braucht aber mehr Speicher und wird etwas langsamer.",i="MoE (Mixture of Experts): viele Parameter fürs Wissen, aber pro Wort ist nur ein kleiner Teil aktiv → fast große-Modell-Qualität bei hohem Tempo. Ideal für deine APU.",l={perfect:0,marginal:1,too_tight:2},o={vision:"Bilder",coder:"Coden",reasoning:"Logik",agent:"Agenten & Tools",scout:"Allrounder",reviewer:"Review",manager:"Manager"},d=[{label:"Bilder",kw:["-vl-","-vl","vision","llava","multimodal","-mm-","pixtral"]},{label:"Coden",kw:["coder","-code-","code-","codestral","starcoder"]},{label:"Logik",kw:["-r1","deepseek-r1","reasoning","qwq","magistral","-think","thinking","-o1"]},{label:"Agenten & Tools",kw:["hermes","-tool","command-r","watt","-fc-","function"]}];function c(y){const w=(y||"").toLowerCase();for(const U of d)if(U.kw.some(V=>w.includes(V)))return U.label;return"Allrounder"}function u(y=""){const w=y.toLowerCase();return/\d+x\d+(\.\d+)?b/.test(w)||new RegExp("(?{mt(),ut()});async function mt(){f(z,!0);try{const y=await Se("/api/cookbook/recipes");f(x,y.recipes||[],!0),f(C,y.recommended_id||null,!0)}catch(y){ee(y.message,!0)}f(z,!1)}async function ut(y=!1){f(I,!0);try{const w=await Se("/api/cookbook/discover"+(y?"?force=true":""));f(M,w,!0),f(Ie,w.stale,!0)}catch(w){ee("Empfehlungen nicht ladbar: "+w.message,!0)}f(I,!1)}function vt(y){y=y.trim();const w=y.match(/huggingface\.co\/([^\s/]+\/[^\s/?#]+)/i);return w?w[1]:/^[\w.-]+\/[\w.-]+$/.test(y)?y:null}async function Je(){const y=t(fe).trim(),w=vt(y);let U=y;if(t(K)&&!w&&(U=U?U+" "+t(K):t(K)),!U&&!w){f(me,[],!0);return}f(ke,!0),f(he,[],!0),f(xe,-1);try{if(w)f(me,[{id:w,author:w.split("/")[0],downloads:0}],!0);else{const V=`https://huggingface.co/api/models?search=${encodeURIComponent(U)}&filter=gguf&sort=${encodeURIComponent(t(Y))}&direction=-1&limit=40`,pe=await fetch(V);f(me,await pe.json(),!0)}t(me).forEach((V,pe)=>ze(pe,V.id))}catch(V){ee(V.message,!0),f(me,[],!0)}f(ke,!1)}async function ze(y,w){var U;try{const V=await Se("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:w,ctx:8192})});if(!((U=V.files)!=null&&U.length)){t(he)[y]=null,Et();return}const pe=V.files.find(ft=>{var _t;return(_t=ft.quant)==null?void 0:_t.includes("Q4_K_M")})||V.files[0];t(he)[y]=pe.fit.level,Et()}catch{t(he)[y]=null,Et()}}function Et(){let y=-1,w=99;t(he).forEach((U,V)=>{if(U==null)return;const pe=l[U]??99;pe=0&&w<=1?y:-1,!0)}function Tt(y){f(Te,t(x).find(w=>w.id===y),!0)}async function $t(y){const w=document.getElementById("cb-r-install-btn");w&&(w.disabled=!0,w.textContent="Starte…");try{const U=await Se("/api/cookbook/install-recipe",{method:"POST",body:JSON.stringify({recipe_id:y,hf_token:li()})});ee(`${U.count} Download${U.count!==1?"s":""} läuft — Modelle erscheinen danach automatisch im Modelle-Tab.`),f(Te,null),He("activity")}catch(U){ee(U.message,!0),w&&(w.disabled=!1,w.textContent="Installieren")}}async function D(y,w){var U,V;f(Ve,!0),f(yt,w,!0),f(T,y,!0),f(Ye,""),f(ae,8192),f(X,null),f(re,null),f(ve,""),f(Be,!0);try{if(f(X,await Se("/api/cookbook/analyze",{method:"POST",body:JSON.stringify({repo_id:y,ctx:8192})}),!0),(V=(U=t(X))==null?void 0:U.files)!=null&&V.length){const pe=t(X).files.find(ft=>{var _t;return(_t=ft.quant)==null?void 0:_t.includes("Q4_K_M")})||t(X).files[0];f(ve,pe.filename,!0),pe.optimal_ctx&&t(ae)===8192&&f(ae,pe.optimal_ctx,!0),N()}}catch(pe){ee(pe.message,!0)}f(Be,!1)}function N(){var y,w,U;!((w=(y=t(X))==null?void 0:y.files)!=null&&w.length)||!t(ve)||(f(re,t(X).files.find(V=>V.filename===t(ve))||null,!0),(U=t(re))!=null&&U.optimal_ctx&&t(ae)===8192&&f(ae,t(re).optimal_ctx,!0))}async function Me(){var y,w;if(!t(T)||!t(ve))return ee("Bitte eine GGUF-Datei wählen.",!0);f(Be,!0);try{const U=((y=t(X))==null?void 0:y.params_b)??7,V=((w=t(re))==null?void 0:w.quant)??"Q4_K_M";await Se("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:t(T),role:t(Ye),params_b:U,quant:V,file:t(ve),ctx:t(ae),hf_token:li()})}),ee("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),f(Ve,!1),He("activity")}catch(U){ee("Fehler: "+U.message,!0)}f(Be,!1)}async function Qe(y,w,U,V){V.disabled=!0,V.textContent="Starte…";try{await Se("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:y,role:w,params_b:U,quant:"Q4_K_M",hf_token:li()})}),ee("Download läuft — Modell erscheint danach automatisch im Modelle-Tab."),He("activity")}catch(pe){ee(pe.message,!0),V.disabled=!1,V.textContent="Installieren"}}function k(){f(Oe,null),f(Z,""),f(oe,""),f(se,[{repo:"",role:"",quant:"Q4_K_M"}],!0),f(F,!0)}function L(y){const w=t(x).find(U=>U.id===y);w&&(f(Oe,y,!0),f(Z,w.title,!0),f(oe,w.desc||"",!0),f(se,w.models.map(U=>({repo:U.repo,role:U.role,quant:U.quant||"Q4_K_M"})),!0),f(F,!0))}async function te(){if(!t(Z).trim())return ee("Bitte einen Titel angeben.",!0);const y=t(se).filter(w=>w.repo.trim());if(!y.length)return ee("Mindestens ein Modell (Repo) angeben.",!0);try{t(Oe)?(await Se("/api/cookbook/user-recipe/"+encodeURIComponent(t(Oe)),{method:"PUT",body:JSON.stringify({title:t(Z),desc:t(oe),models:y})}),ee("Setup aktualisiert.")):(await Se("/api/cookbook/user-recipe",{method:"POST",body:JSON.stringify({title:t(Z),desc:t(oe),models:y})}),ee("Setup gespeichert.")),f(F,!1),mt()}catch(w){ee(w.message,!0)}}async function Pe(y){const w=t(x).find(U=>U.id===y);if(await mn({title:`„${(w==null?void 0:w.title)||y}" löschen?`,body:"Dein eigenes Setup wird aus dem Cookbook entfernt. Bereits installierte Modelle bleiben unangetastet.",confirmLabel:"Löschen",danger:!0}))try{await Se("/api/cookbook/user-recipe/"+encodeURIComponent(y),{method:"DELETE"}),ee("Setup gelöscht."),mt()}catch(U){ee(U.message,!0)}}function de(y){if(!u(y))return"";const w=v(y);return`MoE${w?` · ~${w}B aktiv`:""}`}function Fe(y){return y?`${$n(y)}`:""}var Ee=Cc(),$e=r(Ze(Ee),2),Xe=s($e),Ke=r(s(Xe),2),lt=r(Xe,4);{var P=y=>{var w=Hd();h(y,w)},ie=y=>{var w=Yd();nt(w,21,()=>t(x),rt,(U,V)=>{const pe=O(()=>t(V).id===t(C));var ft=Zd(),_t=s(ft);{var ue=Ce=>{var dt=Jd(),Vt=Ze(dt),Bt=r(Vt,2);S("click",Vt,zt=>{zt.stopPropagation(),L(t(V).id)}),S("keydown",Vt,zt=>{zt.key==="Enter"&&(zt.stopPropagation(),L(t(V).id))}),S("click",Bt,zt=>{zt.stopPropagation(),Pe(t(V).id)}),S("keydown",Bt,zt=>{zt.key==="Enter"&&(zt.stopPropagation(),Pe(t(V).id))}),h(Ce,dt)};q(_t,Ce=>{t(V).user&&Ce(ue)})}var De=r(_t,2);{var Ge=Ce=>{var dt=er();h(Ce,dt)},St=Ce=>{var dt=Qd();h(Ce,dt)};q(De,Ce=>{t(pe)?Ce(Ge):t(V).user&&Ce(St,1)})}var We=r(De,2),tt=s(We),kt=s(tt),Lt=s(kt),tn=r(tt,2),Mt=s(tn),Ue=r(We,2),It=s(Ue),Gt=r(Ue,2),At=s(Gt);$((Ce,dt)=>{Ct(ft,1,`card-btn${t(pe)?" cb-best":""}`),g(Lt,t(V).title),Ct(tn,1,`fit-badge ${Ce??""}`),g(Mt,dt),g(It,t(V).desc),g(At,`${t(V).models.length??""} Modell${t(V).models.length>1?"e":""} im Setup`)},[()=>b(t(V).fit_level),()=>A(t(V).fit_level)]),S("click",ft,()=>Tt(t(V).id)),h(U,ft)}),h(y,w)};q(lt,y=>{t(z)?y(P):y(ie,-1)})}var we=r($e,2),ot=s(we),et=r(s(ot),2),Qt=s(et);{var Zt=y=>{const w=O(()=>Math.round((Date.now()/1e3-t(M).updated)/60));var U=ec(),V=Ze(U);{var pe=Ge=>{var St=ri();$(()=>g(St,`Quellen befragt vor ${t(w)??""} min`)),h(Ge,St)},ft=Ge=>{var St=ri();$(We=>g(St,`Quellen befragt vor ${We??""} h`),[()=>Math.round(t(w)/60)]),h(Ge,St)},_t=Ge=>{var St=ri();$(We=>g(St,`Quellen befragt vor ${We??""} Tg.`),[()=>Math.round(t(w)/1440)]),h(Ge,St)};q(V,Ge=>{t(w)<60?Ge(pe):t(w)<1440?Ge(ft,1):Ge(_t,-1)})}var ue=r(V,2);{var De=Ge=>{var St=Xd();h(Ge,St)};q(ue,Ge=>{t(Ie)&&Ge(De)})}h(y,U)};q(Qt,y=>{var w;(w=t(M))!=null&&w.updated&&y(Zt)})}var qt=r(et,2),E=s(qt),H=r(ot,4);{var Ne=y=>{var w=tc();h(y,w)},ce=y=>{var w=di(),U=Ze(w);nt(U,17,()=>t(M).categories,rt,(V,pe)=>{var ft=sc(),_t=s(ft),ue=s(_t),De=s(ue),Ge=r(_t,2);nt(Ge,21,()=>t(pe).models,rt,(St,We)=>{const tt=O(()=>t(pe).recommended&&t(We).repo===t(pe).recommended);var kt=rc(),Lt=s(kt);{var tn=ct=>{var gt=er();h(ct,gt)};q(Lt,ct=>{t(tt)&&ct(tn)})}var Mt=r(Lt,2),Ue=s(Mt),It=s(Ue),Gt=s(It),At=r(It,2),Ce=s(At),dt=r(Ue,2),Vt=s(dt),Bt=r(Mt,2),zt=s(Bt);qe(zt,()=>Fe(o[t(We).role]||c(t(We).repo)));var On=r(zt,2);qe(On,()=>de(t(We).repo));var Hn=r(Bt,2),An=s(Hn),Ea=r(Hn,2);nt(Ea,17,()=>t(We).requirements||[],rt,(ct,gt)=>{var Rt=nc(),Cn=s(Rt);$(()=>g(Cn,`⚠ ${t(gt)??""}`)),h(ct,Rt)});var wt=r(Ea,4),at=s(wt);{var ht=ct=>{var gt=ac();$(()=>qi(gt,"title",`bereits eingerichtet als ${t(We).installed??""}`)),h(ct,gt)},Pt=ct=>{var gt=ic();S("click",gt,Rt=>Qe(t(We).repo,t(We).role,t(We).params_b,Rt.currentTarget)),h(ct,gt)};q(at,ct=>{t(We).installed?ct(ht):ct(Pt,-1)})}$((ct,gt,Rt)=>{Ct(kt,1,`card${t(tt)?" res-best":""}`),g(Gt,t(We).name),g(Ce,`${t(We).author??""} · ${t(We).params_b??""}B`),Ct(dt,1,`fit-badge ${ct??""}`),g(Vt,t(We).fit.text),g(An,`${gt??""} · ⬇ ${Rt??""}`)},[()=>b(t(We).fit.level),()=>m(t(We).fit),()=>(t(We).downloads||0).toLocaleString()]),h(St,kt)}),$(()=>g(De,t(pe).title)),h(V,ft)}),h(y,w)};q(H,y=>{var w;t(I)&&!t(M)?y(Ne):(w=t(M))!=null&&w.categories&&y(ce,1)})}var G=r(we,2),j=r(s(G),4),W=s(j),R=r(W,2),J=s(R);J.value=J.__value="downloads";var Q=r(J);Q.value=Q.__value="trending";var le=r(Q);le.value=le.__value="created_at";var Ae=r(R,2),be=s(Ae),pt=r(j,2);nt(pt,20,()=>["","coder","vision","reasoning","chat","agent"],rt,(y,w)=>{var U=lc(),V=s(U);$(()=>{Ct(U,1,t(K)===w?"primary":"ghost"),g(V,w||"Alle")}),S("click",U,()=>{f(K,w,!0),Je()}),h(y,U)});var xt=r(pt,2);{var _e=y=>{var w=dc();nt(w,21,()=>t(me),rt,(U,V,pe)=>{var ft=oc(),_t=s(ft);{var ue=Bt=>{var zt=er();h(Bt,zt)};q(_t,Bt=>{pe===t(xe)&&Bt(ue)})}var De=r(_t,2),Ge=s(De),St=s(Ge),We=s(St),tt=r(St,2),kt=s(tt),Lt=r(Ge,2),tn=s(Lt),Mt=r(De,2),Ue=s(Mt);qe(Ue,()=>Fe(c(t(V).id)));var It=r(Ue,2);qe(It,()=>de(t(V).id));var Gt=r(Mt,4),At=s(Gt),Ce=s(At),dt=r(At,2),Vt=s(dt);$((Bt,zt,On,Hn,An)=>{Ct(ft,1,`card${pe===t(xe)?" res-best":""}`),g(We,Bt),g(kt,t(V).author||""),Ct(Lt,1,`fit-badge ${zt??""}`),g(tn,On),g(Ce,Hn),g(Vt,`⬇ ${An??""}`)},[()=>t(V).id.split("/").pop(),()=>t(he)[pe]?b(t(he)[pe]):"warn",()=>t(he)[pe]?A(t(he)[pe]):"prüfe…",()=>t(he)[pe]?m({req_gb:0,tps:0}):"Hardware-Fit…",()=>(t(V).downloads||0).toLocaleString()]),S("click",ft,()=>D(t(V).id,t(V).id.split("/").pop())),h(U,ft)}),h(y,w)};q(xt,y=>{t(me).length&&y(_e)})}var bt=r(G,2);{var Bn=y=>{const w=O(()=>t(Te));var U=mc(),V=s(U),pe=s(V),ft=r(pe,2),_t=s(ft),ue=r(ft,2),De=s(ue),Ge=r(ue,2);nt(Ge,21,()=>t(w).models,rt,(Mt,Ue)=>{var It=pc(),Gt=s(It),At=s(Gt),Ce=s(At),dt=s(Ce),Vt=r(Ce,2),Bt=s(Vt),zt=r(Vt,2);qe(zt,()=>de(t(Ue).repo));var On=r(At,2);{var Hn=ht=>{var Pt=cc(),ct=s(Pt);$(()=>g(ct,t(Ue).why)),h(ht,Pt)};q(On,ht=>{t(Ue).why&&ht(Hn)})}var An=r(On,2);{var Ea=ht=>{var Pt=uc(),ct=s(Pt);$((gt,Rt,Cn)=>g(ct,`~${gt??""} GB · ~${Rt??""} Tok/s · optimal ~${Cn??""}k Kontext`),[()=>(t(Ue).fit.req_gb??0).toFixed(1),()=>Math.round(t(Ue).fit.tps??0),()=>Math.round((t(Ue).optimal_ctx||8192)/1024)]),h(ht,Pt)};q(An,ht=>{t(Ue).fit&&ht(Ea)})}var wt=r(Gt,2);{var at=ht=>{var Pt=vc(),ct=s(Pt);$(gt=>{Ct(Pt,1,`fit-badge ${gt??""}`),g(ct,t(Ue).fit.text)},[()=>b(t(Ue).fit.level)]),h(ht,Pt)};q(wt,ht=>{t(Ue).fit&&ht(at)})}$(()=>{g(dt,t(Ue).name),g(Bt,t(Ue).role)}),h(Mt,It)});var St=r(Ge,2);{var We=Mt=>{const Ue=O(()=>Math.max(...t(w).models.map(Ce=>{var dt;return((dt=Ce.fit)==null?void 0:dt.req_gb)??0})));var It=fc(),Gt=r(s(It)),At=s(Gt);$(Ce=>g(At,`~${Ce??""} GB`),[()=>t(Ue).toFixed(1)]),h(Mt,It)};q(St,Mt=>{t(w).models.length&&t(w).models[0].fit&&Mt(We)})}var tt=r(St,2);{var kt=Mt=>{const Ue=O(()=>t(x).find(Ce=>!Ce.user&&Ce.fit_level!=="too_tight"&&Ce.id!==t(w).id));var It=gc(),Gt=r(s(It));{var At=Ce=>{var dt=hc(),Vt=r(Ze(dt)),Bt=s(Vt);$(()=>g(Bt,`„${t(Ue).title??""}" ansehen`)),S("click",Vt,zt=>{zt.preventDefault(),f(Te,null),setTimeout(()=>Tt(t(Ue).id),50)}),h(Ce,dt)};q(Gt,Ce=>{t(Ue)&&Ce(At)})}h(Mt,It)};q(tt,Mt=>{t(w).fit_level==="too_tight"&&Mt(kt)})}var Lt=r(tt,2),tn=s(Lt);$(()=>{g(_t,t(w).title),g(De,t(w).desc),Ct(Lt,1,`primary${t(w).fit_level==="too_tight"?" warn":""}`),g(tn,t(w).fit_level==="too_tight"?"Trotzdem installieren (nicht empfohlen)":"Komplettes Setup installieren")}),S("click",U,Mt=>{Mt.target.classList.contains("modal-overlay")&&f(Te,null)}),S("click",pe,()=>f(Te,null)),S("click",Lt,()=>$t(t(w).id)),h(y,U)};q(bt,y=>{t(Te)&&y(Bn)})}var Un=r(bt,2);{var la=y=>{var w=Mc(),U=s(w),V=s(U),pe=r(V,2),ft=s(pe),_t=r(pe,2),ue=s(_t),De=r(_t,2);{var Ge=tt=>{var kt=bc();h(tt,kt)},St=tt=>{var kt=xc(),Lt=r(Ze(kt),2);nt(Lt,21,()=>t(X).files,rt,(wt,at)=>{const ht=O(()=>t(at).fit.level==="perfect"?"●":t(at).fit.level==="marginal"?"◐":"○");var Pt=Yr(),ct=s(Pt),gt={};$(()=>{g(ct,`${t(ht)??""} ${t(at).filename??""}`),gt!==(gt=t(at).filename)&&(Pt.value=(Pt.__value=t(at).filename)??"")}),h(wt,Pt)});var tn=r(Lt,2),Mt=s(tn),Ue=r(s(Mt),2),It=r(Mt,2),Gt=s(It),At=r(s(Gt));qe(At,()=>mr(a));var Ce=r(Gt,2),dt=r(tn,2);{var Vt=wt=>{var at=_c(),ht=r(s(at)),Pt=s(ht),ct=r(ht,2);$(gt=>g(Pt,`~${gt??""}k`),[()=>Math.round(t(re).optimal_ctx/1024)]),S("click",ct,gt=>{gt.preventDefault(),f(ae,t(re).optimal_ctx,!0)}),h(wt,at)};q(dt,wt=>{var at;(at=t(re))!=null&&at.optimal_ctx&&wt(Vt)})}var Bt=r(dt,2);{var zt=wt=>{var at=kc(),ht=s(at),Pt=r(s(ht),2),ct=s(Pt),gt=r(ht,2),Rt=s(gt);$((Cn,ki,Wi)=>{g(ct,`~${Cn??""} GB · ~${ki??""} Tok/s · ${(t(re).quant||"GGUF")??""}`),Ct(gt,1,`fit-badge ${Wi??""}`),g(Rt,t(re).fit.text)},[()=>(t(re).fit.req_gb??0).toFixed(1),()=>Math.round(t(re).fit.tps??0),()=>b(t(re).fit.level)]),h(wt,at)};q(Bt,wt=>{t(re)&&wt(zt)})}var On=r(Bt,2);{var Hn=wt=>{const at=O(()=>t(X).files.find(Rt=>Rt.fit.level!=="too_tight"&&Rt.filename!==t(ve)));var ht=di(),Pt=Ze(ht);{var ct=Rt=>{var Cn=wc(),ki=r(s(Cn)),Wi=s(ki);$(Ui=>g(Wi,`${t(at).filename??""} (${Ui??""})`),[()=>A(t(at).fit.level)]),S("click",ki,Ui=>{Ui.preventDefault(),f(ve,t(at).filename,!0),N()}),h(Rt,Cn)},gt=Rt=>{var Cn=yc();h(Rt,Cn)};q(Pt,Rt=>{t(at)?Rt(ct):Rt(gt,-1)})}h(wt,ht)};q(On,wt=>{var at,ht;((at=t(re))==null?void 0:at.fit.level)==="too_tight"&&((ht=t(X))!=null&&ht.files)&&wt(Hn)})}var An=r(On,2),Ea=s(An);$(()=>{var wt,at;Ct(An,1,`primary${((wt=t(re))==null?void 0:wt.fit.level)==="too_tight"?" warn":""}`),An.disabled=t(Be),g(Ea,t(Be)?"Starte…":((at=t(re))==null?void 0:at.fit.level)==="too_tight"?"Trotzdem holen (zu groß — nicht empfohlen)":"Herunterladen & Einpflegen")}),S("change",Lt,N),ya(Lt,()=>t(ve),wt=>f(ve,wt)),gn(Ue,()=>t(Ye),wt=>f(Ye,wt)),gn(Ce,()=>t(ae),wt=>f(ae,wt)),S("click",An,Me),h(tt,kt)},We=tt=>{var kt=Sc();h(tt,kt)};q(De,tt=>{var kt,Lt;t(Be)&&!t(X)?tt(Ge):(Lt=(kt=t(X))==null?void 0:kt.files)!=null&&Lt.length?tt(St,1):t(Be)||tt(We,2)})}$(()=>{g(ft,t(yt)),g(ue,t(T))}),S("click",w,tt=>{tt.target.classList.contains("modal-overlay")&&f(Ve,!1)}),S("click",V,()=>f(Ve,!1)),h(y,w)};q(Un,y=>{t(Ve)&&y(la)})}var jn=r(Un,2);{var Ha=y=>{var w=Ac(),U=s(w),V=s(U),pe=r(V,2),ft=s(pe),_t=r(pe,6),ue=r(_t,4),De=r(ue,4);nt(De,17,()=>t(se),rt,(tt,kt,Lt)=>{var tn=Ec(),Mt=s(tn),Ue=r(Mt,2),It=r(Ue,2);nt(It,20,()=>["Q4_K_M","Q5_K_M","Q6_K","Q8_0","Q3_K_M"],rt,(At,Ce)=>{var dt=Yr(),Vt=s(dt),Bt={};$(()=>{g(Vt,Ce),Bt!==(Bt=Ce)&&(dt.__value=Ce)}),h(At,dt)});var Gt=r(It,2);gn(Mt,()=>t(kt).repo,At=>t(kt).repo=At),gn(Ue,()=>t(kt).role,At=>t(kt).role=At),ya(It,()=>t(kt).quant,At=>t(kt).quant=At),S("click",Gt,()=>f(se,t(se).filter((At,Ce)=>Ce!==Lt),!0)),h(tt,tn)});var Ge=r(De,2),St=r(Ge,4),We=s(St);$(()=>{g(ft,t(Oe)?"Setup bearbeiten":"Eigenes Setup erstellen"),g(We,t(Oe)?"Änderungen speichern":"Setup speichern")}),S("click",w,tt=>{tt.target.classList.contains("modal-overlay")&&f(F,!1)}),S("click",V,()=>f(F,!1)),gn(_t,()=>t(Z),tt=>f(Z,tt)),gn(ue,()=>t(oe),tt=>f(oe,tt)),S("click",Ge,()=>f(se,[...t(se),{repo:"",role:"",quant:"Q4_K_M"}],!0)),S("click",St,te),h(y,w)};q(jn,y=>{t(F)&&y(Ha)})}$(()=>{qt.disabled=t(I),g(E,t(I)?"Suche…":"Aktualisieren"),Ae.disabled=t(ke),g(be,t(ke)?"Lade…":"Suchen")}),S("click",Ke,k),S("click",qt,()=>ut(!0)),S("keydown",W,y=>y.key==="Enter"&&Je()),gn(W,()=>t(fe),y=>f(fe,y)),ya(R,()=>t(Y),y=>f(Y,y)),S("click",Ae,Je),h(e,Ee),Vn()}sa(["click","keydown","change"]);var zc=_(`
Du öffnest Mission Control über einen Proxy/Namen. Die Engine läuft auf Port 8080 ohne HTTPS direkt am Bosgame. + Trag in deinen Tools die LAN-IP ein: http://192.168.178.151:8080/v1 — nicht den Proxy-Namen.
`),Pc=_(' '),Dc=_('
'),$c=_(' '),Lc=_(''),Xr=_(''),Ic=_('

Jan AI ist eine Desktop-App — kein Browser, kein Server, kein Admin-Panel. Einfach installieren und loslegen.

Jan AI öffnen → linke Leiste → Remote-Modelle+ Modell hinzufügen:

API-Key: ein beliebiger Wert (z.B. local). Jan AI fragt danach beim Einrichten.
Jan AI herunterladen: jan.ai — kostenlos, open source, Windows/macOS/Linux.
',1),Bc=_('

Datei anlegen oder öffnen: ~/.continue/config.json

Falls bereits eine config.json vorhanden: nur den "models"-Eintrag ergänzen, nicht die ganze Datei ersetzen.

Danach Continue in VS Code neu starten → im Chat-Panel das Modell wählen.

Continue: continue.dev — kostenlose VS Code / JetBrains Extension. Hinweis: 2026 von Cursor akquiriert — aktuell weiter aktiv und kostenlos.
',1),Oc=_('

Antigravity (Googles agentic IDE, VS Code-basiert) unterstützt OpenAI-kompatible Endpoints direkt:

Settings → Models → Custom Endpoint+ hinzufügen:

API-Key: ein beliebiger Wert (z.B. local). Danach das Modell in der Model-Liste auswählen.
Antigravity herunterladen: antigravityide.net — kostenlose Einzelperson-Tier, VS Code-basiert.
',1),Rc=_('

Öffne die Zed-Settings mit Cmd/Strg + , und füge diesen Block in deine bestehende settings.json ein. Falls bereits ein "bosgame"-Eintrag existiert: vorher löschen.

Nur diesen Block einfügen, nicht die ganze Datei ersetzen — sonst gehen andere Einstellungen verloren.

API-Key: Öffne den Agent-Panel → Anbieter bosgame → trag irgendeinen Wert ein (z.B. local).

Danach im Agent-Panel das Modell auswählen.
',1),Fc=_('

Datei anlegen oder öffnen:

Windows: %USERPROFILE%\\.config\\opencode\\opencode.json

Nur den "provider"-Block einfügen. Falls bereits ein "llama-swap"-Eintrag vorhanden: vorher löschen, sonst erscheinen Modelle doppelt.

Danach in OpenCode /models wählen.

',1),Kc=_('

In Cline/Cursor den Provider „OpenAI Compatible" wählen:

API-Key: ein beliebiger Wert (z.B. local).
',1),Nc=_('

Settings → Admin Panel → Connections → neue OpenAI-Verbindung:

',1),qc=_('

Bilder einbinden (Vision)

Mit Vision-Modellen kannst du Screenshots oder Fehlerbilder direkt mitschicken.
'),Gc=_('

2 · Modelle auswählen

Wähle, welche Modelle im Config-Snippet erscheinen sollen.

3 · Tool wählen

Für welches Werkzeug brauchst du die Konfiguration?
Chat
Coding-Assistenten

4 · Config-Snippet

',1),Vc=_('

2 · Erst ein Modell installieren

Noch kein Modell eingerichtet
Bevor du ein Tool verbinden kannst, braucht die Engine mindestens ein Modell. Das Config-Snippet wird dann automatisch mit deinen echten Modellnamen befüllt.
'),Wc=_(''),Uc=_('

In Cline: MCP-Einstellungen öffnen (Stecker-Icon in der Cline-Sidebar) → „Add MCP Server" → diesen Block einfügen.

In Claude Code: Block in ~/.claude/settings.json unter "mcpServers" einfügen.

Einmalig auf dem Windows-PC: pip install mcp httpx ausführen — danach mcp_memory.py aus dem Repo-Ordner erreichbar machen (Pfad im Snippet anpassen).
',1),jc=_('

Block in ~/.config/opencode/opencode.json unter "mcpServers" einfügen.

Einmalig: pip install mcp httpx — und Pfad zu mcp_memory.py im Snippet anpassen.
',1),Hc=_('

Block in die MCP-Config des jeweiligen Tools einfügen. Der Bosgame-Pfad /opt/mission-control/mcp_memory.py ist bereits korrekt — kein weiteres Setup nötig.

'),Jc=_(`

Verbinden

Schritt für Schritt: KI-Modelle in deine Tools einbinden — getestet, erklärt, mit Copy-Paste-Config.

1 · Verbindung prüfen

Stelle sicher, dass die LLM-Engine erreichbar ist, bevor du Tools konfigurierst.

Wie funktioniert das Auto-Swap?

Gedächtnis-MCP

Neu in v7
Damit Cline, OpenCode und Claude Code sich Projektfakten, Entscheidungen und Präferenzen + über Sessions hinweg merken — geteilt über alle Tools, verwaltet im Gedächtnis-Tab.
`,1);function Qc(e,n){Gn(n,!0);const a=O(()=>_i.value),i=O(()=>{var k;return(((k=t(a))==null?void 0:k.models)||[]).filter(L=>!L.incomplete)}),l=O(A);let o=B("zed"),d=B(jt([])),c=B(""),u=B(!1),v=B("cline");const b=O(()=>Y(t(v)));function A(){return`http://${location.hostname}:8080/v1`}function m(k){return/^\d{1,3}(\.\d{1,3}){3}$/.test(k)}function x(){return location.protocol==="https:"||!m(location.hostname)}const C=O(()=>t(d).length?t(d):t(i).map(k=>k.name)),z=O(()=>t(C)[0]||"coder"),M=O(()=>{var k;return(k=t(i).find(L=>{var te,Pe;return(Pe=(te=L.meta)==null?void 0:te.caps)==null?void 0:Pe.includes("Bild")}))==null?void 0:k.name});function I(k,L){const Pe=(L.length?t(i).filter(de=>L.includes(de.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(de=>{var $e,Xe;const Fe=((($e=de.meta)==null?void 0:$e.caps)||[]).some(Ke=>/Bild|Vision/i.test(Ke)),Ee=((Xe=de.meta)==null?void 0:Xe.ctx)||131072;return` { "name": "${de.name}", "display_name": "${de.name}", "max_tokens": ${Ee}${Fe?', "capabilities": { "tools": true, "images": true }':""} }`}).join(`, `);return`"language_models": { "openai_compatible": { "bosgame": { - "api_url": "${B}", + "api_url": "${k}", "available_models": [ -${Oe} +${Pe} ] } } -}`}function S(B,U){const Oe=(U.length?t(i).filter(he=>U.includes(he.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(he=>{var ht;const St=((ht=he.meta)==null?void 0:ht.ctx)||131072;return` "${he.name}": { "name": "${he.name}", "contextWindowSize": ${St} }`}).join(`, +}`}function Ie(k,L){const Pe=(L.length?t(i).filter(de=>L.includes(de.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(de=>{var Ee;const Fe=((Ee=de.meta)==null?void 0:Ee.ctx)||131072;return` "${de.name}": { "name": "${de.name}", "contextWindowSize": ${Fe} }`}).join(`, `);return`"provider": { "llama-swap": { "npm": "@ai-sdk/openai-compatible", "name": "Bosgame (llama-swap)", "options": { - "baseURL": "${B}", + "baseURL": "${k}", "apiKey": "local" }, "models": { -${Oe} +${Pe} } } -}`}function $(B,U){return`{ +}`}function fe(k,L){return`{ "models": [ -${(U.length?t(i).filter(he=>U.includes(he.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(he=>` { - "title": "llama-swap / ${he.name}", +${(L.length?t(i).filter(de=>L.includes(de.name)):t(i).length?t(i):[{name:"coder",meta:{}}]).map(de=>` { + "title": "llama-swap / ${de.name}", "provider": "openai", - "model": "${he.name}", - "apiBase": "${B}", + "model": "${de.name}", + "apiBase": "${k}", "apiKey": "local" }`).join(`, `)} ] -}`}async function Ce(){h(c,"Teste…");try{const B=await we("/api/integration/test");h(u,B.ok,!0),h(c,B.ok?`✓ Verbunden — ${B.models.length} Modell(e): ${B.models.join(", ")}`:`✗ Keine Verbindung: ${B.error}`,!0)}catch(B){h(u,!1),h(c,"✗ "+B.message)}}function oe(B){var ce;const U=B.querySelector("code");U&&((ce=navigator.clipboard)==null||ce.writeText(U.textContent||""))}function ae(B){var U;(U=navigator.clipboard)==null||U.writeText(B.value)}var xe=Vc(),V=s(We(xe),2),Q=s(l(V),6),fe=l(Q),be=s(fe,2),Se=s(Q,2);{var Ne=B=>{var U=zc();m(B,U)},bt=I(()=>E());K(Se,B=>{t(bt)&&B(Ne)})}var C=s(Se,2),Y=l(C),ue=s(Y,2);{var Ue=B=>{var U=Dc(),ce=l(U);P(()=>{fn(U,`color:${t(u)?"#7ee29a":"#ff9b95"}`),b(ce,t(c))}),m(B,U)};K(ue,B=>{t(c)&&B(Ue)})}var te=s(V,2),Te=s(l(te),2);st(Te,20,()=>[["⚡","Kein manuelles Starten nötig",'Wenn du in Zed oder OpenCode „coder" auswählst und eine Anfrage sendest, lädt llama-swap das Modell automatisch — in ca. 2–5 Sekunden.'],["🔄","Modelle wechseln sich automatisch ab","Rufst du ein anderes Modell auf, entlädt llama-swap das aktuelle (nach TTL-Ablauf) und lädt das neue. Es läuft immer nur eines gleichzeitig."],["🧠","Zwei Modelle gleichzeitig aktiv halten","Du hast 124 GB RAM — genug für z.B. Scout 8B (~5 GB) dauerhaft geladen + ein größeres Modell das swappt. Dafür beim Scout im Modelle-Tab → Konfigurieren die TTL auf 99999 setzen."]],rt,(B,U)=>{var ce=I(()=>Ca(U,3));let Oe=()=>t(ce)[0],he=()=>t(ce)[1],St=()=>t(ce)[2];var ht=Pc(),Mt=l(ht),Et=l(Mt),At=s(Mt,2),It=l(At),qt=l(It),z=s(It,2),N=l(z);P(()=>{b(Et,Oe()),b(qt,he()),b(N,St())}),m(B,ht)});var ie=s(te,2);{var lt=B=>{var U=Gc(),ce=We(U),Oe=l(ce),he=s(l(Oe),2),St=l(he),ht=s(Oe,4);st(ht,21,()=>t(i),rt,(j,ee)=>{const W=I(()=>t(d).includes(t(ee).name));var J=$c(),x=l(J);P(()=>{fn(J,`cursor:pointer;${t(W)?"background:rgba(45,212,191,.2);border-color:var(--accent);color:var(--accent)":""}`),b(x,t(ee).name)}),A("click",J,()=>h(d,t(W)?t(d).filter(L=>L!==t(ee).name):[...t(d),t(ee).name],!0)),A("keydown",J,L=>L.key==="Enter"&&h(d,t(W)?t(d).filter(R=>R!==t(ee).name):[...t(d),t(ee).name],!0)),m(j,J)});var Mt=s(ht,2);{var Et=j=>{var ee=Lc(),W=l(ee);A("click",W,J=>{J.preventDefault(),h(d,[],!0)}),m(j,ee)};K(Mt,j=>{t(d).length&&j(Et)})}var At=s(ce,2),It=s(l(At),6);st(It,20,()=>[["janai","Jan AI","Einfachstes Chat-Interface — Desktop-App, kein Setup"],["openwebui","OpenWebUI","Browser-Chat für Teams — mehr Features, mehr Setup"]],rt,(j,ee)=>{var W=I(()=>Ca(ee,3));let J=()=>t(W)[0],x=()=>t(W)[1],L=()=>t(W)[2];var R=Xr(),ne=l(R),Z=l(ne),Je=s(ne,2),Qe=l(Je);P(()=>{kt(R,1,`card-btn${t(o)===J()?" cb-best":""}`),b(Z,x()),b(Qe,L())}),A("click",R,()=>h(o,J(),!0)),m(j,R)});var qt=s(It,4);st(qt,20,()=>[["continue","Continue","VS Code/JetBrains — Hilfe ohne Agent-Overhead"],["cline","Cline","VS Code/JetBrains/Zed — voller Coding-Agent"],["antigravity","Antigravity","Googles agentic IDE — VS Code-basiert"],["opencode","OpenCode","Terminal-Agent — autonom, mächtig"],["zed","Zed","Schneller nativer Editor mit KI-Panel"]],rt,(j,ee)=>{var W=I(()=>Ca(ee,3));let J=()=>t(W)[0],x=()=>t(W)[1],L=()=>t(W)[2];var R=Xr(),ne=l(R),Z=l(ne),Je=s(ne,2),Qe=l(Je);P(()=>{kt(R,1,`card-btn${t(o)===J()?" cb-best":""}`),b(Z,x()),b(Qe,L())}),A("click",R,()=>h(o,J(),!0)),m(j,R)});var z=s(At,2),N=s(l(z),2);{var Me=j=>{var ee=Ic(),W=s(We(ee),6),J=l(W),x=s(J,2),L=s(W,4),R=l(L),ne=s(R,2);P(()=>{Hn(J,t(r)),Hn(R,t(y))}),A("click",x,Z=>ae(Z.currentTarget.previousElementSibling)),A("click",ne,Z=>ae(Z.currentTarget.previousElementSibling)),m(j,ee)},ut=j=>{const ee=I(()=>$(t(r),t(f)));var W=Bc(),J=s(We(W),4),x=l(J),L=s(x,2),R=l(L),ne=l(R),Z=s(J,2),Je=s(l(Z)),Qe=l(Je);P(()=>{b(ne,t(ee)),b(Qe,`llama-swap / ${t(y)??""}`)}),A("click",x,et=>oe(et.currentTarget.parentElement)),m(j,W)},G=j=>{var ee=Rc(),W=s(We(ee),6),J=l(W),x=s(J,2),L=s(W,4),R=l(L),ne=s(R,2),Z=s(L,2),Je=s(l(Z),3),Qe=l(Je);P(()=>{Hn(J,t(r)),Hn(R,t(y)),b(Qe,t(y))}),A("click",x,et=>ae(et.currentTarget.previousElementSibling)),A("click",ne,et=>ae(et.currentTarget.previousElementSibling)),m(j,ee)},ze=j=>{const ee=I(()=>D(t(r),t(f)));var W=Oc(),J=s(We(W),4),x=l(J),L=s(x,2),R=l(L),ne=l(R),Z=s(J,4),Je=s(l(Z)),Qe=l(Je);P(()=>{b(ne,t(ee)),b(Qe,`bosgame / ${t(y)??""}`)}),A("click",x,et=>oe(et.currentTarget.parentElement)),m(j,W)},He=j=>{const ee=I(()=>S(t(r),t(f)));var W=Fc(),J=s(We(W),6),x=l(J),L=s(x,2),R=l(L),ne=l(R),Z=s(J,2),Je=s(l(Z),3),Qe=l(Je);P(()=>{b(ne,t(ee)),b(Qe,`llama-swap/${t(y)??""}`)}),A("click",x,et=>oe(et.currentTarget.parentElement)),m(j,W)},Pt=j=>{var ee=qc(),W=s(We(ee),4),J=l(W),x=s(J,2),L=s(W,4),R=l(L),ne=s(R,2);P(()=>{Hn(J,t(r)),Hn(R,t(y))}),A("click",x,Z=>ae(Z.currentTarget.previousElementSibling)),A("click",ne,Z=>ae(Z.currentTarget.previousElementSibling)),m(j,ee)},$t=j=>{var ee=Nc(),W=s(We(ee),4),J=l(W),x=s(J,2),L=s(W,4),R=l(L),ne=s(R,2);P(()=>Hn(J,t(r))),A("click",x,Z=>ae(Z.currentTarget.previousElementSibling)),A("click",ne,Z=>ae(Z.currentTarget.previousElementSibling)),m(j,ee)};K(N,j=>{t(o)==="janai"?j(Me):t(o)==="continue"?j(ut,1):t(o)==="antigravity"?j(G,2):t(o)==="zed"?j(ze,3):t(o)==="opencode"?j(He,4):t(o)==="cline"?j(Pt,5):t(o)==="openwebui"&&j($t,6)})}var vt=s(z,2);{var _t=j=>{const ee=I(()=>`curl ${t(r)}/chat/completions \\ +}`}async function me(){f(c,"Teste…");try{const k=await Se("/api/integration/test");f(u,k.ok,!0),f(c,k.ok?`✓ Verbunden — ${k.models.length} Modell(e): ${k.models.join(", ")}`:`✗ Keine Verbindung: ${k.error}`,!0)}catch(k){f(u,!1),f(c,"✗ "+k.message)}}function ke(k){var te;const L=k.querySelector("code");L&&((te=navigator.clipboard)==null||te.writeText(L.textContent||""))}function K(k){var L;(L=navigator.clipboard)==null||L.writeText(k.value)}function Y(k){return`{ + "mcpServers": { + "mission-control-memory": { + "command": "${k==="bosgame"?"/opt/mission-control/.venv/bin/python":"python"}", + "args": ["${k==="bosgame"?"/opt/mission-control/mcp_memory.py":"C:\\\\Users\\\\TobisPC\\\\mission-control\\\\mcp_memory.py"}"], + "env": { + "MC_URL": "http://192.168.178.151:9000" + } + } + } +}`}var he=Jc(),xe=r(Ze(he),2),Te=r(s(xe),6),Ve=s(Te),yt=r(Ve,2),T=r(Te,2);{var X=k=>{var L=zc();h(k,L)},ve=O(()=>x());q(T,k=>{t(ve)&&k(X)})}var Ye=r(T,2),ae=s(Ye),Be=r(ae,2);{var re=k=>{var L=Pc(),te=s(L);$(()=>{Xt(L,`color:${t(u)?"#7ee29a":"#ff9b95"}`),g(te,t(c))}),h(k,L)};q(Be,k=>{t(c)&&k(re)})}var F=r(xe,2),Z=r(s(F),2);nt(Z,20,()=>[["⚡","Kein manuelles Starten nötig",'Wenn du in Zed oder OpenCode „coder" auswählst und eine Anfrage sendest, lädt llama-swap das Modell automatisch — in ca. 2–5 Sekunden.'],["🔄","Modelle wechseln sich automatisch ab","Rufst du ein anderes Modell auf, entlädt llama-swap das aktuelle (nach TTL-Ablauf) und lädt das neue. Es läuft immer nur eines gleichzeitig."],["🧠","Zwei Modelle gleichzeitig aktiv halten","Du hast 124 GB RAM — genug für z.B. Scout 8B (~5 GB) dauerhaft geladen + ein größeres Modell das swappt. Dafür beim Scout im Modelle-Tab → Konfigurieren die TTL auf 99999 setzen."]],rt,(k,L)=>{var te=O(()=>ea(L,3));let Pe=()=>t(te)[0],de=()=>t(te)[1],Fe=()=>t(te)[2];var Ee=Dc(),$e=s(Ee),Xe=s($e),Ke=r($e,2),lt=s(Ke),P=s(lt),ie=r(lt,2),we=s(ie);$(()=>{g(Xe,Pe()),g(P,de()),g(we,Fe())}),h(k,Ee)});var oe=r(F,2);{var se=k=>{var L=Gc(),te=Ze(L),Pe=s(te),de=r(s(Pe),2),Fe=s(de),Ee=r(Pe,4);nt(Ee,21,()=>t(i),rt,(G,j)=>{const W=O(()=>t(d).includes(t(j).name));var R=$c(),J=s(R);$(()=>{Xt(R,`cursor:pointer;${t(W)?"background:rgba(45,212,191,.2);border-color:var(--accent);color:var(--accent)":""}`),g(J,t(j).name)}),S("click",R,()=>f(d,t(W)?t(d).filter(Q=>Q!==t(j).name):[...t(d),t(j).name],!0)),S("keydown",R,Q=>Q.key==="Enter"&&f(d,t(W)?t(d).filter(le=>le!==t(j).name):[...t(d),t(j).name],!0)),h(G,R)});var $e=r(Ee,2);{var Xe=G=>{var j=Lc(),W=s(j);S("click",W,R=>{R.preventDefault(),f(d,[],!0)}),h(G,j)};q($e,G=>{t(d).length&&G(Xe)})}var Ke=r(te,2),lt=r(s(Ke),6);nt(lt,20,()=>[["janai","Jan AI","Einfachstes Chat-Interface — Desktop-App, kein Setup"],["openwebui","OpenWebUI","Browser-Chat für Teams — mehr Features, mehr Setup"]],rt,(G,j)=>{var W=O(()=>ea(j,3));let R=()=>t(W)[0],J=()=>t(W)[1],Q=()=>t(W)[2];var le=Xr(),Ae=s(le),be=s(Ae),pt=r(Ae,2),xt=s(pt);$(()=>{Ct(le,1,`card-btn${t(o)===R()?" cb-best":""}`),g(be,J()),g(xt,Q())}),S("click",le,()=>f(o,R(),!0)),h(G,le)});var P=r(lt,4);nt(P,20,()=>[["continue","Continue","VS Code/JetBrains — Hilfe ohne Agent-Overhead"],["cline","Cline","VS Code/JetBrains/Zed — voller Coding-Agent"],["antigravity","Antigravity","Googles agentic IDE — VS Code-basiert"],["opencode","OpenCode","Terminal-Agent — autonom, mächtig"],["zed","Zed","Schneller nativer Editor mit KI-Panel"]],rt,(G,j)=>{var W=O(()=>ea(j,3));let R=()=>t(W)[0],J=()=>t(W)[1],Q=()=>t(W)[2];var le=Xr(),Ae=s(le),be=s(Ae),pt=r(Ae,2),xt=s(pt);$(()=>{Ct(le,1,`card-btn${t(o)===R()?" cb-best":""}`),g(be,J()),g(xt,Q())}),S("click",le,()=>f(o,R(),!0)),h(G,le)});var ie=r(Ke,2),we=r(s(ie),2);{var ot=G=>{var j=Ic(),W=r(Ze(j),6),R=s(W),J=r(R,2),Q=r(W,4),le=s(Q),Ae=r(le,2);$(()=>{Qn(R,t(l)),Qn(le,t(z))}),S("click",J,be=>K(be.currentTarget.previousElementSibling)),S("click",Ae,be=>K(be.currentTarget.previousElementSibling)),h(G,j)},et=G=>{const j=O(()=>fe(t(l),t(C)));var W=Bc(),R=r(Ze(W),4),J=s(R),Q=r(J,2),le=s(Q),Ae=s(le),be=r(R,2),pt=r(s(be)),xt=s(pt);$(()=>{g(Ae,t(j)),g(xt,`llama-swap / ${t(z)??""}`)}),S("click",J,_e=>ke(_e.currentTarget.parentElement)),h(G,W)},Qt=G=>{var j=Oc(),W=r(Ze(j),6),R=s(W),J=r(R,2),Q=r(W,4),le=s(Q),Ae=r(le,2),be=r(Q,2),pt=r(s(be),3),xt=s(pt);$(()=>{Qn(R,t(l)),Qn(le,t(z)),g(xt,t(z))}),S("click",J,_e=>K(_e.currentTarget.previousElementSibling)),S("click",Ae,_e=>K(_e.currentTarget.previousElementSibling)),h(G,j)},Zt=G=>{const j=O(()=>I(t(l),t(C)));var W=Rc(),R=r(Ze(W),4),J=s(R),Q=r(J,2),le=s(Q),Ae=s(le),be=r(R,4),pt=r(s(be)),xt=s(pt);$(()=>{g(Ae,t(j)),g(xt,`bosgame / ${t(z)??""}`)}),S("click",J,_e=>ke(_e.currentTarget.parentElement)),h(G,W)},qt=G=>{const j=O(()=>Ie(t(l),t(C)));var W=Fc(),R=r(Ze(W),6),J=s(R),Q=r(J,2),le=s(Q),Ae=s(le),be=r(R,2),pt=r(s(be),3),xt=s(pt);$(()=>{g(Ae,t(j)),g(xt,`llama-swap/${t(z)??""}`)}),S("click",J,_e=>ke(_e.currentTarget.parentElement)),h(G,W)},E=G=>{var j=Kc(),W=r(Ze(j),4),R=s(W),J=r(R,2),Q=r(W,4),le=s(Q),Ae=r(le,2);$(()=>{Qn(R,t(l)),Qn(le,t(z))}),S("click",J,be=>K(be.currentTarget.previousElementSibling)),S("click",Ae,be=>K(be.currentTarget.previousElementSibling)),h(G,j)},H=G=>{var j=Nc(),W=r(Ze(j),4),R=s(W),J=r(R,2),Q=r(W,4),le=s(Q),Ae=r(le,2);$(()=>Qn(R,t(l))),S("click",J,be=>K(be.currentTarget.previousElementSibling)),S("click",Ae,be=>K(be.currentTarget.previousElementSibling)),h(G,j)};q(we,G=>{t(o)==="janai"?G(ot):t(o)==="continue"?G(et,1):t(o)==="antigravity"?G(Qt,2):t(o)==="zed"?G(Zt,3):t(o)==="opencode"?G(qt,4):t(o)==="cline"?G(E,5):t(o)==="openwebui"&&G(H,6)})}var Ne=r(ie,2);{var ce=G=>{const j=O(()=>`curl ${t(l)}/chat/completions \\ -H "Content-Type: application/json" \\ -d '{ - "model": "${t(T)}", + "model": "${t(M)}", "messages": [{"role":"user","content":[{"type":"text","text":"Was ist auf dem Bild falsch?"},{"type":"image_url","image_url":{"url":"data:image/png;base64,"}}]}] -}'`);var W=Kc(),J=l(W),x=s(l(J),2),L=l(x);Ae(L,()=>Bt("check"));var R=s(L),ne=s(J,4),Z=l(ne),Je=s(Z,2),Qe=l(Je),et=l(Qe);P(()=>{b(R,` „${t(T)??""}" bereit`),b(et,t(ee))}),A("click",Z,M=>oe(M.currentTarget.parentElement)),m(j,W)};K(vt,j=>{t(T)&&j(_t)})}P(()=>b(St,t(d).length?`${t(d).length} von ${t(i).length} ausgewählt`:"alle werden eingeschlossen")),m(B,U)},je=B=>{var U=Wc(),ce=s(l(U),2),Oe=s(l(ce),4);A("click",Oe,()=>{var he;return(he=document.querySelector(".nav-item[data-view='cookbook']"))==null?void 0:he.dispatchEvent(new MouseEvent("click"))}),m(B,U)};K(ie,B=>{t(i).length?B(lt):B(je,-1)})}P(()=>Hn(fe,t(r))),A("click",be,B=>{const U=B.currentTarget.previousElementSibling;ae(U)}),A("click",Y,Ce),m(e,xe),ia()}xa(["click","keydown"]);var jc=w('
'),Hc=w('

Für dich: Upgrades

Neuere Modelle, die ein installiertes ersetzen können.
'),Jc=w('
Lade News… (erstes Laden kann kurz dauern)
'),Qc=w('
'),Zc=w('
Keine News geladen
Die Quellen sind gerade nicht erreichbar — später nochmal probieren.
'),Yc=w('für dich'),Xc=w('
'),eu=w('
'),tu=w('

News

Aktuelles aus der Local-LLM-Welt — aus kuratierten Quellen.
',1);function nu(e,n){aa(n,!0);let a=O(Ht([])),i=O(Ht([])),r=O(!0),o=O("");const d=V=>V==="perfect"?"ok":V==="marginal"?"warn":"bad";function c(V){const Q=Math.max(0,Date.now()/1e3-V);return Q<60?Q+"s":Q<3600?Math.floor(Q/60)+"m":Q<86400?Math.floor(Q/3600)+"h":Math.floor(Q/86400)+"d"}async function u(){h(r,!0),h(o,"");try{h(a,(await we("/api/news")).items||[],!0)}catch(V){h(o,V.message||"Fehler beim Laden",!0)}finally{h(r,!1)}}async function v(){try{h(i,(await we("/api/cookbook/upgrades")).upgrades||[],!0)}catch{h(i,[],!0)}}async function g(V,Q){var fe;Q.disabled=!0,Q.textContent="Starte…";try{await we("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:V.repo,role:V.role,params_b:V.params_b,quant:V.quant,hf_token:li()})}),(fe=document.querySelector(".nav-item[data-view='activity']"))==null||fe.dispatchEvent(new MouseEvent("click"))}catch(be){Q.disabled=!1,Q.textContent="Installieren",alert("Fehler: "+be.message)}}function E(){u(),v()}bi(()=>{u(),v()});var f=tu(),y=We(f),T=s(l(y),2),D=s(y,2);{var S=V=>{var Q=Hc(),fe=l(Q),be=s(l(fe),2),Se=l(be),Ne=s(fe,4);st(Ne,21,()=>t(i),rt,(bt,C)=>{var Y=jc(),ue=l(Y),Ue=l(ue),te=l(Ue),Te=l(te),ie=s(te,2),lt=l(ie),je=s(Ue,2),B=l(je),U=s(ue,2);P(ce=>{b(Te,t(C).name),kt(ie,1,`fit-badge ${ce??""}`),b(lt,t(C).fit.text),b(B,`Ersetzt dein „${t(C).old??""}". ${t(C).why??""}`)},[()=>d(t(C).fit.level)]),A("click",U,ce=>g(t(C),ce.currentTarget)),m(bt,Y)}),P(()=>b(Se,t(i).length)),m(V,Q)};K(D,V=>{t(i).length&&V(S)})}var $=s(D,2);{var Ce=V=>{var Q=Jc();m(V,Q)},oe=V=>{var Q=Qc(),fe=l(Q);P(()=>b(fe,t(o))),m(V,Q)},ae=V=>{var Q=Zc();m(V,Q)},xe=V=>{var Q=eu();st(Q,21,()=>t(a),rt,(fe,be,Se)=>{var Ne=Xc();kt(Ne,1,`news-card${Se===0?" featured":""}`);var bt=l(Ne),C=l(bt),Y=l(C),ue=s(C,2);{var Ue=je=>{var B=Yc();m(je,B)};K(ue,je=>{t(be).relevant&&je(Ue)})}var te=s(ue,2),Te=l(te),ie=s(bt,2),lt=l(ie);P(je=>{Ni(Ne,"href",t(be).link),b(Y,t(be).source),b(Te,je),b(lt,t(be).title)},[()=>t(be).ts?c(t(be).ts):""]),m(fe,Ne)}),m(V,Q)};K($,V=>{t(r)?V(Ce):t(o)?V(oe,1):t(a).length?V(xe,-1):V(ae,2)})}A("click",T,E),m(e,f),ia()}xa(["click"]);const au=[{label:"Einstieg",tutorials:[["Dein erster Workflow — in 3 Schritten",` +}'`);var W=qc(),R=s(W),J=r(s(R),2),Q=s(J);qe(Q,()=>Ft("check"));var le=r(Q),Ae=r(R,4),be=s(Ae),pt=r(be,2),xt=s(pt),_e=s(xt);$(()=>{g(le,` „${t(M)??""}" bereit`),g(_e,t(j))}),S("click",be,bt=>ke(bt.currentTarget.parentElement)),h(G,W)};q(Ne,G=>{t(M)&&G(ce)})}$(()=>g(Fe,t(d).length?`${t(d).length} von ${t(i).length} ausgewählt`:"alle werden eingeschlossen")),h(k,L)},Oe=k=>{var L=Vc(),te=r(s(L),2),Pe=r(s(te),4);S("click",Pe,()=>{var de;return(de=document.querySelector(".nav-item[data-view='cookbook']"))==null?void 0:de.dispatchEvent(new MouseEvent("click"))}),h(k,L)};q(oe,k=>{t(i).length?k(se):k(Oe,-1)})}var He=r(oe,2),mt=r(s(He),2),ut=r(s(mt)),vt=r(mt,2);nt(vt,20,()=>[["cline","Cline / Claude Code","Windows — Tools auf dem Entwicklungs-PC"],["opencode","OpenCode","Windows — Terminal-Agent"],["bosgame","Direkt am Bosgame","Wenn das Tool am Server läuft"]],rt,(k,L)=>{var te=O(()=>ea(L,3));let Pe=()=>t(te)[0],de=()=>t(te)[1],Fe=()=>t(te)[2];var Ee=Wc(),$e=s(Ee),Xe=s($e),Ke=r($e,2),lt=s(Ke);$(()=>{Ct(Ee,1,`card-btn${t(v)===Pe()?" cb-best":""}`),g(Xe,de()),g(lt,Fe())}),S("click",Ee,()=>f(v,Pe(),!0)),h(k,Ee)});var Je=r(vt,2),ze=s(Je),Et=r(ze,2),Tt=s(Et),$t=s(Tt),D=r(Je,2);{var N=k=>{var L=Uc();h(k,L)},Me=k=>{var L=jc();h(k,L)},Qe=k=>{var L=Hc();h(k,L)};q(D,k=>{t(v)==="cline"?k(N):t(v)==="opencode"?k(Me,1):k(Qe,-1)})}$(()=>{Qn(Ve,t(l)),g($t,t(b))}),S("click",yt,k=>{const L=k.currentTarget.previousElementSibling;K(L)}),S("click",ae,me),S("click",ut,k=>{var L;k.preventDefault(),(L=document.querySelector(".nav-item[data-view='memory']"))==null||L.click()}),S("click",ze,k=>ke(k.currentTarget.parentElement)),h(e,he),Vn()}sa(["click","keydown"]);var Zc=_('
'),Yc=_('

Für dich: Upgrades

Neuere Modelle, die ein installiertes ersetzen können.
'),Xc=_('
Lade News… (erstes Laden kann kurz dauern)
'),eu=_('
'),tu=_('
Keine News geladen
Die Quellen sind gerade nicht erreichbar — später nochmal probieren.
'),nu=_('für dich'),au=_('
'),iu=_('
'),ru=_('

News

Aktuelles aus der Local-LLM-Welt — aus kuratierten Quellen.
',1);function su(e,n){Gn(n,!0);let a=B(jt([])),i=B(jt([])),l=B(!0),o=B("");const d=K=>K==="perfect"?"ok":K==="marginal"?"warn":"bad";function c(K){const Y=Math.max(0,Date.now()/1e3-K);return Y<60?Y+"s":Y<3600?Math.floor(Y/60)+"m":Y<86400?Math.floor(Y/3600)+"h":Math.floor(Y/86400)+"d"}async function u(){f(l,!0),f(o,"");try{f(a,(await Se("/api/news")).items||[],!0)}catch(K){f(o,K.message||"Fehler beim Laden",!0)}finally{f(l,!1)}}async function v(){try{f(i,(await Se("/api/cookbook/upgrades")).upgrades||[],!0)}catch{f(i,[],!0)}}async function b(K,Y){var he;Y.disabled=!0,Y.textContent="Starte…";try{await Se("/api/cookbook/install-model",{method:"POST",body:JSON.stringify({repo:K.repo,role:K.role,params_b:K.params_b,quant:K.quant,hf_token:li()})}),(he=document.querySelector(".nav-item[data-view='activity']"))==null||he.dispatchEvent(new MouseEvent("click"))}catch(xe){Y.disabled=!1,Y.textContent="Installieren",alert("Fehler: "+xe.message)}}function A(){u(),v()}bi(()=>{u(),v()});var m=ru(),x=Ze(m),C=r(s(x),2),z=r(x,2);{var M=K=>{var Y=Yc(),he=s(Y),xe=r(s(he),2),Te=s(xe),Ve=r(he,4);nt(Ve,21,()=>t(i),rt,(yt,T)=>{var X=Zc(),ve=s(X),Ye=s(ve),ae=s(Ye),Be=s(ae),re=r(ae,2),F=s(re),Z=r(Ye,2),oe=s(Z),se=r(ve,2);$(Oe=>{g(Be,t(T).name),Ct(re,1,`fit-badge ${Oe??""}`),g(F,t(T).fit.text),g(oe,`Ersetzt dein „${t(T).old??""}". ${t(T).why??""}`)},[()=>d(t(T).fit.level)]),S("click",se,Oe=>b(t(T),Oe.currentTarget)),h(yt,X)}),$(()=>g(Te,t(i).length)),h(K,Y)};q(z,K=>{t(i).length&&K(M)})}var I=r(z,2);{var Ie=K=>{var Y=Xc();h(K,Y)},fe=K=>{var Y=eu(),he=s(Y);$(()=>g(he,t(o))),h(K,Y)},me=K=>{var Y=tu();h(K,Y)},ke=K=>{var Y=iu();nt(Y,21,()=>t(a),rt,(he,xe,Te)=>{var Ve=au();Ct(Ve,1,`news-card${Te===0?" featured":""}`);var yt=s(Ve),T=s(yt),X=s(T),ve=r(T,2);{var Ye=Z=>{var oe=nu();h(Z,oe)};q(ve,Z=>{t(xe).relevant&&Z(Ye)})}var ae=r(ve,2),Be=s(ae),re=r(yt,2),F=s(re);$(Z=>{qi(Ve,"href",t(xe).link),g(X,t(xe).source),g(Be,Z),g(F,t(xe).title)},[()=>t(xe).ts?c(t(xe).ts):""]),h(he,Ve)}),h(K,Y)};q(I,K=>{t(l)?K(Ie):t(o)?K(fe,1):t(a).length?K(ke,-1):K(me,2)})}S("click",C,A),h(e,m),Vn()}sa(["click"]);const lu=[{label:"Einstieg",tutorials:[["Dein erster Workflow — in 3 Schritten",`
  1. Modell holen: Tab Cookbook → Anwendungsfall wählen (z.B. „Coden & Programmieren") → Komplettes Setup installieren. Der Download läuft im Tab Aktivität — einfach warten bis der Job grün wird.
  2. @@ -638,4 +649,6 @@ src/
    Strg+Shift+R (Hard Reload). Wenn das nicht hilft: Tab Server → Mission Control → Neu starten.
    - `]]}],iu=[["LLM / Modell","Die KI selbst — versteht und schreibt Text (wie ChatGPT, nur lokal auf deinem PC). Ein Modell ist eine konkrete Datei, oft auf etwas spezialisiert (Code, Bilder, Chat)."],["GGUF","Das lokal lauffähige Dateiformat. llama-swap lädt nur GGUF — Repos ohne GGUF kann die Engine nicht nutzen."],["Quantisierung (Q4_K_M)","Verkleinert ein Modell (16-Bit → 4-Bit), damit es in den Speicher passt — bei kaum Qualitätsverlust. Q4_K_M ist der bewährte Sweetspot. Für Coding/Reasoning: Q8_0 (nahezu verlustfrei). Wenn Q4_K_M 1 GB zu groß ist: IQ4_XS als Alternative (ähnliche Qualität, etwas kleiner)."],["Kontextfenster","Das Kurzzeitgedächtnis: wie viel Text sich das Modell gleichzeitig merken kann. Größer = mehr Überblick, mehr Speicher, etwas langsamer."],["Token","Die kleinste Einheit die ein Modell verarbeitet — meist 3–4 Zeichen oder ein kurzes Wort. 1 000 Tokens ≈ 750 Wörter. Kontextfenster, Geschwindigkeit und Kosten werden in Tokens gemessen."],["Auto-Swap","llama-swap lädt/entlädt Modelle automatisch — immer nur eins gleichzeitig. Du managst nichts."],["TTL (Time to Live)","Wie lange ein Modell nach der letzten Anfrage im RAM bleibt bevor es entladen wird. Standard: 5 Minuten. ∞ = bleibt dauerhaft geladen (sinnvoll für den Scout)."],["Agent","Ein Programm (OpenCode, Cline, Continue), das das Modell in einer Handlungsschleife laufen lässt — Dateien lesen/ändern, Befehle ausführen, planen, bis die Aufgabe erledigt ist."],["MCP","Model Context Protocol — der Stecker, über den ein Agent zusätzliche Werkzeuge bekommt (Web, Datenbank, GitHub …). MCP = neue Fähigkeiten."],["Skills / Rules","Kurze Textdatei (AGENTS.md, .clinerules …) mit Anweisungen wie der Agent in deinem Projekt arbeiten soll — einmal geschrieben, immer befolgt. Seit 2026 plattformübergreifender Standard: AGENTS.md wird von über 10 Tools nativ gelesen."],["Memory Bank","Clines Konzept für dauerhaften Projekt-Kontext: projectbrief.md (Ziel & Scope), activeContext.md (aktueller Fokus), progress.md (Stand). Wird zu Beginn jeder Aufgabe automatisch gelesen — ähnlich wie AGENTS.md, aber aufgeteilt nach Zweck."],["System-Prompt","Eine unsichtbare Anweisung die vor deiner Nachricht steht und das Verhalten des Modells grundlegend prägt (Sprache, Ton, Rolle). Skills nutzen oft den System-Prompt."],["Vision","Modelle mit Vision-Fähigkeit können Bilder verstehen — Screenshots, Diagramme, Fehlerfotos. Erkennbar am mmproj-Projektor der mitgeladen wird."]];var ru=w('
    '),su=w('
    '),lu=w('

    '),ou=w('

    Guide

    Schritt für Schritt erklärt — von der ersten Einrichtung bis zu echten Agenten-Workflows.

    Begriffe kurz erklärt

    ',1);function du(e){var n=ou(),a=s(We(n),2);st(a,17,()=>au,rt,(r,o,d)=>{var c=su(),u=l(c),v=l(u),g=s(u,2);st(g,17,()=>t(o).tutorials,rt,(E,f,y)=>{var T=I(()=>Ca(t(f),2));let D=()=>t(T)[0],S=()=>t(T)[1];var $=ru();$.open=d===0&&y===0;var Ce=l($),oe=l(Ce),ae=s(Ce,2);Ae(ae,S,!0),P(()=>b(oe,D())),m(E,$)}),P(()=>b(v,t(o).label)),m(r,c)});var i=s(a,4);st(i,21,()=>iu,rt,(r,o)=>{var d=I(()=>Ca(t(o),2));let c=()=>t(d)[0],u=()=>t(d)[1];var v=lu(),g=l(v),E=l(g),f=s(g,2),y=l(f);P(()=>{b(E,c()),b(y,u())}),m(r,v)}),m(e,n)}let es={};function cu(){const e=document.getElementById("top-active-text");e&&(e.classList.add("swap-flash"),setTimeout(()=>e.classList.remove("swap-flash"),900))}function ts(e){var r;const n=document.getElementById("swdot"),a=document.getElementById("swlabel"),i=document.getElementById("top-active-text");if(!e)n&&(n.className="dot off"),a&&(a.textContent="Backend nicht erreichbar"),i&&(i.textContent="Backend offline"),ns("Backend nicht erreichbar – läuft uvicorn?",!1);else{const o=(e.swap_url||"").replace(/^https?:\/\//,"");n&&(n.className="dot "+(e.swap_ok?"on":"off")),a&&(a.textContent=(e.swap_ok?"LLM-Engine: Online – ":"LLM-Engine: Offline – ")+o);const d=["running","ready","loading","starting"],c=(e.models||[]).find(v=>d.includes(v.state));if(i)if(c){const v=(r=c.meta)!=null&&r.ctx?` · ${Math.round(c.meta.ctx/1024)}k ctx`:"",g=c.state==="loading"||c.state==="starting"?' lädt…':"";i.innerHTML=`${c.name}${v}${g}`}else i.innerHTML='Kein Modell im VRAM';e.swap_ok?fu():ns(`LLM-Engine nicht erreichbar unter ${o} – läuft der llama-swap Dienst?`,!0);const u={};for(const v of e.models||[])u[v.name]=v.state;for(const[v,g]of Object.entries(u)){const E=es[v];if(E&&E!==g&&(g==="running"||g==="loading")){cu();break}}es=u}uu(e),_i.set(e)}function uu(e){const n=document.getElementById("sec-chip"),a=document.getElementById("sec-chip-tx");!n||!a||(n.classList.toggle("ok",!!(e!=null&&e.secured)),a.textContent=e!=null&&e.secured?"Geschützt · Heimnetz":"Nur im Heimnetz (offen)")}function vu(e){ca.set(e||[])}function pu(e){Dr.set(e)}function ns(e,n){const a=document.getElementById("alert");a.className="alert"+(n?" warn":""),a.innerHTML=`${e}`,a.style.display="flex"}function fu(){const e=document.getElementById("alert");e&&(e.style.display="none")}const hu=e=>{var n;return(n=document.querySelector(`.nav-item[data-view="${e}"]`))==null?void 0:n.click()};function er(e,n,a,i){const r=document.createElement("span");return r.className="upd-badge"+(n?" "+n:""),r.textContent=e,i&&(r.title=i),r.onclick=()=>hu(a),r}async function nl(){try{const e=await we("/api/updates"),n=document.getElementById("update-badges");if(!n)return;const a=e.apt_cache_age_h,i=a!=null&&a>24,r=a!=null?` · apt-Cache: vor ${a}h`:"";n.innerHTML="",n.appendChild(er(e.os>0?`OS: ${e.os} Updates`:i?"OS: ?":"OS: aktuell",e.os>0||i?"warn":"ok","server",e.os>0?`${e.os} Pakete${r}`:i?`apt-Cache veraltet (${a}h)`:`Keine Updates${r}`)),n.appendChild(er(e.engine>0?"Engine: Update":"Engine: aktuell",e.engine>0?"warn":"ok","server")),n.appendChild(er(e.models>0?`Modelle: ${e.models}`:"Modelle: aktuell",e.models>0?"warn":"ok","news"))}catch{}}async function Gi(){try{ts(await we("/api/status"))}catch{ts(null)}}async function al(){try{vu(await we("/api/jobs"))}catch{}}function il(){const e=window.location.protocol==="https:"?"wss:":"ws:",n=new WebSocket(`${e}//${window.location.host}/api/system/stream`);n.onmessage=a=>{try{pu(JSON.parse(a.data))}catch{}},n.onclose=()=>{setTimeout(il,3e3)},n.onerror=()=>n.close()}var os;((os=document.getElementById("logo"))==null?void 0:os.innerHTML)!==void 0&&(document.getElementById("logo").innerHTML=Ki.logo);document.querySelectorAll("[data-ic]").forEach(e=>{e.innerHTML=Ki[e.dataset.ic||""]||""});const gu=[["overview",ud],["models",Ed],["activity",Rd],["server",jd],["cookbook",Tc],["connect",Uc],["news",nu],["guides",du]];for(const[e,n]of gu){const a=document.querySelector(`.view[data-view="${e}"]`);a&&So(n,{target:a})}Uo("overview");const tr=document.getElementById("token");tr&&(tr.value=tl(),tr.addEventListener("change",e=>{No(e.target.value),Gi()}));const nr=document.getElementById("hf-token");nr&&(nr.value=li(),nr.addEventListener("change",e=>Go(e.target.value)));const as=document.getElementById("nav-settings"),ar=document.getElementById("settings-modal"),is=document.getElementById("sm-close");as&&ar&&is&&(as.addEventListener("click",()=>ar.style.display="flex"),is.addEventListener("click",()=>ar.style.display="none"));function mu(){const e=document.getElementById("clock");e&&(e.textContent=new Date().toTimeString().slice(0,5))}document.addEventListener("mc:refresh",Gi);Gi();al();il();setInterval(mu,1e3);setInterval(Gi,3e3);setInterval(al,1500);nl();setInterval(nl,6e4); + `]]}],ou=[["LLM / Modell","Die KI selbst — versteht und schreibt Text (wie ChatGPT, nur lokal auf deinem PC). Ein Modell ist eine konkrete Datei, oft auf etwas spezialisiert (Code, Bilder, Chat)."],["GGUF","Das lokal lauffähige Dateiformat. llama-swap lädt nur GGUF — Repos ohne GGUF kann die Engine nicht nutzen."],["Quantisierung (Q4_K_M)","Verkleinert ein Modell (16-Bit → 4-Bit), damit es in den Speicher passt — bei kaum Qualitätsverlust. Q4_K_M ist der bewährte Sweetspot. Für Coding/Reasoning: Q8_0 (nahezu verlustfrei). Wenn Q4_K_M 1 GB zu groß ist: IQ4_XS als Alternative (ähnliche Qualität, etwas kleiner)."],["Kontextfenster","Das Kurzzeitgedächtnis: wie viel Text sich das Modell gleichzeitig merken kann. Größer = mehr Überblick, mehr Speicher, etwas langsamer."],["Token","Die kleinste Einheit die ein Modell verarbeitet — meist 3–4 Zeichen oder ein kurzes Wort. 1 000 Tokens ≈ 750 Wörter. Kontextfenster, Geschwindigkeit und Kosten werden in Tokens gemessen."],["Auto-Swap","llama-swap lädt/entlädt Modelle automatisch — immer nur eins gleichzeitig. Du managst nichts."],["TTL (Time to Live)","Wie lange ein Modell nach der letzten Anfrage im RAM bleibt bevor es entladen wird. Standard: 5 Minuten. ∞ = bleibt dauerhaft geladen (sinnvoll für den Scout)."],["Agent","Ein Programm (OpenCode, Cline, Continue), das das Modell in einer Handlungsschleife laufen lässt — Dateien lesen/ändern, Befehle ausführen, planen, bis die Aufgabe erledigt ist."],["MCP","Model Context Protocol — der Stecker, über den ein Agent zusätzliche Werkzeuge bekommt (Web, Datenbank, GitHub …). MCP = neue Fähigkeiten."],["Skills / Rules","Kurze Textdatei (AGENTS.md, .clinerules …) mit Anweisungen wie der Agent in deinem Projekt arbeiten soll — einmal geschrieben, immer befolgt. Seit 2026 plattformübergreifender Standard: AGENTS.md wird von über 10 Tools nativ gelesen."],["Memory Bank","Clines Konzept für dauerhaften Projekt-Kontext: projectbrief.md (Ziel & Scope), activeContext.md (aktueller Fokus), progress.md (Stand). Wird zu Beginn jeder Aufgabe automatisch gelesen — ähnlich wie AGENTS.md, aber aufgeteilt nach Zweck."],["System-Prompt","Eine unsichtbare Anweisung die vor deiner Nachricht steht und das Verhalten des Modells grundlegend prägt (Sprache, Ton, Rolle). Skills nutzen oft den System-Prompt."],["Vision","Modelle mit Vision-Fähigkeit können Bilder verstehen — Screenshots, Diagramme, Fehlerfotos. Erkennbar am mmproj-Projektor der mitgeladen wird."]];var du=_('
    '),cu=_('
    '),uu=_('

    '),vu=_('

    Guide

    Schritt für Schritt erklärt — von der ersten Einrichtung bis zu echten Agenten-Workflows.

    Begriffe kurz erklärt

    ',1);function pu(e){var n=vu(),a=r(Ze(n),2);nt(a,17,()=>lu,rt,(l,o,d)=>{var c=cu(),u=s(c),v=s(u),b=r(u,2);nt(b,17,()=>t(o).tutorials,rt,(A,m,x)=>{var C=O(()=>ea(t(m),2));let z=()=>t(C)[0],M=()=>t(C)[1];var I=du();I.open=d===0&&x===0;var Ie=s(I),fe=s(Ie),me=r(Ie,2);qe(me,M,!0),$(()=>g(fe,z())),h(A,I)}),$(()=>g(v,t(o).label)),h(l,c)});var i=r(a,4);nt(i,21,()=>ou,rt,(l,o)=>{var d=O(()=>ea(t(o),2));let c=()=>t(d)[0],u=()=>t(d)[1];var v=uu(),b=s(v),A=s(b),m=r(b,2),x=s(m);$(()=>{g(A,c()),g(x,u())}),h(l,v)}),h(e,n)}var fu=_('

    Neuer Eintrag

    Strg+Enter zum Speichern
    '),hu=_(' '),gu=_('
    Lade…
    '),mu=_(''),bu=_('
    '),_u=_('
    ',1),ku=_('
    '),wu=_("
    "),yu=_('
    '),xu=_(`

    Gedächtnis

    Fakten, Entscheidungen und Kontext — geteilt von allen KI-Tools via MCP.
    Filter:

    Wie KI-Tools dieses Gedächtnis nutzen

    Cline, OpenCode und Claude Code greifen über den Memory MCP-Server auf diese Einträge zu. + Beim Start einer Session lädt der Agent automatisch alle Einträge — er kennt dann deinen Stack, + deine Präferenzen und frühere Entscheidungen. Den Setup-Guide findest du unter Verbinden → Gedächtnis-MCP.
    Kategorien: Stabil = Projektfakten die sich selten ändern · Versioniert = Tech-Versionen (bei Updates überschreiben) · Temporär = aktuelle Aufgaben, nach 7 Tagen automatisch gelöscht
    `,1);function Su(e,n){Gn(n,!0);let a=B(jt([])),i=B(!0),l=B("all"),o=B(!1),d=B(""),c=B("stable"),u=B(null),v=B(""),b=B("stable");const A=O(()=>t(l)==="all"?t(a):t(a).filter(F=>F.category===t(l))),m={stable:{label:"Stabil",color:"var(--accent)"},versioned:{label:"Versioniert",color:"#f59e0b"},ephemeral:{label:"Temporär",color:"var(--mut)"}};function x(F){const Z=Math.floor((Date.now()-new Date(F).getTime())/1e3);return Z<60?"gerade eben":Z<3600?`vor ${Math.floor(Z/60)} Min`:Z<86400?`vor ${Math.floor(Z/3600)} Std`:`vor ${Math.floor(Z/86400)} Tagen`}function C(F){return t(a).filter(Z=>Z.category===F).length}async function z(){try{f(a,await Se("/api/memory"),!0)}catch(F){ee("Laden fehlgeschlagen: "+F.message,!0)}finally{f(i,!1)}}async function M(){if(t(d).trim())try{const F=await Se("/api/memory",{method:"POST",body:JSON.stringify({content:t(d).trim(),category:t(c),source:"manual"})});f(a,[F,...t(a)],!0),f(d,""),f(c,"stable"),f(o,!1),ee("Gespeichert")}catch(F){ee("Fehler: "+F.message,!0)}}async function I(F){try{const Z=await Se(`/api/memory/${F.id}`,{method:"PUT",body:JSON.stringify({content:t(v),category:t(b)})});f(a,t(a).map(oe=>oe.id===F.id?Z:oe),!0),f(u,null),ee("Aktualisiert")}catch(Z){ee("Fehler: "+Z.message,!0)}}async function Ie(F){if(await mn({title:"Eintrag löschen?",body:`„${F.content.length>80?F.content.slice(0,80)+"…":F.content}" wird dauerhaft entfernt.`,danger:!0}))try{await Se(`/api/memory/${F.id}`,{method:"DELETE"}),f(a,t(a).filter(oe=>oe.id!==F.id),!0),ee("Gelöscht")}catch(oe){ee("Fehler: "+oe.message,!0)}}function fe(F){f(u,F.id,!0),f(v,F.content,!0),f(b,F.category,!0)}Ki(()=>{z()});var me=xu(),ke=Ze(me),K=r(s(ke),2),Y=s(K),he=r(ke,2);{var xe=F=>{var Z=fu(),oe=r(s(Z),4),se=r(oe,4),Oe=s(se);Oe.value=Oe.__value="stable";var He=r(Oe);He.value=He.__value="versioned";var mt=r(He);mt.value=mt.__value="ephemeral";var ut=r(se,2),vt=s(ut),Je=r(vt,2);$(ze=>vt.disabled=ze,[()=>!t(d).trim()]),S("keydown",oe,ze=>{ze.key==="Enter"&&(ze.ctrlKey||ze.metaKey)&&M()}),gn(oe,()=>t(d),ze=>f(d,ze)),ya(se,()=>t(c),ze=>f(c,ze)),S("click",vt,M),S("click",Je,()=>{f(o,!1),f(d,"")}),h(F,Z)};q(he,F=>{t(o)&&F(xe)})}var Te=r(he,2),Ve=s(Te),yt=r(s(Ve),2);nt(yt,17,()=>[["all","Alle","",t(a).length],["stable","Stabil","var(--accent)",C("stable")],["versioned","Versioniert","#f59e0b",C("versioned")],["ephemeral","Temporär","var(--mut)",C("ephemeral")]],rt,(F,Z)=>{var oe=O(()=>ea(t(Z),4));let se=()=>t(oe)[0],Oe=()=>t(oe)[1],He=()=>t(oe)[2],mt=()=>t(oe)[3];var ut=hu(),vt=s(ut),Je=r(vt),ze=s(Je);$(()=>{Xt(ut,`cursor:pointer;${t(l)===se()?`background:rgba(45,212,191,.12);border-color:${He()||"var(--accent)"};color:${He()||"var(--accent)"}`:""}`),g(vt,`${Oe()??""} `),g(ze,mt())}),S("click",ut,()=>f(l,se(),!0)),S("keydown",ut,Et=>Et.key==="Enter"&&f(l,se(),!0)),h(F,ut)});var T=r(Te,2);{var X=F=>{var Z=gu();h(F,Z)},ve=F=>{var Z=bu(),oe=s(Z),se=s(oe),Oe=s(se),He=r(se,2),mt=s(He),ut=r(He,2);{var vt=Je=>{var ze=mu();S("click",ze,()=>f(o,!0)),h(Je,ze)};q(ut,Je=>{t(a).length===0&&Je(vt)})}$(()=>{g(Oe,t(a).length===0?"Noch keine Einträge":"Keine Treffer"),g(mt,t(a).length===0?'Klicke „+ Eintrag" um manuell etwas zu speichern, oder verbinde ein KI-Tool via MCP.':"Andere Kategorie wählen oder Eintrag anlegen.")}),h(F,Z)},Ye=F=>{var Z=yu();nt(Z,23,()=>t(A),oe=>oe.id,(oe,se,Oe)=>{var He=wu(),mt=s(He);{var ut=Je=>{var ze=_u(),Et=Ze(ze),Tt=r(Et,2),$t=s(Tt);$t.value=$t.__value="stable";var D=r($t);D.value=D.__value="versioned";var N=r(D);N.value=N.__value="ephemeral";var Me=r(Tt,2),Qe=s(Me),k=r(Qe,2);gn(Et,()=>t(v),L=>f(v,L)),ya(Tt,()=>t(b),L=>f(b,L)),S("click",Qe,()=>I(t(se))),S("click",k,()=>f(u,null)),h(Je,ze)},vt=Je=>{var ze=ku(),Et=s(ze),Tt=s(Et),$t=s(Tt),D=r(Tt,2),N=s(D),Me=s(N),Qe=r(N,2),k=s(Qe),L=r(Qe,2),te=s(L),Pe=r(Et,2),de=s(Pe),Fe=r(de,2);$(Ee=>{var $e,Xe,Ke;g($t,t(se).content),Xt(N,`border-color:${((($e=m[t(se).category])==null?void 0:$e.color)||"var(--mut)")??""};color:${(((Xe=m[t(se).category])==null?void 0:Xe.color)||"var(--mut)")??""}`),g(Me,((Ke=m[t(se).category])==null?void 0:Ke.label)||t(se).category),g(k,t(se).source),g(te,Ee)},[()=>x(t(se).updated_at)]),S("click",de,()=>fe(t(se))),S("click",Fe,()=>Ie(t(se))),h(Je,ze)};q(mt,Je=>{t(u)===t(se).id?Je(ut):Je(vt,-1)})}$(()=>Xt(He,`padding:14px 16px;${t(Oe){t(i)?F(X):t(A).length===0?F(ve,1):F(Ye,-1)})}var ae=r(T,2),Be=r(s(ae),2),re=r(s(Be),3);$(()=>g(Y,t(o)?"Abbrechen":"+ Eintrag")),S("click",K,()=>{f(o,!t(o)),f(d,"")}),S("click",re,F=>{var Z;F.preventDefault(),(Z=document.querySelector(".nav-item[data-view='connect']"))==null||Z.click()}),h(e,me),Vn()}sa(["click","keydown"]);let es={};function Mu(){const e=document.getElementById("top-active-text");e&&(e.classList.add("swap-flash"),setTimeout(()=>e.classList.remove("swap-flash"),900))}function ts(e){var l;const n=document.getElementById("swdot"),a=document.getElementById("swlabel"),i=document.getElementById("top-active-text");if(!e)n&&(n.className="dot off"),a&&(a.textContent="Backend nicht erreichbar"),i&&(i.textContent="Backend offline"),ns("Backend nicht erreichbar – läuft uvicorn?",!1);else{const o=(e.swap_url||"").replace(/^https?:\/\//,"");n&&(n.className="dot "+(e.swap_ok?"on":"off")),a&&(a.textContent=(e.swap_ok?"LLM-Engine: Online – ":"LLM-Engine: Offline – ")+o);const d=["running","ready","loading","starting"],c=(e.models||[]).find(v=>d.includes(v.state));if(i)if(c){const v=(l=c.meta)!=null&&l.ctx?` · ${Math.round(c.meta.ctx/1024)}k ctx`:"",b=c.state==="loading"||c.state==="starting"?' lädt…':"";i.innerHTML=`${c.name}${v}${b}`}else i.innerHTML='Kein Modell im VRAM';e.swap_ok?Tu():ns(`LLM-Engine nicht erreichbar unter ${o} – läuft der llama-swap Dienst?`,!0);const u={};for(const v of e.models||[])u[v.name]=v.state;for(const[v,b]of Object.entries(u)){const A=es[v];if(A&&A!==b&&(b==="running"||b==="loading")){Mu();break}}es=u}Eu(e),_i.set(e)}function Eu(e){const n=document.getElementById("sec-chip"),a=document.getElementById("sec-chip-tx");!n||!a||(n.classList.toggle("ok",!!(e!=null&&e.secured)),a.textContent=e!=null&&e.secured?"Geschützt · Heimnetz":"Nur im Heimnetz (offen)")}function Au(e){va.set(e||[])}function Cu(e){Pr.set(e)}function ns(e,n){const a=document.getElementById("alert");a.className="alert"+(n?" warn":""),a.innerHTML=`${e}`,a.style.display="flex"}function Tu(){const e=document.getElementById("alert");e&&(e.style.display="none")}const zu=e=>{var n;return(n=document.querySelector(`.nav-item[data-view="${e}"]`))==null?void 0:n.click()};function tr(e,n,a,i){const l=document.createElement("span");return l.className="upd-badge"+(n?" "+n:""),l.textContent=e,i&&(l.title=i),l.onclick=()=>zu(a),l}async function nl(){try{const e=await Se("/api/updates"),n=document.getElementById("update-badges");if(!n)return;const a=e.apt_cache_age_h,i=a!=null&&a>24,l=a!=null?` · apt-Cache: vor ${a}h`:"";n.innerHTML="",n.appendChild(tr(e.os>0?`OS: ${e.os} Updates`:i?"OS: ?":"OS: aktuell",e.os>0||i?"warn":"ok","server",e.os>0?`${e.os} Pakete${l}`:i?`apt-Cache veraltet (${a}h)`:`Keine Updates${l}`)),n.appendChild(tr(e.engine>0?"Engine: Update":"Engine: aktuell",e.engine>0?"warn":"ok","server")),n.appendChild(tr(e.models>0?`Modelle: ${e.models}`:"Modelle: aktuell",e.models>0?"warn":"ok","news"))}catch{}}async function Vi(){try{ts(await Se("/api/status"))}catch{ts(null)}}async function al(){try{Au(await Se("/api/jobs"))}catch{}}function il(){const e=window.location.protocol==="https:"?"wss:":"ws:",n=new WebSocket(`${e}//${window.location.host}/api/system/stream`);n.onmessage=a=>{try{Cu(JSON.parse(a.data))}catch{}},n.onclose=()=>{setTimeout(il,3e3)},n.onerror=()=>n.close()}var os;((os=document.getElementById("logo"))==null?void 0:os.innerHTML)!==void 0&&(document.getElementById("logo").innerHTML=Gi.logo);document.querySelectorAll("[data-ic]").forEach(e=>{e.innerHTML=Gi[e.dataset.ic||""]||""});const Pu=[["overview",ud],["models",Ed],["activity",Od],["server",jd],["cookbook",Tc],["connect",Qc],["news",su],["guides",pu],["memory",Su]];for(const[e,n]of Pu){const a=document.querySelector(`.view[data-view="${e}"]`);a&&So(n,{target:a})}Uo("overview");const nr=document.getElementById("token");nr&&(nr.value=tl(),nr.addEventListener("change",e=>{No(e.target.value),Vi()}));const ar=document.getElementById("hf-token");ar&&(ar.value=li(),ar.addEventListener("change",e=>Go(e.target.value)));const as=document.getElementById("nav-settings"),ir=document.getElementById("settings-modal"),is=document.getElementById("sm-close");as&&ir&&is&&(as.addEventListener("click",()=>ir.style.display="flex"),is.addEventListener("click",()=>ir.style.display="none"));function Du(){const e=document.getElementById("clock");e&&(e.textContent=new Date().toTimeString().slice(0,5))}document.addEventListener("mc:refresh",Vi);Vi();al();il();setInterval(Du,1e3);setInterval(Vi,3e3);setInterval(al,1500);nl();setInterval(nl,6e4); diff --git a/static/index.html b/static/index.html index 85dd77b..2b9310e 100644 --- a/static/index.html +++ b/static/index.html @@ -22,6 +22,7 @@ Verbinden News Guides + Gedächtnis
    Einstellungen @@ -48,6 +49,7 @@ +