# Mission Control Web-Dashboard zur Verwaltung eines **lokalen LLM-Stacks (`llama-swap`)** auf dem Bosgame M5. FastAPI-Backend + Single-File-HTML-Dashboard. **Leitprinzip: KISS — kein Build-Schritt, kein Frontend-Framework, keine Datenbank.** ## Architektur - **`app.py`** — FastAPI-Backend. Endpoints unter `/api/*`: `status`, `download`, `register`, `unload`, `update`, `chat`, `jobs`. Ein In-Memory-Job-System (Threads + Subprocess) fährt Downloads/Updates mit Live-Log. Spricht `llama-swap` an (`/running`, `/v1/models`, unload) und editiert dessen `config.yaml` per `ruamel.yaml` (Kommentare bleiben erhalten). - **`static/index.html`** — das komplette Dashboard. Vanilla JS, inline CSS, kein Build. Sektionen: Modelle/Ports, Download + Einpflegen, Wartung, Schnelltest-Chat, Aktivität. - **`mission-control.service`** — systemd-Unit (uvicorn auf Port 9000). - **Konfiguration** rein über Env-Vars: `MC_LLAMA_SWAP_URL`, `MC_CONFIG_PATH`, `MC_MODELS_DIR`, `MC_CMD_TEMPLATE`, `MC_UPDATE_CMD`, `MC_DEFAULT_TTL`, `MC_TOKEN`. ## Der Stack drumherum (Kontext) - **Bosgame M5**: AMD Strix Halo (gfx1151), Ubuntu 26.04, Kernel 7.0, ~124 GB GTT-Speicher. LAN-IP `192.168.178.151`. - **Inferenz**: vorgebaute llama.cpp-ROCm-Binaries → `llama-swap` auf `:8080` (läuft mit `-watch-config`). - **3 Modelle / 5 Rollen**: `coder`, `scout`, `vision` (Qwen3-Familie). Modelle werden geswappt, nicht parallel geladen. - **Mission Control**: Produktiv unter `/opt/mission-control` (als Dienst), Source-Repo unter `~/mission-control`. ## Entwickeln - **Niemals direkt in `/opt` arbeiten.** Dev-Instanz aus der Source auf einem anderen Port starten: ```bash cd ~/mission-control && python3 -m venv .venv && . .venv/bin/activate pip install -r requirements.txt uvicorn app:app --host 0.0.0.0 --port 9001 --reload ``` Dann `:9001` = Spielwiese, `:9000` = stabil. - **Ausrollen**: `sudo cp -r ~/mission-control/. /opt/mission-control/ && sudo systemctl restart mission-control` - **Logs**: `journalctl -u mission-control -f` ## Konventionen - KISS über alles: kein schweres Framework, solange es ohne geht. Ein HTML-File fürs UI. - Funktion darf **nicht** von `localStorage` abhängen (nur das Token-Feld nutzt es, das ist ok). - **Sicherheit**: Das Backend führt Shell-Befehle aus → ausschließlich im vertrauenswürdigen LAN betreiben, niemals offen ins Internet. ## Gotchas (wichtig!) - **`${PORT}`** in der generierten `llama-swap`-Config muss **literal** stehen bleiben → beim Bauen des cmd-Strings `str.replace` benutzen, NICHT `.format` (sonst KeyError auf `PORT`). - `llama-swap` muss mit **`-watch-config`** laufen, sonst greift das Auto-Einpflegen neuer Modelle nicht. - HuggingFace-Downloads mit **`HF_HUB_DISABLE_XET=1`** (sonst reproduzierbarer Hänger bei ~6 MB). - Vision-Modelle in llama.cpp brauchen zusätzlich **`--mmproj ` und `--jinja`**. ## Roadmap Siehe @ROADMAP.md für die v2-Planung. **Nordstern: den Server nie wieder via SSH/Putty anfassen müssen — 100 % Automatisierung / Klicki-Bunti.**