v6: Toolbar zeigt AI-Engine-Update-Status + immer-sichtbare Badges

- /api/updates liefert zusaetzlich "engine" (llama.cpp-ROCm: neueste
  GitHub-Release vs. /opt/llamacpp-mtime, 1h gecacht)
- Toolbar-Badges fuer OS/Engine/Modelle jetzt auch im "aktuell"-Zustand
  sichtbar (gruener .ok-Style) statt nur bei ausstehenden Updates
- Guide: neuer Tutorial-Eintrag "Was passiert, wenn der Kontext volllaeuft?"

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hitonabi
2026-06-21 17:40:56 +02:00
parent 3ccdee339a
commit 3a4de152b0
4 changed files with 42 additions and 4 deletions
+27 -2
View File
@@ -72,9 +72,34 @@ def reboot(req: PwdReq):
pass
return {"ok": True, "note": "Reboot getriggert."}
_engine_cache = {"ts": 0.0, "avail": False}
def _engine_update_available():
"""Heuristik: ist die neueste llama.cpp-ROCm-Release neuer als die installierte? (1h gecacht)"""
import time
now = time.time()
if now - _engine_cache["ts"] < 3600:
return _engine_cache["avail"]
avail = False
try:
import os as _os
import httpx
from datetime import datetime
rel = httpx.get("https://api.github.com/repos/lemonade-sdk/llamacpp-rocm/releases/latest",
timeout=6, headers={"User-Agent": "MissionControl"}).json()
pub = datetime.fromisoformat(rel["published_at"].replace("Z", "+00:00")).timestamp()
inst = _os.path.getmtime("/opt/llamacpp")
avail = pub > inst + 86400 # neuer als Installation (1 Tag Puffer)
except Exception: # noqa: BLE001
avail = False
_engine_cache.update(ts=now, avail=avail)
return avail
@router.get("/updates")
def updates():
"""Ausstehende Updates für die Toolbar: OS-Pakete (apt-Cache) + Modell-Upgrades."""
"""Ausstehende Updates für die Toolbar: OS-Pakete (apt), AI-Engine (llama.cpp), Modell-Upgrades."""
import psutil
from routers.cookbook import compute_upgrades
os_count = 0
@@ -89,7 +114,7 @@ def updates():
models = len(compute_upgrades(psutil.virtual_memory().total / (1024 ** 3)))
except Exception: # noqa: BLE001
models = 0
return {"os": os_count, "models": models}
return {"os": os_count, "models": models, "engine": 1 if _engine_update_available() else 0}
@router.websocket("/logs/{service}")
async def stream_logs(websocket: WebSocket, service: str):