// Bottom telemetry strip. // All numeric values are DERIVED from real scenario data in the store — // no sine waves, no hardcoded SLA. The throughput sparkline plots the // "running" rollup over time (it changes only when state actually changes). // The "ui tick" dot is a UI heartbeat labelled as such. import { useEffect, useMemo, useState } from "react"; import { useApp, scenarioById } from "../state/store"; import { Pulse, Spark } from "./icons"; function Sparkline({ values, color, label }: { values: number[]; color: string; label: string }) { const w = 120, h = 28, pad = 2; if (!values.length) return ; const max = Math.max(...values, 1); const min = Math.min(...values, 0); const span = Math.max(1, max - min); const pts = values .map((v, i) => { const x = pad + ((w - pad * 2) * i) / Math.max(1, values.length - 1); const y = h - pad - ((v - min) / span) * (h - pad * 2); return `${x.toFixed(1)},${y.toFixed(1)}`; }) .join(" "); return ( ); } const HIST_LEN = 24; export default function Telemetry() { const scenarioId = useApp((s) => s.scenarioId); const scenarios = useApp((s) => s.scenarios); const mode = useApp((s) => s.mode); const sc = scenarioById(scenarioId); // Real rollup across every loaded scenario. const totals = useMemo(() => { let running = 0, errored = 0, cases = 0, done = 0; for (const s of scenarios) { for (const q of s.queue) { cases += 1; if (q.status === "running" || q.status === "waiting_for_user" || q.status === "waiting_for_agent") running += 1; else if (q.status === "errored" || q.status === "failed") errored += 1; else if (q.status === "completed" || q.status === "done") done += 1; } } return { running, errored, cases, done }; }, [scenarios]); // SLA = (non-errored queue items) / (queue items). Real, derived. const sla = totals.cases === 0 ? 1 : 1 - totals.errored / totals.cases; // Agent acceptance: across scenarios, fraction of agent runs not blocked/rejected. const agentRate = useMemo(() => { let total = 0, accepted = 0; for (const s of scenarios) { for (const a of s.agentRuns) { total += 1; if (a.status !== "proposed") accepted += 1; } } return total === 0 ? 1 : accepted / total; }, [scenarios]); // Sparkline = history of `running` totals. Updates only when totals change. const [history, setHistory] = useState(() => Array(HIST_LEN).fill(totals.running)); useEffect(() => { const t = setInterval(() => { setHistory((h) => [...h.slice(1), totals.running]); }, 1500); return () => clearInterval(t); }, [totals.running]); return (
running over time {totals.running} now
cases {totals.cases}
running {totals.running}
errored 0 ? "var(--block)" : "var(--text-2)" }}>{totals.errored}
sla (derived) {(sla * 100).toFixed(1)}%
agent acceptance (derived) {(agentRate * 100).toFixed(0)}%
scenario {sc?.family.label ?? "—"}
mode {mode === "live" ? "LIVE" : "SNAPSHOT"}
source EA2
); } function Gauge({ value, accent = "var(--run)" }: { value: number; accent?: string }) { const w = 60, h = 12; return (
); }