# Claude-Code-Auftrag: „Brain"-Rolle für Lucy (Front- + Backend-Umbau) > Ziel: Lucys Hirn (aktuell `gemma-4-26B-A4B-it`) als **erstklassige, dauer-warme Rolle** im MC2-Stack > verankern — statt es als `scout` zu führen, das nach `ttl` entladen wird. Features (Sehen/Hören/ > Sprechen/Embedding) dürfen NICHT verloren gehen, KO-Residenz + Budget müssen sauber bleiben. ## Kontext / Architektur (Ist-Zustand, verifiziert 30.06.) - **Engine:** llama-swap (config: `/etc/llama-swap/config.yaml` auf der Box, läuft mit `-watch-config`). Rollen werden als llama-swap **`aliases`** gesetzt; Warm-Bleiben über `groups:` (eine Gruppe `brains: { swap: false }`) + `ttl`. Installierte Modelle: `Qwen3.6-35B-A3B` (fast, ttl 0), `Qwen3.5-122B-A10B` (heavy, ttl 600), `Qwen3-Coder-Next` (coder, ttl 600), `Qwen3-Coder-30B-A3B-Instruct` (coder_lite, ttl 300), `Qwen3-VL-8B-Instruct` (vision, ttl 300), `Qwen3-Embedding-0.6B` (ttl 0 = immer warm), `gemma-4-26B-A4B-it` (ttl 180). - **Gateway:** MC2 builtin auf `:9001/v1` mit virtuellen Lanes `chat` (→ fast/heavy) und `coding` (→ coder_lite/coder). Code: `backend/services/router_logic.py`, `routing_policy.py`. **Lucy nutzt die Lanes NICHT** — sie ist der Hermes-Agent. - **Lucy-Hirn:** Hermes-Agent (`:8642`), Brain = `~/.hermes/config.yaml` → `model.default` (jetzt `gemma-4-26B-A4B-it`), Delegation = `heavy`. Persona/Prompt kommt aus dem **Client** (`client/lucy-desktop/src/renderer/src/config.ts`), nicht aus der Box-Config. - **Hardware:** Strix Halo (Ryzen AI Max+ 395), 122 GB, GTT ~124 GB, bandbreitenlimitiert → MoE mit wenig aktiven Params ist schnell, dichte Modelle langsam. ## Root-Cause des Bugs 1. Kanonische Rollen `ROLE_IDS = {fast, heavy, coder, vision, scout}` — **keine `brain`/Agent-Rolle**. (Kommentar im Code: „kein agent/reasoning mehr".) 2. Es gibt keine Verknüpfung „Hirn-Modell ⇒ muss warm bleiben". gemma trägt den Alias `scout`, ist NICHT in der `brains`-Gruppe, `ttl 180` → entlädt im Leerlauf → Lucy lädt kalt nach (~5–10 s). 3. `roles.py` referenziert noch eine `hermes`-Rolle, die in `ROLE_IDS` nicht existiert → Inkonsistenz. ## Aufgabe ### Backend (`backend/`) 1. **Neue erstklassige Rolle `brain` einführen** (oder `hermes` reaktivieren) und in ALLEN Quellen synchronisieren (heute dupliziert!): - `services/llamaswap.py` → `ROLE_IDS` - `services/sources.py` → `ROLE_IDS` + Titel/Icon (analog `scout: {title, icon}`) - `services/maintenance.py` (Modell-Upgrade-Rollenliste) - `services/roles.py` → `_capability_suit`/`_pref`/`_reason` für `brain` (Tools Pflicht, mittlere Größe + MoE bevorzugt, niedrige Latenz). `hermes`-Altlast bereinigen. 2. **Rolle `brain` ⇒ automatisch warm + ko-resident.** Beim Zuweisen der `brain`-Rolle (`POST /api/models/{model_id}/role`, `routers/models.py`): - Modell via `set_group("brains", members=[...], swap=False, persist=True)` in die Warm-Gruppe aufnehmen (bestehender Helper in `llamaswap.py`). - `ttl: 0` setzen (oder hoch), vorheriges Brain-Modell aus `brains` entfernen + ttl entspannen. - Embedding (`Qwen3-Embedding-0.6B`, ttl 0) MUSS warm bleiben — nicht verdrängen. 3. **Single Source of Truth für „Lucys Hirn":** beim Setzen der `brain`-Rolle auch Hermes' `~/.hermes/config.yaml` → `model.default` auf das Modell setzen + `systemctl --user restart hermes-gateway` (mit Backup der config). So bleibt MC2-UI-Auswahl ↔ Hermes-Brain konsistent. 4. **Budget/KO-Residenz-Safety:** Brain(warm) + Embedding(warm) + on-demand Vision + Coder müssen in GTT (~124 GB) passen. `services/budget.py`/`fit.py` nutzen, bei OOM warnen (nicht hart laden). 5. **Lanes/IDEs unangetastet lassen:** chat/coding-Routing (`router_logic.py`) bleibt wie es ist; `fast` bleibt für die chat-Lane warm. ### Frontend (`frontend/src/`) 1. **Rollen-Taxonomie** um `brain` erweitern (Badges/Titel/Icon) — Duplikat zur Backend-Liste finden & angleichen (`components/models/*`, `views/ModelsView.tsx`, evtl. `ModelBadges.ROLES`). gemma darf NICHT mehr als `scout` erscheinen. 2. **Rollen-Zuweisungs-Modal:** `brain` auswählbar; Warm-/KO-Residenz-Status anzeigen (ist das Brain in `brains`? warm? ttl?). Empfehlung via bestehendem `/api/roles/{role}/recommend`. 3. **Warm-Set / GTT-Budget sichtbar machen** (Dashboard/Models): was ist gerade ko-resident, passt es ins Budget? (nutzt `/api/models` `running` + budget-Infos). 4. Optional: „Lucy-Hirn"-Selector, der die `brain`-Rolle setzt (treibt Backend #2 + #3). ### Zusatz: MTP-Speculative-Decoding für Gemma (Durchsatz für agentische Arbeit) Lucy ist ein **voller Agent** (Tools/MCP/PC-Control/Vision/Delegation) — Durchsatz zählt, nicht nur TTFB. Gemma 4 bringt **MTP** (Multi-Token-Prediction) mit → 1,5–2× schneller bei null Qualitätsverlust. - **Engine kann es bereits:** `llama-server` v9843 listet `--spec-type … draft-mtp …`. ✓ - **Vocab-kompatibler „Draft" = Gemmas eigener MTP-Kopf** `gemma-4-26B-A4B-it-assistant` (~0,4B, identischer Tokenizer per Konstruktion). Quelle z.B. `unsloth/gemma-4-26B-A4B-it-GGUF` (enthält den MTP-Drafter, PR ggml-org/llama.cpp#23398). Muss nach `/srv/models/...` geladen werden (noch nicht da). - **Flag-Änderung beachten:** `--draft-max/--draft-min` sind ENTFERNT → `--spec-draft-n-max` / `--spec-draft-n-min`. Drafter laden via `-md --spec-type draft-mtp`. Exakte Flags des Builds mit `llama-server --help` gegenprüfen. - **MC2-Bug:** die Spec-Draft-Auswahl (UI + Backend) kennt **nur klassische Drafts** (vergleicht stur `n_vocab`/`pre`) und bot fälschlich nur den Qwen-Draft an („Vocab ?"). **Erweitern:** MTP-Drafter (`gemma4_assistant`-Arch) als gültigen, vocab-kompatiblen Draft erkennen, den passenden `-assistant`- GGUF anbieten, und beim Aktivieren `-md … --spec-type draft-mtp --spec-draft-n-max/-n-min` in die llama-swap-cmd schreiben. Co-Residenz: Drafter ~0,4B → vernachlässigbar. ## Akzeptanzkriterien - [ ] `gemma-4-26B-A4B-it` wird in der UI als **`brain`** geführt (nicht `scout`). - [ ] Es bleibt **warm**: in `brains: swap:false`, `ttl 0`; überlebt > alter ttl Leerlauf (Verifikation: `curl :8080/running` nach >5 Min Idle zeigt das Modell weiterhin `ready`). - [ ] Lucy antwortet ohne Kalt-Nachladen nach Leerlauf. - [ ] Vision (`Qwen3-VL-8B`), Embedding (`Qwen3-Embedding-0.6B`), Coder bleiben funktionsfähig & ko-resident; **kein OOM**; IDE-Lanes (chat/coding) unverändert. - [ ] Brain-Wechsel in der UI aktualisiert llama-swap (Warm-Gruppe) UND Hermes `model.default` (+ Restart), reversibel (Backup). ## Sofort-Hotfix (unabhängig vom Umbau — macht Lucy JETZT warm) Auf der Box, bis der saubere Umbau steht: ```bash # gemma als immer-warm + in die brains-Gruppe (Backup zuerst!) cp /etc/llama-swap/config.yaml /etc/llama-swap/config.yaml.bak # gemma ttl 180 -> 0 und groups.brains.members um gemma-4-26B-A4B-it ergänzen # (manuell editieren oder via MC2 set_group), dann: # llama-swap reloadt per -watch-config automatisch. ``` ## Wichtige Dateien (Einstieg) - Backend: `services/llamaswap.py` (Rollen=aliases, `set_role_alias`, `set_group`, `register_model`), `services/roles.py`, `services/sources.py`, `services/routing_policy.py`, `services/router_logic.py`, `services/budget.py`, `services/fit.py`, `routers/models.py`, `routers/routing.py`. - Frontend: `views/ModelsView.tsx`, `components/models/*`, `components/SystemDrawer.tsx`. - Box (nicht im Repo): `/etc/llama-swap/config.yaml`, `~/.hermes/config.yaml`.