v6 Phase C: Cookbook diversifiziert + 'Beste Wahl' hervorgehoben
- recipes.py: best-in-class je Use-Case, herstelleruebergreifend (Qwen3-Coder, Gemma 3, Mistral Small, DeepSeek-R1, Qwen3-VL) + neue Kategorie 'Nachdenken & Logik'. - recipes-Endpoint: recommended_id = reichstes Setup das komplett passt. - cookbook.js + CSS: 'Beste Wahl fuer dein System' (Rahmen + Badge). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+34
-27
@@ -1,59 +1,66 @@
|
||||
"""
|
||||
Kuratierte Use-Case-„Setups" (Stacks) fuers Cookbook 2.0. Stand: Juni 2026.
|
||||
|
||||
Daten, kein Code (KISS/SoC). Pro Modell nur Repo + Groesse/Quant — die konkrete GGUF-Datei wird
|
||||
beim Installieren dynamisch aus dem Repo aufgeloest (robust gegen Datei-Umbenennungen). Hardware-Fit
|
||||
+ optimaler Kontext kommen zur Laufzeit aus hw_math.
|
||||
Best-in-class je Use-Case — bewusst herstelleruebergreifend (Qwen, Google Gemma, Mistral, DeepSeek),
|
||||
nicht alles Qwen. Pro Modell nur Repo + Groesse/Quant; die GGUF-Datei wird beim Installieren dynamisch
|
||||
aufgeloest (robust). Fit + optimaler Kontext kommen zur Laufzeit aus hw_math.
|
||||
"""
|
||||
|
||||
# Aktuelle, lokal gut laufende GGUF-Repos (Juni 2026). Bevorzugt unsloth (zuverlaessige Quants).
|
||||
RECIPES = [
|
||||
{
|
||||
"id": "coding", "title": "Coden & Programmieren", "icon": "code",
|
||||
"desc": "Aktueller Top-Coder (MoE, nur 3B aktiv → schnell), ein flinker Helfer und Vision für Screenshots.",
|
||||
"models": [
|
||||
{"role": "coder", "name": "Qwen3-Coder 30B-A3B", "repo": "unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF",
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Aktuelles Top-Coder-Modell — versteht große Codebasen, läuft dank MoE flott."},
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Bestes lokales Coder-Modell — versteht große Codebasen, läuft dank MoE flott."},
|
||||
{"role": "coder-fast", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Schneller Helfer für einfache Edits & Autovervollständigung."},
|
||||
{"role": "vision", "name": "Qwen2.5-VL 7B", "repo": "unsloth/Qwen2.5-VL-7B-Instruct-GGUF",
|
||||
"params_b": 7, "quant": "Q4_K_M", "why": "Liest Screenshots & Fehlerbilder für die Analyse."},
|
||||
{"role": "vision", "name": "Qwen3-VL 8B", "repo": "Qwen/Qwen3-VL-8B-Instruct-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Liest Screenshots & Fehlerbilder für die Analyse."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "vision", "title": "Bilder verstehen", "icon": "eye",
|
||||
"desc": "Ein multimodales Modell, das Bilder und Text gemeinsam versteht.",
|
||||
"models": [
|
||||
{"role": "vision", "name": "Qwen2.5-VL 7B", "repo": "unsloth/Qwen2.5-VL-7B-Instruct-GGUF",
|
||||
"params_b": 7, "quant": "Q4_K_M", "why": "Beschreibt Bilder, liest Diagramme, analysiert Screenshots."},
|
||||
{"role": "vision", "name": "Qwen3-VL 8B", "repo": "Qwen/Qwen3-VL-8B-Instruct-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Aktuelles Vision-Modell — beschreibt Bilder, liest Diagramme & Screenshots."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "chat", "title": "Allrounder & Chat", "icon": "compass",
|
||||
"desc": "Vielseitige Modelle für Alltag, Texte und Brainstorming.",
|
||||
"desc": "Vielseitig für Alltag, Texte und Brainstorming — Googles Gemma als starke Alternative zu Qwen.",
|
||||
"models": [
|
||||
{"role": "scout", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Schneller, kluger Allrounder — guter Standard."},
|
||||
{"role": "scout-pro", "name": "Qwen3 30B-A3B", "repo": "unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF",
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Mehr Tiefe (MoE), wenn die Antworten besser sein sollen."},
|
||||
{"role": "scout", "name": "Gemma 3 27B", "repo": "unsloth/gemma-3-27b-it-GGUF",
|
||||
"params_b": 27, "quant": "Q4_K_M", "why": "Googles Allrounder — exzellent bei Sprache, Wissen und langem Kontext."},
|
||||
{"role": "scout-fast", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Schnelle Alternative für kurze Fragen."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "reasoning", "title": "Nachdenken & Logik", "icon": "pulse",
|
||||
"desc": "Ein Reasoning-Modell, das Schritt für Schritt denkt — für Mathe, Logik, knifflige Probleme.",
|
||||
"models": [
|
||||
{"role": "thinker", "name": "DeepSeek-R1 Distill 7B", "repo": "unsloth/DeepSeek-R1-Distill-Qwen-7B-GGUF",
|
||||
"params_b": 7, "quant": "Q4_K_M", "why": "DeepSeeks Reasoning-Ansatz — denkt laut mit, stark bei Logik & Mathe."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "longdoc", "title": "Lange Dokumente", "icon": "file",
|
||||
"desc": "Großes Modell mit großem Kontext — für lange Texte, Verträge, Bücher.",
|
||||
"models": [
|
||||
{"role": "reader", "name": "Qwen3 30B-A3B", "repo": "unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF",
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Starke Qualität bei großem Kontextfenster (auto-optimiert)."},
|
||||
{"role": "reader", "name": "Gemma 3 27B", "repo": "unsloth/gemma-3-27b-it-GGUF",
|
||||
"params_b": 27, "quant": "Q4_K_M", "why": "Starke Qualität bei sehr großem Kontextfenster (auto-optimiert)."},
|
||||
],
|
||||
},
|
||||
{
|
||||
"id": "agents", "title": "Agenten & Tool-Use", "icon": "layers",
|
||||
"desc": "Modelle, die gut mit Werkzeugen/Funktionen umgehen — für autonome Agenten (MCP).",
|
||||
"desc": "Modelle, die gut mit Werkzeugen/Funktionen umgehen (MCP) — Mistral als Tool-Use-Spezialist.",
|
||||
"models": [
|
||||
{"role": "agent", "name": "Qwen3 30B-A3B", "repo": "unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF",
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Stark im Function-Calling und mehrstufigem Denken."},
|
||||
{"role": "agent-fast", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Schneller Helfer für einfache Tool-Schritte."},
|
||||
{"role": "agent", "name": "Mistral Small 3.2 24B", "repo": "unsloth/Mistral-Small-3.2-24B-Instruct-2506-GGUF",
|
||||
"params_b": 24, "quant": "Q4_K_M", "why": "Mistrals Stärke: zuverlässiges Function-Calling für Agenten."},
|
||||
{"role": "agent-think", "name": "Qwen3 30B-A3B", "repo": "unsloth/Qwen3-30B-A3B-Instruct-2507-GGUF",
|
||||
"params_b": 30, "quant": "Q4_K_M", "why": "Starkes mehrstufiges Denken (MoE) als Backup-Hirn."},
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -62,21 +69,21 @@ RECIPES = [
|
||||
"models": [
|
||||
{"role": "mini", "name": "Qwen3 4B", "repo": "Qwen/Qwen3-4B-GGUF",
|
||||
"params_b": 4, "quant": "Q4_K_M", "why": "Winzig & sehr schnell für einfache Aufgaben."},
|
||||
{"role": "scout", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
{"role": "scout-fast", "name": "Qwen3 8B", "repo": "unsloth/Qwen3-8B-GGUF",
|
||||
"params_b": 8, "quant": "Q4_K_M", "why": "Etwas mehr Können, immer noch flott."},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
# Upgrade-Map (Phase 3.2): wenn der Nutzer ein „altes" Modell hat, schlagen wir das neue vor.
|
||||
# Upgrade-Map: hat der Nutzer ein „altes" Modell, schlagen wir das aktuelle vor.
|
||||
UPGRADES = [
|
||||
{"match": ["qwen2.5-coder", "qwen2_5-coder"], "name": "Qwen3-Coder 30B-A3B",
|
||||
"repo": "unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF", "params_b": 30, "quant": "Q4_K_M",
|
||||
"why": "Nachfolger deines Coders: MoE mit nur 3B aktiven Parametern → schneller und stärker auf SWE-bench."},
|
||||
{"match": ["qwen2.5-7b", "qwen2_5-7b", "qwen2.5-instruct"], "name": "Qwen3 8B",
|
||||
{"match": ["qwen2.5-7b", "qwen2_5-7b", "qwen2.5-instruct", "llama-3.1-8b", "llama-3-8b"], "name": "Qwen3 8B",
|
||||
"repo": "unsloth/Qwen3-8B-GGUF", "params_b": 8, "quant": "Q4_K_M",
|
||||
"why": "Neuere Generation deines Allrounders — besser im Reasoning und bei Tool-Use."},
|
||||
{"match": ["llama-3.2-11b-vision", "llama3.2", "llama-3.2-vision"], "name": "Qwen2.5-VL 7B",
|
||||
"repo": "unsloth/Qwen2.5-VL-7B-Instruct-GGUF", "params_b": 7, "quant": "Q4_K_M",
|
||||
"why": "Modernes Vision-Modell — kleiner und meist treffsicherer beim Bildverständnis."},
|
||||
{"match": ["llama-3.2-11b-vision", "llama-3.2-vision", "qwen2.5-vl"], "name": "Qwen3-VL 8B",
|
||||
"repo": "Qwen/Qwen3-VL-8B-Instruct-GGUF", "params_b": 8, "quant": "Q4_K_M",
|
||||
"why": "Modernes Vision-Modell — kleiner und treffsicherer beim Bildverständnis."},
|
||||
]
|
||||
|
||||
+4
-1
@@ -134,7 +134,10 @@ def recipes():
|
||||
if _FIT_ORDER[fit["level"]] > _FIT_ORDER[worst]:
|
||||
worst = fit["level"]
|
||||
out.append({**r, "models": models, "fit_level": worst})
|
||||
return {"recipes": out, "sys_ram_gb": round(ram_gb, 1)}
|
||||
# „Beste Wahl": das reichste Setup, das komplett auf die Hardware passt.
|
||||
fitting = [r for r in out if r["fit_level"] != "too_tight"]
|
||||
rec = max(fitting, key=lambda r: len(r["models"]), default=None) if fitting else None
|
||||
return {"recipes": out, "sys_ram_gb": round(ram_gb, 1), "recommended_id": rec["id"] if rec else None}
|
||||
|
||||
|
||||
@router.post("/install-recipe")
|
||||
|
||||
@@ -216,5 +216,7 @@ button:disabled{opacity:.5;cursor:not-allowed}
|
||||
border-radius:var(--radius);padding:var(--sp-3) var(--sp-4);cursor:pointer;transition:border-color .15s,background .15s;
|
||||
color:var(--tx);font-family:var(--sans)}
|
||||
.card-btn:hover,.card-btn:focus{border-color:var(--accent);background:var(--bg2);outline:none}
|
||||
.card-btn.cb-best{border:2px solid var(--accent);background:rgba(45,212,191,.05)}
|
||||
.cb-best-tag{display:inline-block;font-size:11px;color:var(--accent-ink);background:var(--accent);border-radius:6px;padding:2px 9px;margin-bottom:8px;font-weight:500}
|
||||
.card-btn h3{margin:0;font-size:var(--text-lg);font-weight:500}
|
||||
.card-btn p{margin:var(--sp-2) 0 0;font-size:var(--text-sm);color:var(--mut)}
|
||||
|
||||
@@ -17,6 +17,7 @@ let currentResults = [];
|
||||
let currentAnalysis = null;
|
||||
let activeFilter = "";
|
||||
let RECIPES = [];
|
||||
let RECOMMENDED = null;
|
||||
|
||||
const fitCls = lvl => lvl === "perfect" ? "ok" : lvl === "marginal" ? "warn" : "bad";
|
||||
const fitWord = lvl => lvl === "perfect" ? "Passt locker" : lvl === "marginal" ? "Wird knapp" : "Zu groß";
|
||||
@@ -117,6 +118,7 @@ async function loadRecipes() {
|
||||
try {
|
||||
const d = await api("/api/cookbook/recipes");
|
||||
RECIPES = d.recipes || [];
|
||||
RECOMMENDED = d.recommended_id || null;
|
||||
renderRecipes();
|
||||
} catch (e) {
|
||||
$("#cb-recipes").innerHTML = `<div class="alert err" style="grid-column:1/-1">Setups nicht ladbar: ${esc(e.message)}</div>`;
|
||||
@@ -124,8 +126,10 @@ async function loadRecipes() {
|
||||
}
|
||||
|
||||
function renderRecipes() {
|
||||
$("#cb-recipes").innerHTML = RECIPES.map(r => `
|
||||
<button class="card-btn" data-recipe="${esc(r.id)}">
|
||||
$("#cb-recipes").innerHTML = RECIPES.map(r => {
|
||||
const best = r.id === RECOMMENDED;
|
||||
return `<button class="card-btn${best ? " cb-best" : ""}" data-recipe="${esc(r.id)}">
|
||||
${best ? `<div class="cb-best-tag">★ Beste Wahl für dein System</div>` : ""}
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="flex items-center gap-2"><span class="text-accent">${icon(r.icon)}</span>
|
||||
<h3 style="margin:0;font-size:15px">${esc(r.title)}</h3></span>
|
||||
@@ -133,7 +137,8 @@ function renderRecipes() {
|
||||
</div>
|
||||
<p>${esc(r.desc)}</p>
|
||||
<div class="text-xs text-mut">${r.models.length} Modell${r.models.length > 1 ? "e" : ""} im Setup</div>
|
||||
</button>`).join("");
|
||||
</button>`;
|
||||
}).join("");
|
||||
$("#cb-recipes").querySelectorAll("[data-recipe]").forEach(b =>
|
||||
b.addEventListener("click", () => openRecipe(b.getAttribute("data-recipe"))));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user