import { useState } from "react" import { Bot, ExternalLink, Activity, Cpu, Wrench, Monitor, Shield, Check, X } from "lucide-react" import { api } from "@/lib/api" import { useAgentStatus, useModels, useQueryClient, qk } from "@/lib/queries" import { useDialog } from "@/lib/useDialog" import { cn, resolveExternalUrl } from "@/lib/utils" // Lane-/Gateway-Aliase, auf die das Hirn zeigen kann (Lane-Sprache statt altem „auto"). const ALIASES = ["chat", "coding", "fast", "heavy"] export function AgentView() { const { data: s, error: sErr } = useAgentStatus() const { data: modelsData } = useModels() const { showAlert, dialogElement } = useDialog() const qc = useQueryClient() const error = sErr ? String(sErr) : "" const [showBrainSelect, setShowBrainSelect] = useState(false) const installed = modelsData?.models ?? [] // Adressen aus dem Status-Payload statt hartcodiert — die UI zeigt, was konfiguriert IST. const port = (url?: string) => url?.match(/:(\d+)/)?.[1] ?? "" const gwPort = port(s?.gateway_url) || "8642" const pcUrl = s?.pc_executor_url ?? "" const pcHost = pcUrl.replace(/^https?:\/\//, "") const pcPort = port(pcUrl) || "7777" // Alias setzen → roher Config-Write (model.default zeigt aufs Alias). async function setBrainAlias(alias: string) { try { await api("/api/agent/brain", { method: "POST", body: JSON.stringify({ model: alias }) }) showAlert("Erledigt", `Hermes-Hirn zeigt jetzt auf das Alias '${alias}'. Der Gateway-Dienst wurde neu gestartet.`) qc.invalidateQueries({ queryKey: qk.agentStatus }) setShowBrainSelect(false) } catch (e: any) { showAlert("Fehler", `Wechsel fehlgeschlagen: ${e.message || e}`) } } // Installiertes Modell → warm-bewusst (hermes-Alias + brains-Gruppe + Config + Restart). async function setBrainWarm(modelName: string) { try { await api("/api/agent/brain/set", { method: "POST", body: JSON.stringify({ model_id: modelName }) }) showAlert("Erledigt", "Agent-Hirn gewechselt (warm gehalten). Gateway wurde neugestartet.") qc.invalidateQueries({ queryKey: qk.agentStatus }) qc.invalidateQueries({ queryKey: qk.models }) setShowBrainSelect(false) } catch (e: any) { showAlert("Fehler", `Wechsel fehlgeschlagen: ${e.message || e}`) } } return (
{/* Header */}

Hermes Agenten-Cockpit

Hermes ist ein autonomer Agent, der im Hintergrund der Box läuft (Port :{gwPort}) und seine eigene UI besitzt.

{s?.hermes_ui_url && ( Hermes-GUI öffnen )}
{error && (
Status nicht lesbar ({error}).
)} {s && (
{/* Agent-Fluss: Terminal → Gateway → Hirn / Verdrahtung / PC (ruhig, statt SVG-Graph) */}
Agent-Fluss
{/* Quelle: Terminal/Clients */}
{/* Gateway + nachgelagerte Module */}
{/* Agent Gateway */}
Agent Gateway :{gwPort} {s.gateway_reachable ? "online" : "offline"}
{/* Drei Module: Hirn (klickbar), Verdrahtung, PC */}
Verdrahtung
Config: {s.has_config ? "✓" : "—"} Skills: {s.has_skills ? "✓" : "—"} Memory: {s.has_memories ? "✓" : "—"}
PC
:{pcPort} {s.pc_executor_reachable ? "verbunden" : "offline"}
{/* PC Executor Status Card */}

PC Verbindung

{s.pc_executor_reachable ? "Erreichbar" : "Nicht verbunden"}

Der Hermes PC Executor läuft auf {pcHost || "deinem Windows-PC"} und ermöglicht Hermes den direkten Zugriff auf deinen Windows-PC — Shell-Befehle, Screenshots, Tastatureingaben.

Hermes erreicht den PC über den MCP-Server hermes-pc-control, der automatisch beim Gateway-Start verbunden wird.

{s.pc_executor_reachable ? (
PC Executor verbunden

Hermes kann jetzt per Telegram oder Terminal Befehle auf TobisNicerPC ausführen. Nutze pc_shell, pc_screenshot oder pc_open.

) : (

PC Executor starten

Starte start.bat im Ordner client\hermes-pc\ auf dem Windows-PC und lasse das Fenster offen.

client\hermes-pc\start.bat
)}
{/* Diagnostic Details if Offline */} {!s.gateway_reachable && (

Hermes-Agent Diagnostics

Der Hermes-Dienst ist auf der Box derzeit offline oder kann sich nicht mit dem lokalen llama-swap verbinden.

Am schnellsten: In der System-Schublade unter Dienste den Eintrag{" "} Hermes-Gateway mit einem Klick neu starten (dort gibt es auch die Logs dazu).

Weitere Einrichtungsdetails (Brain-Konfiguration, MCP-Kopplungen, SSH-Tunneling und Such-Engines) findest du in der Dokumentationsdatei: docs/HERMES_SETUP.md.

)}
)} {/* Brain Selection Modal — eine Stelle für den Hirn-Wechsel (warm-bewusst + Alias) */} {s && showBrainSelect && (

Hermes-Hirn konfigurieren

{/* Lane / Gateway-Alias */}
Lane / Gateway-Alias
{ALIASES.map((a) => { const cur = s.brain_model === a return ( ) })}

Schlank & flexibel: das Hirn folgt dem Lane-Routing (z.B. chat = fast↔heavy).

{/* Installierte Modelle (warm-bewusst) */}
Installiertes Modell (warm gehalten)
{installed.map((m) => { const isBrain = m.role === "hermes" return ( ) })}
💡 Für einen Agenten sind Hermes-Modelle (natives Tool-Calling) meist die robustere Wahl. Neues Modell? Erst über „Modell-Manager → Modelle finden" laden.
)} {dialogElement}
) }