import { Chip, TierBadge } from '@/components/ui/badges'; import { DataTable, Td, Th } from '@/components/ui/data-table'; import { EntityLink } from '@/components/ui/entity'; import { Note } from '@/components/ui/section'; import { cn } from '@/lib/cn'; import { fmtAgo, fmtDate, fmtScore, fmtUsdPerM, fmtValue, num } from '@/lib/format'; import { routes } from '@/lib/site'; import type { BenchmarkResult, CompareDimension, ComparePayload, Price, ProvenanceEntry } from '@/lib/types'; import { CompareButton } from './compare-button'; /* ------------------------------------------------------------------------------------------------------ helpers */ const PRICE_KEYS = new Set(['best_input_per_mtok', 'best_output_per_mtok', 'min_input_per_mtok', 'min_output_per_mtok']); /** Numeric dimensions where lower is better. */ function lowerIsBetter(key: string): boolean { return PRICE_KEYS.has(key) || /tdp|price|latency/.test(key); } function host(url: string | null | undefined): string | null { if (!url) return null; try { return new URL(url).hostname.replace(/^www\./, ''); } catch { return null; } } /** Compact per-cell provenance: T1 · host · 3 h ago (full text in title). */ function CellProvenance({ p }: { p: ProvenanceEntry }) { const h = p.source_name ?? host(p.url) ?? 'source'; return ( {p.url ? ( {h} ) : ( {h} )} · {fmtAgo(p.observed_at)} ); } function CellValue({ v, dim }: { v: unknown; dim: CompareDimension }) { if (v === null || v === undefined || v === '' || (Array.isArray(v) && v.length === 0)) return Unavailable; switch (dim.kind) { case 'date': return <>{fmtDate(String(v))}; case 'bool': return <>{v ? 'Yes' : 'No'}; case 'list': { const arr = Array.isArray(v) ? v : [v]; return ( {arr.map((x, i) => ( {typeof x === 'object' && x ? JSON.stringify(x) : String(x)} ))} ); } case 'number': if (PRICE_KEYS.has(dim.key)) return {fmtUsdPerM(v)}; return <>{fmtValue(v, dim.key)}; default: return <>{typeof v === 'string' ? v : fmtValue(v, dim.key)}; } } const STICKY = 'sticky left-0 z-10 bg-canvas'; /** First-column width: table layout ignores max-width, so set width + min-width explicitly. */ const FIRST = 'w-[9rem] min-w-[9rem] md:w-[12rem] md:min-w-[12rem]'; /** `.table-scroll td { white-space: nowrap }` out-specifies utilities — wrap the first column inline. */ const WRAP = { whiteSpace: 'normal' } as const; /** Horizontal scroll wrapper without the negative page margins (so the sticky column pins at the very left edge). */ function ScrollTable({ children, caption, className }: { children: React.ReactNode; caption: string; className?: string }) { return (
{children}
); } function EntityHead({ e }: { e: ComparePayload['items'][number]['entity'] }) { return ( {e.organization && {e.organization.name}} ); } /* ------------------------------------------------------------------------------------------------------ matrix */ /** Dimension × entity matrix: sticky first column, horizontal scroll, kind-aware formatting, per-cell provenance. */ export function CompareMatrix({ res }: { res: ComparePayload }) { return ( <> Dimension {res.items.map((it) => ( ))} {res.dimensions.map((dim) => { const nums = res.items.map((it) => num(it.values[dim.key])); const present = nums.filter((n): n is number => n !== null); const best = dim.kind === 'number' && present.length > 1 ? (lowerIsBetter(dim.key) ? Math.min(...present) : Math.max(...present)) : null; return ( {dim.label} {dim.unit && {dim.unit}} {res.items.map((it, i) => { const v = it.values[dim.key]; const p = it.provenance?.[dim.key]; const isBest = best !== null && nums[i] === best; return ( {p && } ); })} ); })} Bold marks the best number in a row (highest, or lowest for prices); it is not a verdict. Each value carries its own source and tier; hover a cell for the observation date. Missing values are shown as unavailable, never estimated. ); } /* ------------------------------------------------------------------------------------------------------ shared benchmarks */ function configSummary(c: Record): string { return Object.entries(c ?? {}) .filter(([, v]) => v !== null && v !== undefined && v !== '') .slice(0, 4) .map(([k, v]) => `${k}=${typeof v === 'object' ? JSON.stringify(v) : String(v)}`) .join(' · '); } /** Benchmarks with a current result for every compared model (best result per model per benchmark). */ export function SharedBenchmarks({ res }: { res: ComparePayload }) { const perItem = res.items.map((it) => { const m = new Map(); for (const r of it.results ?? []) { const prev = m.get(r.benchmark.slug); if (!prev || (r.higher_is_better === false ? r.score < prev.score : r.score > prev.score)) m.set(r.benchmark.slug, r); } return m; }); const first = perItem[0]; const shared = first ? [...first.values()].filter((r) => perItem.every((m) => m.has(r.benchmark.slug))) : []; const anyResults = res.items.some((it) => (it.results?.length ?? 0) > 0); if (shared.length === 0) return (

{anyResults ? 'No benchmark has a published result for every compared model.' : 'No benchmark results recorded for these models.'} Per-model results are on each model page (Benchmarks tab).

); shared.sort((a, b) => a.benchmark.name.localeCompare(b.benchmark.name)); return ( <> Benchmark {res.items.map((it) => ( ))} {shared.map((row) => { const cells = perItem.map((m) => m.get(row.benchmark.slug) ?? null); const scores = cells.map((c) => (c ? c.score : null)).filter((s): s is number => s !== null); const best = scores.length > 1 ? (row.higher_is_better === false ? Math.min(...scores) : Math.max(...scores)) : null; return ( {row.metric ?? '—'} {row.higher_is_better === false ? ' · lower is better' : ''} {cells.map((c, i) => ( {c ? ( <> {fmtScore(c.score)} {c.unit === '%' ? '%' : c.unit ? {c.unit} : ''} {configSummary(c.config) || (c.evaluated_at ? fmtDate(c.evaluated_at) : '')} ) : ( — )} ))} ); })} Only benchmarks with a result for every compared model are shown (best current result per model). Configurations may differ — hover a score for its config; scores under different configs are not strictly comparable. ); } /* ------------------------------------------------------------------------------------------------------ prices */ type Best = { input: number | null; output: number | null; observed: string; url: string | null; tier: number }; /** Provider × entity: cheapest current input / output per provider for each compared model. */ export function ComparePrices({ res }: { res: ComparePayload }) { const providers = new Map(); const perItem = res.items.map((it) => { const m = new Map(); for (const p of it.prices ?? []) { providers.set(p.provider.slug, p.provider); const cur = m.get(p.provider.slug) ?? { input: null, output: null, observed: p.observed_at, url: p.source_url, tier: p.tier }; const inp = num(p.input_per_mtok); const out = num(p.output_per_mtok); if (inp !== null && (cur.input === null || inp < cur.input)) cur.input = inp; if (out !== null && (cur.output === null || out < cur.output)) cur.output = out; if (p.observed_at > cur.observed) cur.observed = p.observed_at; m.set(p.provider.slug, cur); } return m; }); if (providers.size === 0) return

No current prices recorded for these models.

; const rows = [...providers.values()].sort((a, b) => a.name.localeCompare(b.name)); const bestOverall = res.items.map((_, i) => { let best: number | null = null; for (const b of perItem[i]!.values()) if (b.input !== null && (best === null || b.input < best)) best = b.input; return best; }); return ( <> Provider {res.items.map((it) => ( in / out per 1M ))} {rows.map((prov) => ( {perItem.map((m, i) => { const b = m.get(prov.slug); if (!b) return —; const cheapest = bestOverall[i] !== null && b.input === bestOverall[i]; return ( {fmtUsdPerM(b.input)} / {fmtUsdPerM(b.output)} {b.url ? ( {host(b.url)} ) : null} · {fmtAgo(b.observed)} ); })} ))} Cheapest current input / output price of each provider for each model, as published on the provider's pricing page (USD per 1M tokens). Bold = the model's cheapest provider. Full tables and history on each model page, or the price index. ); }