import { useMemo } from 'react'; import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, } from 'recharts'; import type { MetricSnapshot, VariantFilter } from '../../lib/types'; interface TokenPanelProps { data: MetricSnapshot[]; variant: VariantFilter; height?: number; } interface ChartDataPoint { timestamp: number; time: string; // Single-variant keys token_rate_in?: number; token_rate_out?: number; token_rate_cache_read?: number; token_rate_cache_write?: number; // Both-variant keys (prod) token_rate_in_prod?: number; token_rate_out_prod?: number; token_rate_cache_read_prod?: number; token_rate_cache_write_prod?: number; // Both-variant keys (canary) token_rate_in_canary?: number; token_rate_out_canary?: number; token_rate_cache_read_canary?: number; token_rate_cache_write_canary?: number; } const COLORS = { input: '#06b6d4', // cyan output: '#8b5cf6', // purple cache_read: '#f59e0b', // amber cache_write: '#10b981', // emerald }; function formatTokenCount(n: number): string { if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(2)}M`; if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`; return n.toFixed(0); } const CustomTooltip = ({ active, payload, label, }: { active?: boolean; payload?: Array<{ name: string; value: number; color: string }>; label?: string; }) => { if (!active || !payload) return null; return (

{label}

{payload.map((entry, i) => (

{entry.name}: {entry.value.toFixed(0)} tok/s

))}
); }; /** Compute running totals over the visible window from cumulative counter values. */ function windowTotal(data: MetricSnapshot[], field: keyof MetricSnapshot): number { if (data.length < 2) return 0; const first = data[0][field] as number; const last = data[data.length - 1][field] as number; const delta = last - first; return delta >= 0 ? delta : last; // guard against counter resets } export function TokenPanel({ data, variant, height = 180 }: TokenPanelProps) { // Running totals over the visible window const totals = useMemo(() => { const filtered = variant === 'both' ? data : data.filter((s) => s.variant === variant); return { input: windowTotal(filtered, 'tokens_input'), output: windowTotal(filtered, 'tokens_output'), cache_read: windowTotal(filtered, 'tokens_cache_read'), cache_write: windowTotal(filtered, 'tokens_cache_write'), }; }, [data, variant]); // Duration label for the summary (window span in hours) const windowHours = useMemo(() => { if (data.length < 2) return null; const spanMs = data[data.length - 1].timestamp - data[0].timestamp; const hrs = spanMs / 3_600_000; return hrs >= 1 ? `${hrs.toFixed(0)}h` : `${Math.round(hrs * 60)}m`; }, [data]); const chartData = useMemo(() => { if (variant === 'both') { const grouped = new Map(); for (const s of data) { const pt = grouped.get(s.timestamp) ?? { timestamp: s.timestamp, time: new Date(s.timestamp).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false, }), }; if (s.variant === 'production') { pt.token_rate_in_prod = s.token_rate_in; pt.token_rate_out_prod = s.token_rate_out; pt.token_rate_cache_read_prod = s.token_rate_cache_read; pt.token_rate_cache_write_prod = s.token_rate_cache_write; } else { pt.token_rate_in_canary = s.token_rate_in; pt.token_rate_out_canary = s.token_rate_out; pt.token_rate_cache_read_canary = s.token_rate_cache_read; pt.token_rate_cache_write_canary = s.token_rate_cache_write; } grouped.set(s.timestamp, pt); } return Array.from(grouped.values()).sort((a, b) => a.timestamp - b.timestamp); } return data.map((s) => ({ timestamp: s.timestamp, time: new Date(s.timestamp).toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: false, }), token_rate_in: s.token_rate_in, token_rate_out: s.token_rate_out, token_rate_cache_read: s.token_rate_cache_read, token_rate_cache_write: s.token_rate_cache_write, })); }, [data, variant]); const yAxisFormatter = (v: number) => v >= 1000 ? `${(v / 1000).toFixed(1)}k` : v.toFixed(0); return (
{/* Header: title + running totals summary */}

Token Throughput

{windowHours && ( {windowHours} window )}
{/* Running totals grid */}
Input
{formatTokenCount(totals.input)}
Output
{formatTokenCount(totals.output)}
Cache↑
{formatTokenCount(totals.cache_read)}
Cache↓
{formatTokenCount(totals.cache_write)}
{/* Rate time series */} } /> {variant === 'both' ? ( <> ) : ( <> )}
); }