78448220b2
voice_metrics.py: neben den rollenden Stats jetzt ein echter Per-Turn-Trace (TurnTrace + Ringpuffer der letzten 60 Turns). Balken-Stufen zeitlich disjunkt (stt · vision · hirn · gen); hirn misst ab mark_brain_start() VOR dem Hermes- Request, damit die Vision-Zeit nicht doppelt gezaehlt wird. STT (davor) und Mem0-Retrieve (Rueckruf waehrend) werden per park()/_take_* best-effort dem Turn zugeordnet (Ein-Nutzer-Geraet, kein Turn-ID noetig). Mem0 = Unter-Detail INNERHALB hirn (nicht addieren) -> ehrlich, kein Doppelzaehlen. voice.py: TurnTrace in voice_chat's gen() (commit garantiert 1x via finally, auch bei Fehler/Abbruch). STT-Endpoint parkt seine Dauer. NEU: GET /api/voice/metrics (schliesst die Luecke - selbstkritik-feed.sh curlte das, existierte nie -> 404) + GET /api/voice/trace?limit=N. memory.py: GET /api/memory?q=... (= Hermes' Mem0-Prefetch) misst + parkt die Retrieve-Zeit. Frontend: LatencyCard (gestapelte Balken je Turn, "Taeter" = groesste Stufe, Fehler-Turns rot, Tooltip mit "davon Mem0 X s"), Query useVoiceTrace, in der Zentrale unter "Stack & Telemetrie". Lokal gegen Seed-Server verifiziert: 30,3-s- Haenger -> Hirn-Balken 94% + "davon Mem0 26,1 s". Grenzen (ehrlich, als Fussnote in der Karte): Tool-Runden im Hermes-LLM-Loop haben keinen Callback an MC2 -> stecken in "Antwort". Reine Telegram-Text-Turns laufen an MC2 vorbei und erscheinen hier nicht. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
56 lines
2.1 KiB
TypeScript
56 lines
2.1 KiB
TypeScript
import { SystemStatusCard } from "@/components/dashboard/SystemStatusCard"
|
|
import { UpdatesCard } from "@/components/dashboard/UpdatesCard"
|
|
import { AgentStatusCard } from "@/components/dashboard/AgentStatusCard"
|
|
import { MemoryInputCard } from "@/components/dashboard/MemoryInputCard"
|
|
import { TokenPerformanceCard } from "@/components/dashboard/TokenPerformanceCard"
|
|
import { ServicesCard } from "@/components/dashboard/ServicesCard"
|
|
import { LatencyCard } from "@/components/dashboard/LatencyCard"
|
|
import { ModelsCard } from "@/components/dashboard/ModelsCard"
|
|
import { LucyHealthCard } from "@/components/dashboard/LucyHealthCard"
|
|
|
|
function ZoneLabel({ children }: { children: React.ReactNode }) {
|
|
return <p className="mb-2 ml-0.5 text-[11px] font-semibold uppercase tracking-wider text-muted-foreground/60">{children}</p>
|
|
}
|
|
|
|
export function DashboardView() {
|
|
return (
|
|
<div className="space-y-7">
|
|
<div>
|
|
<h1 className="text-2xl font-space font-bold tracking-tight bg-gradient-to-r from-foreground via-foreground to-primary bg-clip-text text-transparent">
|
|
Zentrale
|
|
</h1>
|
|
<p className="text-sm text-muted-foreground">Aktueller Status von System, Modellen und Agent.</p>
|
|
</div>
|
|
|
|
{/* „Geht's Lucy gut?" — Klartext-Ampel + 1-Klick-Reparatur, ganz oben. */}
|
|
<LucyHealthCard />
|
|
|
|
{/* Hero-Banner — System, Durchsatz, Modelle (Rollen + warm + Inferenz in einer Karte) */}
|
|
<div className="grid items-stretch gap-6 lg:grid-cols-3">
|
|
<SystemStatusCard />
|
|
<TokenPerformanceCard />
|
|
<ModelsCard />
|
|
</div>
|
|
|
|
{/* Stack & Telemetrie */}
|
|
<section>
|
|
<ZoneLabel>Stack & Telemetrie</ZoneLabel>
|
|
<div className="grid gap-6 lg:grid-cols-2">
|
|
<ServicesCard />
|
|
<LatencyCard />
|
|
</div>
|
|
</section>
|
|
|
|
{/* Betrieb & Wissen */}
|
|
<section>
|
|
<ZoneLabel>Betrieb & Wissen</ZoneLabel>
|
|
<div className="grid gap-6 md:grid-cols-3">
|
|
<UpdatesCard />
|
|
<AgentStatusCard />
|
|
<MemoryInputCard />
|
|
</div>
|
|
</section>
|
|
</div>
|
|
)
|
|
}
|