update-engine.sh / update-swap.sh sichern jetzt den alten Build/die alte Binary
VOR dem Ueberschreiben (.bak), verifizieren nach dem Restart per stack-postcheck.sh
und rollen bei Fehler automatisch zurueck (Binary/Dir wiederherstellen + restart +
erneut pruefen). Exit-Codes: 0 = neuer Build verifiziert, 1 = fehlgeschlagen aber
Rollback ok (alter Stand laeuft wieder), 2 = Update UND Rollback kaputt.
Da die Skripte den Postcheck nun selbst fahren (um reagieren zu koennen), entfaellt
das `&& stack-postcheck` in engine/swap-update-job. OS-Update behaelt den reinen
Detect-Check (apt-Downgrade waere unsicher). Backups sind winzig (Engine 86M,
Swap 14M) bei 1.6TB frei.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bisher hatte nur das Hermes-Update einen echten Post-Check; OS/Engine/Router
liefen mit Exit 0 durch, auch wenn der neue Build den Stack zerschoss (gruener
Job trotz totem Stack). Neu: deploy/stack-postcheck.sh prueft nach jedem Update
funktional — llama-swap aktiv, /v1/models 200, ECHTE 1-Token-Inferenz auf dem
Hirn-Modell (beweist Laden+Generieren), MC2 /api/health engine_reachable, Mem0
erreichbar. Eingehaengt als `<update> && bash stack-postcheck.sh` in os/engine/
swap-update-job → Exit 1 macht den jobengine-Job ROT. Pendant zu hermes-postcheck.sh.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_os_upgradable zaehlte mit `grep -c upgradable`, os_update_details parste
`[upgradable from:]` — beides englisch. Auf der deutschsprachigen Box gibt apt
aber `[aktualisierbar von:]` aus → Zaehler 0 und leere Detailliste, obwohl
`apt list --upgradable` 7 Pakete zeigt. Fix: apt mit LC_ALL=C aufrufen, dann
ist die Ausgabe immer englisch und beide greifen wieder.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- _installed_engine_build matchte nur 'build: <hash> (N)' / 'bNNNN', aber der
aktuelle llama-server meldet 'version: 9821 (hash)'. Dadurch war installed_build
immer None → Engine-Badge fiel auf ungenauen mtime-Vergleich zurueck. Jetzt
praeziser Build-Nummer-Vergleich (latest > installed).
- .gitattributes erzwingt LF fuer *.sh/*.service/*.timer: die Box hatte
core.autocrlf aktiv und checkte deploy.sh mit CRLF aus -> 'set -euo pipefail'
wurde zu 'pipefail\r' (invalid option name), Deploy brach ab.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- engine_update_job leert jetzt _engine_cache nach Abschluss (on_done),
sonst zeigte das Dashboard bis zu 1h "Update verfuegbar" trotz erfolgter
Aktualisierung (1h-Cache wurde nie invalidiert wie bei den anderen Jobs).
- check_updates_job leert zusaetzlich _comp_cache, damit "Nach Updates suchen"
auch den Hermes-Status frisch prueft.
- Neu: GET /api/maintenance/update-details (os|engine|hermes) liefert, was
genau aktualisiert wird (apt-Paketliste, Engine Build X->Y + Release-Notes,
Hermes-Commits HEAD..origin/branch).
- Frontend: "Aktualisieren"-Buttons -> "Anzeigen"; oeffnen ein Detail-Fenster
mit den konkreten Aenderungen, erst "Jetzt aktualisieren" startet das Update.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Wartungs-Tab im SystemDrawer neu strukturiert:
- UPDATES: eine einheitliche Liste (OS, Engine, Hermes-Agent, Modell-Upgrades) mit
Status + Aktion-Button, der nur aktiv ist wenn ein Update ansteht (statt Klick-Karten,
die sofort updaten). Konsistent mit der Dashboard-UpdatesCard.
- DIENSTE: neue Sektion, alle systemd-Units mit Status-Punkt (aus /api/system/services,
jetzt inkl. mem0-service) + Restart + Logs-Sprung.
- BACKUP: kompakt (letztes Backup + Snapshot-Button + Restore-Hinweis).
- GEFAHRENZONE: Reboot abgetrennt. Jobs nur wenn vorhanden.
Hermes-Update-Button: POST /api/maintenance/hermes-update -> Job (Backup -> `hermes update
--yes` (git pull + deps) -> hermes-gateway restart). Backend: hermes_update_job + USER_SERVICES
um mem0-service/hermes-terminal ergaenzt (Restart ging vorher nicht), mem0 in services-API.
Live verifiziert: Button hat Hermes d470ed0 -> 3b44a3c aktualisiert, Integration intakt
(memory.provider, Plugin laedt), Pre-Update-Backup angelegt, Drawer rendert fehlerfrei.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bug: UI zeigte nie ein Hermes-Update, obwohl die CLI eins anzeigte. Ursache: MC2 verglich
das neueste GitHub-RELEASE (frozen v2026.6.19) gegen das installierte Commit — Hermes wird
aber aus git main aktualisiert (`hermes update` = git pull origin <branch>), und main laeuft
den Releases voraus. Darum war update immer false.
Fix: _hermes_agent_update() macht jetzt git fetch + zaehlt Commits HEAD..origin/<branch>
(genau wie `hermes update --check`). update=true wenn behind>0; latest = origin-Kurzhash +
behind-Count. Tote Release-Helfer (_gh_latest, _commit_ts) + HERMES_AGENT_REPO-Import entfernt.
Verifiziert: MC2 == CLI (beide "Update verfuegbar, 1 Commit hinter origin/main").
Frontend (UpdatesCard) rendert components bereits korrekt — nur das Backend-Signal war falsch.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Paket B des Plans. AnythingLLM war nur ein Fallback-Chat zu Hermes; ersetzt durch das
echte interaktive Agent-Terminal (`hermes chat`, mit Tools/PC) als eingebettetes
Web-Terminal.
Box: ttyd (apt) wrappt `hermes chat`; systemd-User-Unit deploy/hermes-terminal.service
(LAN-Bind eno1:7681, apt-Default-ttyd-Dienst deaktiviert). In deploy.sh verankert.
Backend: config HERMES_TERMINAL_URL statt ANYTHINGLLM_URL/_REPO; agent_status liefert
terminal_url/terminal_reachable; maintenance ohne _anythingllm_update; system.py Dienst-Liste
zeigt "Hermes-Terminal".
Frontend: neue Terminal-Seite (iframe auf ttyd) + Nav-Tab; AgentView/AgentStatusCard/nav/api
auf Terminal umgestellt; SystemDrawer toter hermes-dashboard raus, hermes-webui -> hermes-terminal;
Guide-Texte aktualisiert.
Cleanup: deploy/hermes-webui.service + deploy/lobechat/ entfernt (LobeChat-Migration hinfaellig),
HERMES_WEBUI_URL-Env raus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inspiriert von Odysseus' Cookbook: backend/models_catalog.json mit echten Metadaten
(total/active params, moe, generation) je Rolle. services/catalog.py: Laden, Name-Match,
MoE-bewusstes Scoring (Wissen + Tempo via tps -> MoE-first auf der bandbreiten-Box), Fit.
- discover.py: Empfehlung jetzt KATALOG-FIRST (kuratiert, korrekt), HF-Dynamik als Ergaenzung/Fallback.
- maintenance.model_upgrades: Metadaten aus Katalog -> praezise Familie/Generation/Groesse + MoE-first
(dense ersetzt MoE nur bei grossem Wissens-Sprung). Behebt Coder-Next=7B-Fehlschaetzung,
Qwen2.5-VL-Generations-Downgrade, falsches dense-scout-Upgrade.
- fit.py: MXFP4/FP8/AWQ in der Quant-Tabelle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
model_upgrades verletzte das Prinzip: schlug Generations-Downgrades (Qwen2.5-VL ueber
Qwen3-VL), Groessen-Downgrades (Qwen3-Coder-Next ~84B -> 30B; Params aus Name als 7B
fehlgeschaetzt) und Fremd-Familien-Swaps (gpt-oss als Qwen-"Upgrade") vor.
- _params_of: groessen-bewusste Params (max aus Name + Dateigroesse).
- _gen_key: Familie+Subtyp+Generation aus dem Namen (qwen-vl 3.0 vs 2.5 etc.).
- Guard: Upgrade nur bei gleicher erkennbarer Familie UND (neuere Generation ODER
deutlich groesser in gleicher Gen). Sonst keine "Bessere Version"-Anzeige.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- discover.rank_runnable: rankt jetzt fit-level > params_b(desc) > downloads -> fuer die
128GB-Box wird das faehigste passende (MoE-)Modell empfohlen statt kleiner Populaer-Modelle.
Top-4-Anzeige nutzt dasselbe Ranking.
- maintenance.model_upgrades: schlaegt KEIN Downgrade mehr vor (rec.params_b >= installiert*0.95).
Behebt: fast 35B-A3B -> 4B wurde faelschlich als Upgrade angeboten.
- Frontend: Rollen-Farb-Mapping zentralisiert in ModelBadges (ROLE_TONE/roleTone);
Cockpit/RolesCard/ActiveModelsCard nutzen es statt eigener Duplikate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Engine-Cutover ROCm/HIP -> Vulkan/RADV (gfx1151): +12-22% tg auf MoE (llama-bench
verifiziert, fast 53->65 t/s). ROCm-Build bleibt als Rollback unter /opt/llamacpp.
- Backend: vocab-aware Speculative Decoding. services/gguf_meta.py liest den
Tokenizer-Fingerprint (model/pre/n_vocab) direkt aus dem GGUF-Header (ohne Modell-Load);
register_model + migrate_config haengen nur VOCAB-KOMPATIBLE Drafts an (inkl. --spec-type,
das in dieser llama.cpp-Generation noetig ist). Neue Endpoints /api/models/drafts + /{id}/draft.
- Frontend: idiotensichere Spec-Draft-UI (SpecDraftModal) - nur kompatible Drafts waehlbar,
inkompatible gesperrt mit Begruendung; SPEC/SPEC?-Badge nach echtem Aktiv-Status; Rolle in AddModel.
- maintenance.py: Engine-Update-Quelle -> ggml-org/llama.cpp (Build-Nummer-Vergleich),
ENGINE_PATH=/opt/llamacpp-vulkan.
- Startup-Warmup der brains (deploy/warmup.sh, self-detaching ExecStartPost) + deploy/provision-engine.sh.
- Cleanup: tote LiteLLM gateway/config.yaml + alle Referenzen (config.py/backup.py/backup.sh) entfernt;
README + docs/memory aktualisiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- ActiveModelsCard: zeigt geladene Modelle (aus /running via useModels) mit
Rolle, Größe (Unified-RAM) und warm-Status; globaler "Inferenz aktiv"-Puls
via useTokenStats-Delta. Prominent oben im Dashboard. Kein Backend-Change.
- maintenance.logs(): journalctl ohne sudo zuerst (User in Gruppe adm darf das
System-Journal lesen), nur bei fehlenden Rechten sudo-Fallback. Behebt
"Unbekannter Fehler" beim llama-swap-Log im MC2-UI.
tsc + Build grün; Dashboard rendert die Live-Karte (Leerzustand lokal, da Engine
offline), keine Konsolenfehler.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>