Files
mission-control-v2/docs/CLAUDE_CODE_BRIEF_lucy-brain-role.md

7.5 KiB
Raw Permalink Blame History

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.yamlmodel.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 (~510 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.pyROLE_IDS
    • services/sources.pyROLE_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.yamlmodel.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,52× 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 <assistant.gguf> --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:

# 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.