Ursache des fehlgeschlagenen Engine-Updates: die allerneueste llama.cpp-Release traegt
oft noch KEINE CI-Binaries (0 Assets). update-engine.sh lud aber stur von releases/latest
→ 404 „Download fehlgeschlagen".
Fix:
- update-engine.sh: nimmt die neueste Release, die wirklich ein ubuntu-vulkan-x64.tar.gz
traegt, und nutzt dessen echte browser_download_url (robust gegen Namensaenderungen).
- maintenance.py: _engine_update_available + engine_update_details pruefen jetzt ebenfalls
gegen die neueste ASSET-tragende Release → das Badge luegt nicht mehr („verfuegbar", aber
Download 404). Verifiziert: aufgeloeste URL liefert HTTP 200.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Terminals (wie die Box-Konsole):
- hermes-terminal bindet jetzt NUR Loopback (--interface lo --base-path /hermes-terminal)
und wird von MC2 same-origin durchgereicht (routers/console.py generalisiert auf beide
ttyd-Instanzen). Kein eigener Firewall-Port mehr noetig.
- Beide Terminals starten die Shell/CLI ueber `su - hitonabi` → fragen beim Oeffnen das
Box-Passwort ab (PAM gegen das echte Konto, nichts gespeichert). „Login mit sudo-PW".
- agent_status.terminal_url = /hermes-terminal/ (+ reachable via Loopback-Check).
Engine-Update (llama.cpp) — Fix „nicht moeglich":
- update-engine.sh/update-swap.sh sind per sudoers NOPASSWD freigegeben → das fruehere
`sudo true`-Passwort-Gate hat sie faelschlich blockiert (wenn kein/falsches Box-PW). Gate
entfernt → Engine-/Router-Update laufen jetzt passwortlos.
OS-Update (apt) — Fix „nicht moeglich":
- DEBIAN_FRONTEND wird jetzt INNERHALB `sudo bash -c '…'` gesetzt statt `sudo VAR=… cmd`
(sonst lehnt sudos env-Policy die Variable ab und das Upgrade bricht ab).
- Frontend verschluckt password_required/incorrect_password nicht mehr still, sondern zeigt
einen klaren Hinweis (Box-Passwort in „Box-Zugang" setzen/pruefen).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
a) Update-Meldungen: generischer Release-Summarizer in Lucys Stimme mit
strukturiertem Aktions-Verdikt ("Musst du etwas tun? NEIN/JA") für
Hermes, Engine (llama.cpp) und llama-swap; Fangnetz-Hinweis verheiratet
Breaking-Change-Sorge mit dem Postcheck.
b) OS ehrlich: zurückgestellte Pakete (Phasen-Rollout / kept back) werden
ausgewiesen statt scheinbar zu hängen.
d) Ehrliche Speicher-Zahlen: KV-Cache aus echten GGUF-Architektur-Daten
(Layer × KV-Köpfe × head_dim) + KV-Quant aus dem cmd statt params-blinder
Schätzung — footprint_gb als eine Zahlensprache (Zentrale, Modell-Manager,
fits-Check auf warmset+largest). Auto-Rewarm-Nudge nach Config-Reload.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
_summarize_hermes_commits nutzt jetzt finish_reason: bei "length" (Token-Limit
erreicht) wird der unvollstaendige letzte Stichpunkt entfernt, bei "stop" bleibt
die Antwort unveraendert. max_tokens 380 -> 550 als Puffer.
Erster echter Werkstatt-Kreislauf (Gesellenpruefung), Runde 2 nach Review.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Update-Job: nach 'hermes update' laeuft 'hermes doctor' (Job rot bei Fehlern)
- hermes-postcheck.sh: Journal-Scan auf Unknown/deprecated/defaulting (Lehre aus v0.18:
approvals.mode 'auto' wurde still ungueltig -> alle Tools in pending_approval),
Tool-Smoke (echo via Agent, erkennt pending_approval), Voice-Smoke (/api/voice/chat)
- Update-Modal: die Box fasst anstehende Hermes-Commits selbst zusammen (fast-Modell,
no-think, gecacht auf neuesten Hash) — Breaking Changes zuerst
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bisher kein Schutz: Doppelklick/zwei Tabs konnten zwei update-engine.sh parallel
starten → racende .bak-Sicherung + parallele llama-swap-Restarts + sich gegenseitig
als kaputt sehende Postchecks.
Backend: jobengine.start_job bekommt group-Tag + active_in_group(); os/engine/swap/
hermes-update sind group="maintenance" und lehnen einen Start ab, solange eines laeuft
({ok:false, status:"busy", running:<label>}). Schuetzt auch gegen parallele Sessions.
Frontend: laeuft ein Wartungs-Job, zeigt der Drawer ein Banner "Update laeuft: <label>"
und sperrt "Jetzt aktualisieren" + "Nach Updates suchen". Logs/Job-Fortschritt/Dienste
bleiben voll nutzbar (Dashboard nicht hart gesperrt). Busy-Antwort wird als Hinweis gezeigt.
Modell-Upgrades bleiben erlaubt (parallel unkritisch).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>