fix(v8.1): Kritische Bugs behoben — system_status, model-routing, UI

P0:
- hermes_agent: system_status Key-Mismatch behoben (cpu_pct→cpu.percent,
  ram_used_gb→ram.used/1024³, gtt analog) — zeigt jetzt echte Werte statt '?'
- guides-data: & in 4 Titel-Strings → & (Svelte text-node rendert keine HTML-Entities)

P1:
- hermes_agent: choose_model() um recherchier/such/vergleich/etc. erweitert;
  kein Downgrade wenn komplexes Modell bereits geladen
- routers/hermes: asyncio.get_event_loop() → get_running_loop() (Whisper+TTS)
- maintenance: llama-swap Update akzeptiert optionales sudo-PW via stdin;
  import os hinzugefügt (fix NameError in updates()); UpdateReq-Model
- ServerPanel: Engine-Update fragt jetzt nach sudo-PW (analog OS-Update)
- HermesPanel: Chat-History in sessionStorage (überlebt Reload);
  Stopp-Button während Hermes antwortet; Verlauf-löschen-Button
- ConnectPanel: opencode.json → opencode.jsonc; provider → providers;
  LAN-IP Override (localStorage) für NPM-Proxy-Setups

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-23 18:19:01 +02:00
parent 8539999627
commit e8971fbf0c
8 changed files with 204 additions and 89 deletions
+47 -11
View File
@@ -197,13 +197,22 @@ def _exec_get_system_status() -> str:
model_str = "unbekannt"
try:
sys = httpx.get(f"{base}/api/system/status", timeout=5).json()
d = httpx.get(f"{base}/api/system/status", timeout=5).json()
cpu = d.get("cpu", {})
ram = d.get("ram", {})
gtt = d.get("gpu", {}).get("gtt", {})
cpu_pct = round(cpu.get("percent", 0), 1)
cpu_temp = cpu.get("temp", "?")
ram_used = round(ram.get("used", 0) / (1024 ** 3), 1)
ram_total = round(ram.get("total", 0) / (1024 ** 3), 1)
gtt_used = round(gtt.get("used", 0) / (1024 ** 3), 1)
gtt_total = round(gtt.get("total", 0) / (1024 ** 3), 1)
return (
f"Aktives Modell: {model_str}\n"
f"CPU: {sys.get('cpu_pct', '?')}% | "
f"RAM: {sys.get('ram_used_gb', '?')} / {sys.get('ram_total_gb', '?')} GB | "
f"GPU: {sys.get('gpu_mem_used_gb', '?')} / {sys.get('gpu_mem_total_gb', '?')} GB GTT\n"
f"Temp: CPU {sys.get('cpu_temp_c', '?')}°C"
f"CPU: {cpu_pct}% | "
f"RAM: {ram_used} / {ram_total} GB | "
f"GPU: {gtt_used} / {gtt_total} GB GTT\n"
f"Temp: CPU {cpu_temp}°C"
)
except Exception as e:
return f"Aktives Modell: {model_str}\nSystem-Metriken nicht verfuegbar: {e}"
@@ -275,17 +284,44 @@ def execute_tool(name: str, args: dict) -> str:
# ---------------------------------------------------------------------------
_COMPLEX_KW = {
"schreib", "erstell", "baue", "plan", "refactor", "debug", "analysier",
"implementier", "entwickl", "code", "programm", "erklaer ausfuehrlich",
"erstelle", "generier",
# Erstellen / Schreiben
"schreib", "schreibe", "erstell", "erstelle", "generier", "generiere",
"baue", "bau",
# Planen / Analysieren / Recherchieren
"plan", "analysier", "analysiere", "recherchier", "recherchiere",
"vergleich", "vergleiche", "bewert", "bewerte", "untersuche", "untersuchen",
# Entwicklung / Code
"refactor", "debug", "implementier", "implementiere", "entwickl", "entwickle",
"code", "programm", "programmier", "programmiere",
# Web-Suche / Recherche
"such im internet", "suche im internet", "such online", "suche online",
"such nach aktuell", "suche nach aktuell",
# Erklären (ausführlich)
"erklaer ausfuehrlich", "erklaere ausfuehrlich", "erklaer detailliert",
"erklaere detailliert", "erklaer mir genau", "was ist der unterschied",
# Optimieren / Verbessern
"optimier", "optimiere", "verbessere", "verbessern", "reparier", "repariere",
# Multi-Step / Komplex
"konfiguriere", "konfigurieren", "installier", "installiere",
"wie kann ich", "schritt fuer schritt", "schritt für schritt",
}
def choose_model(message: str) -> str:
"""Waehlt simple/complex Modell — upgraded wenn noetig, degradiert nie."""
lower = message.lower()
if any(kw in lower for kw in _COMPLEX_KW):
return HERMES_COMPLEX_MODEL
return HERMES_SIMPLE_MODEL
wants_complex = any(kw in lower for kw in _COMPLEX_KW)
# Nicht downgraden wenn komplexes Modell bereits geladen ist
try:
s = httpx.get("http://127.0.0.1:9000/api/status", timeout=3).json()
loaded = {m["name"] for m in s.get("models", []) if m.get("state") in ("running", "ready")}
if HERMES_COMPLEX_MODEL in loaded:
return HERMES_COMPLEX_MODEL
except Exception:
pass
return HERMES_COMPLEX_MODEL if wants_complex else HERMES_SIMPLE_MODEL
# ---------------------------------------------------------------------------
# System-Prompt