Feat: UI-Audit — Telegram/MCP/PC-Status, incomplete-Badge, SSH-Karte ersetzt
- backend: PC_EXECUTOR_URL Env-Var + 3 neue agent_status()-Felder (telegram_enabled, mcp_server_count, pc_executor_reachable) - AgentStatusCard: 2x2-Grid (Gateway/WebUI/Gehirn/Verdrahtung) + echte Status-Footer-Zeilen fuer Telegram, MCP-Server-Anzahl, PC - TokenStatsCard: 'Juni 2026' entfernt, Null-Fallback fuer pricing - AgentView: SSH-Bypass-Karte ersetzt durch PC-Executor-Statuskarte - Cockpit + RolesCard: Datei-fehlt-Badge + Load-Button disabled fuer incomplete-Modelle - api.ts: AgentStatus-Interface um 3 neue Felder erweitert Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { useState } from "react"
|
||||
import { Bot, ExternalLink, Cpu, Layers, X, Check } from "lucide-react"
|
||||
import { Bot, ExternalLink, Cpu, Layers, Wrench, X, Check } from "lucide-react"
|
||||
import { api } from "@/lib/api"
|
||||
import { useAgentStatus, useModels, useQueryClient, qk } from "@/lib/queries"
|
||||
import { useDialog } from "@/lib/useDialog"
|
||||
@@ -51,37 +51,43 @@ export function AgentStatusCard() {
|
||||
</div>
|
||||
|
||||
{agent ? (
|
||||
<div className="space-y-3">
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="p-3 bg-background/20 rounded-xl border border-border/40">
|
||||
<div className="text-[10px] text-muted-foreground uppercase font-semibold">Gateway</div>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<span className={cn("h-2 w-2 rounded-full", agent.gateway_reachable ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
|
||||
<span className="text-xs font-medium">{agent.gateway_reachable ? "Online" : "Offline"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-background/20 rounded-xl border border-border/40">
|
||||
<div className="text-[10px] text-muted-foreground uppercase font-semibold">WebUI</div>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<span className={cn("h-2 w-2 rounded-full", agent.webui_reachable ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
|
||||
<span className="text-xs font-medium">{agent.webui_reachable ? "Online" : "Offline"}</span>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div className="p-3 bg-background/20 rounded-xl border border-border/40">
|
||||
<div className="text-[10px] text-muted-foreground uppercase font-semibold">Gateway</div>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<span className={cn("h-2 w-2 rounded-full", agent.gateway_reachable ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
|
||||
<span className="text-xs font-medium">{agent.gateway_reachable ? "Online" : "Offline"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-background/20 rounded-xl border border-border/40">
|
||||
<div className="text-[10px] text-muted-foreground uppercase font-semibold">WebUI</div>
|
||||
<div className="flex items-center gap-2 mt-1">
|
||||
<span className={cn("h-2 w-2 rounded-full", agent.webui_reachable ? "bg-emerald-500 animate-pulse" : "bg-amber-500")} />
|
||||
<span className="text-xs font-medium">{agent.webui_reachable ? "Online" : "Offline"}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
onClick={() => setShowBrainSelect(true)}
|
||||
className="p-3 bg-background/20 rounded-xl border border-border/40 hover:border-primary/45 hover:bg-background/30 transition-all duration-300 cursor-pointer group"
|
||||
className="p-3 bg-background/20 rounded-xl border border-border/40 hover:border-primary/45 hover:bg-background/30 transition-all duration-300 cursor-pointer"
|
||||
>
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-[10px] text-muted-foreground uppercase font-semibold">Aktives Gehirn</span>
|
||||
<button className="flex items-center gap-1 text-[9px] font-bold uppercase tracking-wider text-primary border border-primary/20 bg-primary/10 hover:bg-primary/20 px-1.5 py-0.5 rounded transition-all cursor-pointer font-space">
|
||||
<Cpu className="h-3 w-3" /> Ändern
|
||||
</button>
|
||||
<span className="text-[10px] text-muted-foreground uppercase font-semibold">Gehirn</span>
|
||||
<Cpu className="h-3 w-3 text-primary" />
|
||||
</div>
|
||||
<div className="text-xs font-medium mt-1 font-mono text-primary flex items-center gap-1.5">
|
||||
<Layers className="h-3.5 w-3.5" />
|
||||
{agent.brain_model ? `model: ${agent.brain_model}` : "model: auto"}
|
||||
<div className="text-xs font-medium mt-1 font-mono text-primary truncate flex items-center gap-1">
|
||||
<Layers className="h-3 w-3 shrink-0" />
|
||||
{agent.brain_model || "auto"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="p-3 bg-background/20 rounded-xl border border-border/40">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-[10px] text-muted-foreground uppercase font-semibold">Verdrahtung</span>
|
||||
<Wrench className="h-3 w-3 text-primary" />
|
||||
</div>
|
||||
<div className="text-[10px] font-mono mt-1 space-y-0.5 text-muted-foreground">
|
||||
<div>Config: {agent.has_config ? <span className="text-emerald-400">✓</span> : "—"}</div>
|
||||
<div>Skills: {agent.has_skills ? <span className="text-emerald-400">✓</span> : "—"}</div>
|
||||
<div>Memory: {agent.has_memories ? <span className="text-emerald-400">✓</span> : "—"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -89,9 +95,26 @@ export function AgentStatusCard() {
|
||||
<div className="h-28 flex items-center justify-center text-xs text-muted-foreground">Lade Agenten-Status…</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-3 text-[10px] text-muted-foreground/80 border-t border-border/30 pt-3">
|
||||
Gedächtnis & Stack-Tools via MCP gekoppelt.
|
||||
</div>
|
||||
{agent && (
|
||||
<div className="mt-3 border-t border-border/30 pt-3 space-y-1.5">
|
||||
<div className="flex items-center justify-between text-[10px] text-muted-foreground">
|
||||
<span>Telegram</span>
|
||||
<span className={cn("font-semibold", agent.telegram_enabled ? "text-emerald-400" : "")}>
|
||||
{agent.telegram_enabled ? "aktiv" : "nicht konfiguriert"}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-[10px] text-muted-foreground">
|
||||
<span>MCP-Server</span>
|
||||
<span className="font-semibold text-foreground">{agent.mcp_server_count ?? 0} verbunden</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-between text-[10px] text-muted-foreground">
|
||||
<span>PC Executor</span>
|
||||
<span className={cn("font-semibold", agent.pc_executor_reachable ? "text-emerald-400" : "")}>
|
||||
{agent.pc_executor_reachable ? "erreichbar" : "nicht verbunden"}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{agent && showBrainSelect && (
|
||||
<div className="fixed inset-0 z-50 bg-black/60 backdrop-blur-sm flex items-center justify-center p-4">
|
||||
|
||||
@@ -68,6 +68,11 @@ export function RolesCard() {
|
||||
SLOTS: {m.parallel_slots}
|
||||
</span>
|
||||
)}
|
||||
{m.incomplete && (
|
||||
<span className="text-[7px] leading-none font-mono font-bold bg-amber-500/10 text-amber-400 border border-amber-500/20 px-1 py-0.5 rounded" title="GGUF-Datei fehlt">
|
||||
⚠ fehlt
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -51,9 +51,9 @@ export function TokenStatsCard() {
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 text-[9px] text-muted-foreground/70 border-t border-border/30 pt-2.5 leading-normal">
|
||||
Berechnet im Vergleich zu Cloud-APIs von Juni 2026
|
||||
Berechnet ggü. Cloud-APIs
|
||||
{tokenStats?.pricing?.heavy
|
||||
? ` (Ø ${tokenStats.pricing.heavy.in.toFixed(2).replace(".", ",")} $ / ${tokenStats.pricing.heavy.out.toFixed(2).replace(".", ",")} $ pro 1M tkn).`
|
||||
? ` (Ø ${(tokenStats.pricing.heavy.in ?? 0).toFixed(2).replace(".", ",")} $ / ${(tokenStats.pricing.heavy.out ?? 0).toFixed(2).replace(".", ",")} $ pro 1M tkn).`
|
||||
: "."}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user