Bug-Fixes: - hermes_agent.py: asyncio.get_event_loop() → get_running_loop() (Python 3.10+) - routers/hermes.py: Thread-Lock fuer Whisper-Init, HERMES_WINDOWS_USER Import, Piper stderr logging, __import__ Anti-Pattern entfernt - routers/memory.py: SQLite WAL-Mode, Kategorie-Enum-Validierung (user/instruction/stable/versioned/ephemeral) - HermesPanel.svelte: findLast() → reverse().find() (Browser-Kompatibilitaet) - ConnectPanel.svelte: Hardcoded Username durch Platzhalter ersetzt Docs: - CLAUDE.md: komplett aktualisiert (v7+v8, Hermes, Memory, alle Env-Vars) - ROADMAP.md: v7+v8 als erledigt, naechste Features (v8.1-v9.1) - README.md: komplett neu geschrieben (Agentic OS Konzept, alle Features) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
7.1 KiB
Mission Control
Web-Dashboard zur Verwaltung eines lokalen LLM-Stacks (llama-swap) auf dem Bosgame M5.
FastAPI-Backend + Svelte 5-Frontend (Vite-Build). Leitprinzip: KISS — SoC ohne Overhead.
Architektur
Backend (Top-Level-Helfer + ein Router je Bereich):
app.py— dünner Einstieg:FastAPI, hängt die Router ein, liefert das statische UI aus, Exception-Handler +Cache-Control: no-cache-Middleware.config.py— alle Env-Vars + die gemeinsameruamel.yaml-Instanz. AuchSOURCE_DIR/PROD_DIRfürs Self-Update.auth.py— optionale Token-Auth: HeaderX-MC-Tokenoder Query?token=(Query ist Pflicht für WebSockets).jobengine.py— In-Memory-Job-System (Threads + Subprocess) mit Live-Log. Secrets gehen über stdin (kein Leak in Log/ps).llamaswap.py— sprichtllama-swapan und liest/schreibt dessenconfig.yamlperruamel.yaml.hw_math.py— Odysseus-Fit-Mathe: VRAM/RAM-Bedarf, tps-Schätzung,max_ctx_for,extract_params_b.recipes.py— kuratierte Use-Case-Stacks fürs Cookbook 2.0.hermes_agent.py— Kern des Hermes-Agenten: Tool-Definitionen, Tool-Dispatcher, LLM-Loop (ReAct), Modell-Routing.mcp_memory.py— stdio-MCP-Server: Gedächtnis-Tools für Cline/OpenCode/Claude Code.routers/*.py— ein Router je Bereich:models.py— status/download/register/update_model/unload/chatjobs.py— Jobs-Listemaintenance.py— update/self-update/os-update/service-restart/reboot/logs-WebSocketsystem.py— status + stream-WebSocket (Live-Metriken psutil/sysfs)cookbook.py— analyze/evaluate/recipes/install-recipe/upgradesintegration.py— test (Engine-Verbindungstest)news.py— RSS-Aggregation via stdlibmemory.py— Gedächtnis-CRUD (SQLite, WAL-Mode), 5 Kategorienhermes.py— Chat-WebSocket/transcribe(Whisper)/tts(Piper)/status/pubkey
Frontend (frontend/src/, Svelte 5 + Vite, Build → static/dist/):
index.html— Gerüst: Sidebar-Nav (10 Tabs), Topbar, Alert-Banner, View-Container je Bereich.frontend/src/main.ts— bootet alle Svelte-Panels, Topbar/Alert, WebSocket Live-Metriken, Polling.frontend/src/panels/— je ein Panel: Overview, Models, Jobs(Aktivität), Server, Cookbook, Connect(Verbinden), News, Guides, Memory(Gedächtnis), Hermes.frontend/src/stores/— Svelte 5 Runes:status.svelte.ts,jobs.svelte.ts,system.svelte.ts.- Design-System (v3): EINE Akzentfarbe Teal
#2dd4bf. Grün/Gelb/Rot nur für Status. Tokens incss/base.css.
Der Stack drumherum
- Bosgame M5: AMD Strix Halo (gfx1151), Ubuntu 26.04, Kernel 7.0, ~124 GB GTT. LAN-IP
192.168.178.151. - Inferenz: llama.cpp-ROCm-Binaries →
llama-swapauf*:8080(LAN-offen,-watch-config). - 3 Modelle / 5 Rollen:
coder(Qwen3-30B-A3B),scout(Qwen3-8B),vision(Qwen3-VL). - Mission Control: Produktiv unter
/opt/mission-control, Source unter~/mission-control. - Gedächtnis: SQLite unter
/srv/models/mission-control-memory.db(5 Kategorien: user/instruction/stable/versioned/ephemeral). - Hermes Agent: läuft als Teil von Mission Control (kein separater Dienst), Voice via Whisper (CPU) + Piper TTS.
Entwickeln & Deployen
Wo entwickelt wird: Windows-PC (F:\Coding Stuff\mission-control), Ziel: Linux-Bosgame.
Lokal nur Smoke-Test (rendert/bootet?), echter Funktionstest auf dem Bosgame.
Lokaler Smoke-Test (Windows):
python -m venv .venv && .venv/Scripts/python -m pip install -r requirements.txt
.venv/Scripts/python -m uvicorn app:app --port 9001
Bosgame-Zugang:
ssh -i ~/.ssh/id_ed25519_hermes -o IdentitiesOnly=yes hitonabi@192.168.178.151
User: hitonabi. sudo NOPASSWD-Whitelist für systemctl restart mission-control|llama-swap und journalctl.
Frontend-Build:
cd frontend && npm run build # vor jedem git push
Output: static/dist/main.js + static/dist/main.css — wird committet (kein Build-Schritt auf dem Server).
Deploy-Kette:
npm run build → git push (Gitea :3000) → Bosgame: git pull → rsync → systemctl restart
Oder über den Self-Update-Button in Mission Control (empfohlen).
Self-Update-Button (POST /api/self-update): git pull → rsync → restart — alles in einem Klick.
Konfiguration (Env-Vars)
| Variable | Default | Zweck |
|---|---|---|
MC_LLAMA_SWAP_URL |
http://127.0.0.1:8080 |
llama-swap URL |
MC_CONFIG_PATH |
/etc/llama-swap/config.yaml |
llama-swap Config |
MC_MODELS_DIR |
/srv/models |
GGUF-Ablageort |
MC_TOKEN |
leer | Auth-Token (optional, LAN-only) |
MC_UPDATE_CMD |
leer | Engine-Update-Befehl |
MC_DEFAULT_TTL |
300 |
Sekunden bis Auto-Unload |
MC_SOURCE_DIR |
~/mission-control |
Self-Update Quelle |
MC_MEMORY_DB |
{MODELS_DIR}/mission-control-memory.db |
SQLite Gedächtnis |
HERMES_SIMPLE_MODEL |
scout |
Modell für einfache Tasks |
HERMES_COMPLEX_MODEL |
coder |
Modell für komplexe Tasks |
HERMES_WINDOWS_HOST |
leer | Windows-PC IP für SSH |
HERMES_WINDOWS_USER |
TobisPC |
Windows SSH-Username |
HERMES_SSH_KEY |
~/.ssh/id_ed25519_hermes_agent |
SSH-Key für Hermes |
PIPER_BIN |
/opt/mission-control/piper/piper |
Piper TTS Binary |
PIPER_VOICE |
.../de_DE-kerstin-low.onnx |
Piper Stimm-Modell |
WHISPER_MODEL |
medium |
Whisper Modell-Größe |
Konventionen
- Neuer Bereich:
routers/<bereich>.py+frontend/src/panels/<Bereich>Panel.svelte+ Nav/View inindex.html+ Import inmain.ts. Danachnpm run build. - Backend SoC: gemeinsame Logik in
config/auth/jobengine/llamaswap/hw_math. Alles unter/api/*. - Sicherheit: Shell-Befehle → nur LAN. Secrets via stdin. Token optional.
- SQLite: WAL-Mode aktiv,
check_same_thread=False— ausreichend für Single-User. asyncio.get_running_loop()stattget_event_loop()(Python 3.10+ kompatibel).- Memory-Kategorien:
user|instruction|stable|versioned|ephemeral— Enum inrouters/memory.py.
Gotchas
${PORT}in llama-swap-Config →str.replacestatt.format(KeyError sonst).-watch-configbei llama-swap nötig für Auto-Einpflegen.HF_HUB_DISABLE_XET=1bei HuggingFace-Downloads (Hänger bei ~6 MB).- Vision-Modelle: brauchen
--mmproj <projektor>und--jinja. - Gitea-Push kann transient mit „Failed to authenticate" fehlschlagen → einfach nochmal.
- Piper TTS: Binary + Stimm-Modell müssen separat installiert werden (nicht via pip).
- Whisper: lädt beim ersten Aufruf ~1.4 GB Modell herunter (einmalig, dann gecacht).
- Hermes SSH-Key: muss auf dem Bosgame generiert werden (
~/.ssh/id_ed25519_hermes_agent).
Projektstatus
v7 (Memory Layer): SQLite-Gedächtnis mit 5 Kategorien + MCP-Server für alle Tools live. v8 (Hermes Agent): Chat-Agent mit Voice (Whisper STT + Piper TTS), Tool Calling, WebSocket-Streaming live. Offene v8-Schritte: Piper-Binary installieren, Windows OpenSSH Server + SSH-Key einrichten.
Nordstern: Den Bosgame nie wieder via SSH/Putty anfassen — 100 % Automatisierung / Klicki-Bunti.