Show in-flight request count + activity spark on In-Flight Monitor key

The key now renders the live request count (large) when a model is active,
plus a 1Hz count-trend sparkline of the last 60s in a bottom strip. IDLE/
LOADING/OFF/OFFLINE states unchanged. History lives in per-key state with
a sampler cleared on disappear.
This commit is contained in:
2026-08-14 11:20:51 -06:00
parent 38c4c7eccd
commit 6053713020
3 changed files with 75 additions and 8 deletions
+35 -5
View File
@@ -20,6 +20,7 @@ export interface InflightRenderOptions {
count: number;
offline: boolean;
pulse: boolean;
history?: number[];
}
export function renderInflight(opts: InflightRenderOptions): string {
@@ -46,13 +47,26 @@ export function renderInflight(opts: InflightRenderOptions): string {
const isActive = opts.state === "ready" && opts.count > 0;
const bg = opts.state === "ready" ? (isActive ? "#8b2626" : "#1e6b34") : opts.state === "loading" ? "#8a6d1d" : "#3a3a3a";
const label = opts.state === "ready" ? (isActive ? "ACTIVE" : "IDLE") : opts.state === "loading" ? "LOADING" : "OFF";
const center = isActive ? `${opts.count}` : opts.state === "ready" ? "IDLE" : opts.state === "loading" ? "LOADING" : "OFF";
const centerSize = isActive ? 24 : 16;
const opacity = isActive && opts.pulse ? 0.55 : 1;
return frame(bg, [
centerText(label, 38, 18, "bold", "#ffffff", opacity),
centerText(name, 64, 7, "normal", "#ffffff"),
]);
const parts: string[] = [
centerText(name, 12, 7, "normal", "#ffffff"),
centerText(center, 40, centerSize, "bold", "#ffffff", opacity),
];
if (opts.state === "ready") {
const points = inflightSparkPoints(opts.history ?? []);
if (points.length > 1) {
parts.push(
`<path d="M ${points.map((p) => `${p.x},${p.y}`).join(" L ")} L ${points[points.length - 1].x},63 L ${points[0].x},63 Z" fill="#ffffff" opacity="0.18"/>`,
`<polyline points="${points.map((p) => `${p.x},${p.y}`).join(" ")}" fill="none" stroke="#ffffff" stroke-width="1.5" stroke-linejoin="round" stroke-linecap="round" opacity="0.8"/>`,
);
}
}
return frame(bg, parts);
}
export interface GpuGraphRenderOptions {
@@ -132,6 +146,22 @@ function chartPoints(history: number[], metric: GpuMetricKind): { x: number; y:
});
}
function inflightSparkPoints(history: number[]): { x: number; y: number }[] {
const n = history.length;
if (n === 0) return [];
const left = 4;
const right = 68;
const top = 50;
const bottom = 63;
const yMax = Math.max(...history, 1);
return history.map((v, i) => {
const x = n === 1 ? (left + right) / 2 : left + ((right - left) * i) / (n - 1);
const clamped = Math.max(0, Math.min(v, yMax));
const y = bottom - (clamped / yMax) * (bottom - top);
return { x: round1(x), y: round1(y) };
});
}
function yScaleMax(metric: GpuMetricKind, history: number[]): number {
if (metric !== "power") return 100;
const maxValue = Math.max(...history);