65d8ab5fe3
- Engine-Update: deploy/update-engine.sh laedt neuesten ggml-org Vulkan-Build + restart; MC_ENGINE_UPDATE_CMD verdrahtet, engine_update_job nutzt es (Script macht Restart selbst). - Update-Checks: Hermes Agent (NousResearch/hermes-agent, Release-Datum vs. installiertes Commit) + AnythingLLM (Mintplex-Labs/anything-llm, neueste Version + /api/ping-Health), 1h-Cache. Neues Feld /api/maintenance/updates.components; UpdatesCard zeigt beide Zeilen. - WebUI -> AnythingLLM: agent_status.webui_* zeigt jetzt auf ANYTHINGLLM_URL (192.168.178.155:3001, /api/ping); alle "Hermes WebUI"-Buttons/Labels (AgentView, AgentStatusCard, nav, GuideView, Services-Liste) -> "AnythingLLM". Lokaler hermes-webui-Dienst bleibt als Service-Control im SystemDrawer. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
123 lines
4.2 KiB
Python
123 lines
4.2 KiB
Python
"""
|
|
Hermes-Agent-Status (Control-Plane-Read). MC betreibt Hermes NICHT — es zeigt nur
|
|
Status + verlinkt das standalone hermes-webui. Voller Zugriff + Tools/MCP werden in
|
|
Hermes' eigener Config verdrahtet (siehe docs/HERMES_SETUP.md).
|
|
"""
|
|
|
|
import logging
|
|
import os
|
|
|
|
import httpx
|
|
|
|
from config import ANYTHINGLLM_URL, HERMES_API_URL, HERMES_HOME, PC_EXECUTOR_URL
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
def _reach(url: str, path: str = "") -> bool:
|
|
try:
|
|
with httpx.Client(timeout=3.0) as c:
|
|
return c.get(f"{url}{path}").status_code < 500
|
|
except httpx.HTTPError:
|
|
return False
|
|
|
|
|
|
def _count_enabled_mcp_servers() -> int:
|
|
config_path = HERMES_HOME / "config.yaml"
|
|
if not config_path.exists():
|
|
return 0
|
|
try:
|
|
from ruamel.yaml import YAML
|
|
r_yaml = YAML()
|
|
with config_path.open("r", encoding="utf-8") as f:
|
|
cfg = r_yaml.load(f) or {}
|
|
mcp_servers = cfg.get("mcp_servers", {}) if isinstance(cfg, dict) else {}
|
|
if not isinstance(mcp_servers, dict):
|
|
return 0
|
|
return sum(1 for v in mcp_servers.values() if isinstance(v, dict) and v.get("enabled", True))
|
|
except Exception:
|
|
log.debug("_count_enabled_mcp_servers: Fehler", exc_info=True)
|
|
return 0
|
|
|
|
|
|
def agent_status() -> dict:
|
|
"""Erreichbarkeit von Gateway (:8642) + WebUI (:8787) + lokale Hinweise."""
|
|
home = HERMES_HOME
|
|
brain_model = "auto"
|
|
config_path = home / "config.yaml"
|
|
if config_path.exists():
|
|
try:
|
|
from ruamel.yaml import YAML
|
|
r_yaml = YAML()
|
|
with config_path.open("r", encoding="utf-8") as f:
|
|
cfg = r_yaml.load(f) or {}
|
|
if isinstance(cfg, dict):
|
|
brain_model = cfg.get("model", {}).get("model", "auto")
|
|
except Exception:
|
|
log.debug("agent_status: Hermes-config.yaml nicht lesbar", exc_info=True)
|
|
|
|
|
|
return {
|
|
"gateway_url": HERMES_API_URL,
|
|
# Chat-WebUI ist jetzt AnythingLLM (eigener Host), nicht mehr hermes-webui :8787.
|
|
"webui_url": ANYTHINGLLM_URL,
|
|
"gateway_reachable": _reach(HERMES_API_URL, "/health"),
|
|
"webui_reachable": _reach(ANYTHINGLLM_URL, "/api/ping"),
|
|
"home_exists": home.exists(),
|
|
"brain_model": brain_model,
|
|
# Best-effort: welche Verdrahtung lokal sichtbar ist (auf der Box aussagekräftig).
|
|
"has_config": (home / "config.yaml").exists() or (home / "config.json").exists(),
|
|
"has_skills": (home / "skills").exists(),
|
|
"has_memories": (home / "memories").exists(),
|
|
# Neue Felder: Telegram, MCP-Server-Anzahl, PC-Executor-Erreichbarkeit.
|
|
"telegram_enabled": bool(os.environ.get("TELEGRAM_BOT_TOKEN", "")),
|
|
"mcp_server_count": _count_enabled_mcp_servers(),
|
|
"pc_executor_reachable": _reach(PC_EXECUTOR_URL, "/health"),
|
|
}
|
|
|
|
|
|
def update_brain_model(new_model: str) -> bool:
|
|
from config import HERMES_HOME
|
|
home = HERMES_HOME
|
|
config_path = home / "config.yaml"
|
|
|
|
# Ensure home directory exists
|
|
home.mkdir(parents=True, exist_ok=True)
|
|
|
|
cfg = {}
|
|
if config_path.exists():
|
|
try:
|
|
from ruamel.yaml import YAML
|
|
r_yaml = YAML()
|
|
with config_path.open("r", encoding="utf-8") as f:
|
|
cfg = r_yaml.load(f) or {}
|
|
except Exception:
|
|
log.debug("update_brain_model: bestehende config.yaml nicht lesbar", exc_info=True)
|
|
cfg = {}
|
|
|
|
if not isinstance(cfg, dict):
|
|
cfg = {}
|
|
|
|
if "model" not in cfg or not isinstance(cfg["model"], dict):
|
|
cfg["model"] = {}
|
|
|
|
cfg["model"]["model"] = new_model
|
|
|
|
try:
|
|
from ruamel.yaml import YAML
|
|
r_yaml = YAML()
|
|
with config_path.open("w", encoding="utf-8") as f:
|
|
r_yaml.dump(cfg, f)
|
|
|
|
# Restart the user-space service to apply changes
|
|
try:
|
|
import services.maintenance as maintenance
|
|
maintenance.restart_service("hermes-gateway")
|
|
except Exception:
|
|
log.warning("update_brain_model: hermes-gateway-Restart fehlgeschlagen", exc_info=True)
|
|
|
|
return True
|
|
except Exception:
|
|
log.warning("update_brain_model: Schreiben der config.yaml fehlgeschlagen", exc_info=True)
|
|
return False
|