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:
Hitonabi
2026-06-27 00:01:36 +02:00
parent 6a464bf653
commit 0afddcdfdc
13 changed files with 546 additions and 455 deletions
+24 -8
View File
@@ -754,6 +754,11 @@ export function Cockpit() {
SLOTS: {m.parallel_slots}
</span>
)}
{m.incomplete && (
<span className="px-1.5 py-0.5 rounded bg-amber-500/10 border border-amber-500/20 text-[9px] font-mono text-amber-400 font-bold uppercase" title="GGUF-Datei fehlt — Modell kann nicht geladen werden">
Datei fehlt
</span>
)}
</div>
</div>
</div>
@@ -803,11 +808,14 @@ export function Cockpit() {
<div className="flex items-center gap-1.5 border-t border-border/20 pt-3 mt-auto">
<button
onClick={() => isRunning ? handleUnloadModel(m.name) : handleLoadModel(m.name)}
disabled={m.incomplete && !isRunning}
className={cn(
"flex-1 h-7 rounded-lg text-[9px] font-bold uppercase transition-all cursor-pointer border flex items-center justify-center gap-1",
isRunning
? "border-amber-500/30 bg-amber-500/5 hover:bg-amber-500/15 text-amber-400"
: "border-primary/30 bg-primary/5 hover:bg-primary/15 text-primary"
"flex-1 h-7 rounded-lg text-[9px] font-bold uppercase transition-all border flex items-center justify-center gap-1",
m.incomplete && !isRunning
? "border-border/30 bg-background/10 text-muted-foreground/50 cursor-not-allowed"
: isRunning
? "border-amber-500/30 bg-amber-500/5 hover:bg-amber-500/15 text-amber-400 cursor-pointer"
: "border-primary/30 bg-primary/5 hover:bg-primary/15 text-primary cursor-pointer"
)}
>
{isRunning ? "Entladen" : "Laden"}
@@ -889,6 +897,11 @@ export function Cockpit() {
SLOTS: {m.parallel_slots}
</span>
)}
{m.incomplete && (
<span className="px-1.5 py-0.5 rounded bg-amber-500/10 border border-amber-500/20 text-[8px] font-mono text-amber-400 font-bold uppercase shrink-0" title="GGUF-Datei fehlt">
Datei fehlt
</span>
)}
{isRunning && (
<span className="flex items-center gap-0.5 text-[8px] font-semibold text-emerald-400 uppercase tracking-wider shrink-0">
<span className="h-1.5 w-1.5 rounded-full bg-emerald-500 animate-pulse" /> warm
@@ -914,11 +927,14 @@ export function Cockpit() {
<div className="flex items-center gap-1.5">
<button
onClick={() => isRunning ? handleUnloadModel(m.name) : handleLoadModel(m.name)}
disabled={m.incomplete && !isRunning}
className={cn(
"h-7 px-3 rounded-lg text-[9px] font-bold uppercase transition-all cursor-pointer border flex items-center gap-1",
isRunning
? "border-amber-500/30 bg-amber-500/5 hover:bg-amber-500/15 text-amber-400"
: "border-primary/30 bg-primary/5 hover:bg-primary/15 text-primary"
"h-7 px-3 rounded-lg text-[9px] font-bold uppercase transition-all border flex items-center gap-1",
m.incomplete && !isRunning
? "border-border/30 bg-background/10 text-muted-foreground/50 cursor-not-allowed"
: isRunning
? "border-amber-500/30 bg-amber-500/5 hover:bg-amber-500/15 text-amber-400 cursor-pointer"
: "border-primary/30 bg-primary/5 hover:bg-primary/15 text-primary cursor-pointer"
)}
>
{isRunning ? "Entladen" : "Laden"}