'use client'; import { Columns3, ScanSearch } from 'lucide-react'; import Link from 'next/link'; import { createContext, type ReactNode, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react'; import { CompareButton } from '@/components/compare/compare-button'; import { TerminalLayout } from '@/components/layout/terminal'; import { StatusBadge } from '@/components/ui/badges'; import { EntityLink, QualityMark } from '@/components/ui/entity'; import { Sheet } from '@/components/ui/sheet'; import { WatchButton } from '@/components/watchlist/watch-button'; import { cn } from '@/lib/cn'; import { DASH, fmtDate, fmtInt, fmtParams, fmtTokens, fmtUsdPerM, num } from '@/lib/format'; import { routes, STATUS_LABELS } from '@/lib/site'; import type { ModelRow } from '@/lib/types'; import { ArtifactKindChip, IdentityBadge, OpennessChip } from './badges'; import { IDENTITY_LABEL, opennessLabel, rowPrice } from './shared'; /* /models terminal (client): shares the "inspected row" between the table (main pane) and the inspector (right pane / mobile sheet). The filter rail is a server-rendered node passed through untouched. Column visibility lives in localStorage['aia-models-cols']. */ type Ctx = { selected: ModelRow | null; select: (m: ModelRow | null, opts?: { sheet?: boolean }) => void }; const InspectCtx = createContext({ selected: null, select: () => undefined }); export const COLUMNS = [ { key: 'params', label: 'Params', num: true }, { key: 'context', label: 'Context', num: true }, { key: 'openness', label: 'Openness' }, { key: 'license', label: 'Licence' }, { key: 'release', label: 'Released' }, { key: 'price', label: 'Best price in / out', num: true }, { key: 'quality', label: 'Data quality', num: true }, ] as const; type ColKey = (typeof COLUMNS)[number]['key']; const COLS_KEY = 'aia-models-cols'; const DEFAULT_COLS: ColKey[] = ['params', 'context', 'openness', 'license', 'release', 'quality']; export function ModelsTerminal({ filters, filterCount, children, items }: { filters: ReactNode; filterCount: number; children: ReactNode; items: ModelRow[] }) { const [selected, setSelected] = useState(null); const [sheet, setSheet] = useState(false); const select = useCallback((m: ModelRow | null, opts?: { sheet?: boolean }) => { setSelected(m); if (m && opts?.sheet && typeof window !== 'undefined' && window.matchMedia('(max-width: 1023px)').matches) setSheet(true); }, []); // Default inspector target: the first row (so the pane is never empty when rows exist). const target = selected ?? items[0] ?? null; const value = useMemo(() => ({ selected, select }), [selected, select]); return ( } inspectorTitle="Inspector" storageKey="aia-models-inspector"> {children} setSheet(false)} side="bottom" eyebrow="Inspector" title={target?.name}> ); } /* ---------------------------------------------------------------------------------------------------------- inspector */ function Inspector({ m, placeholder }: { m: ModelRow | null; placeholder: boolean }) { if (!m) return

No row to inspect — adjust the filters.

; const a = m.attributes ?? {}; const p = num(a.parameter_count); const ap = num(a.active_parameter_count); const facts: { k: string; v: ReactNode }[] = [ { k: 'Parameters', v: p === null ? DASH : `${fmtParams(p)}${ap !== null && ap !== p ? ` · ${fmtParams(ap)} active` : ''}` }, { k: 'Context', v: num(a.context_length) === null ? DASH : `${fmtTokens(a.context_length)} tokens` }, { k: 'Max output', v: num(a.max_output_tokens) === null ? DASH : `${fmtTokens(a.max_output_tokens)} tokens` }, { k: 'Openness', v: opennessLabel(a.openness) }, { k: 'Licence', v: typeof a.license_key === 'string' ? a.license_key : typeof a.license === 'string' ? a.license : DASH }, { k: 'Released', v: typeof a.release_date === 'string' ? fmtDate(a.release_date) : DASH }, { k: 'Status', v: STATUS_LABELS[m.status] ?? m.status ?? DASH }, { k: 'Knowledge cutoff', v: typeof a.knowledge_cutoff === 'string' ? fmtDate(a.knowledge_cutoff) : DASH }, { k: 'Modalities', v: Array.isArray(a.modalities) && a.modalities.length ? (a.modalities as string[]).join(', ') : DASH }, { k: 'Family', v: m.family ? {m.family.name} : typeof a.family === 'string' ? a.family : DASH }, { k: 'Identity', v: m.identity_confidence ? IDENTITY_LABEL[m.identity_confidence] : DASH }, ]; const isArtifact = m.entity_type === 'artifact'; return (
{placeholder &&

Showing the first row — press “Inspect” on any row (or focus it and press Enter).

}

{isArtifact && }

{m.organization && ( {m.organization.name} )} {isArtifact && m.canonical && (

Packaging of — not an independent model.

)} {m.description &&

{m.description}

}
{facts.map((f) => (
{f.k}
{f.v}
))}

{m.quality?.score === undefined && 'Data quality not computed yet'}

Updated {fmtDate(m.updated_at)} · first seen {fmtDate(m.first_seen_at)}

{fmtInt(m.counts?.claims)} claims · {fmtInt(m.counts?.relations)} relations · {fmtInt(m.counts?.events)} events

Field-level provenance (source, tier, observed time) is on the model page — every value opens the evidence drawer there.

Open page → Graph
); } /* ---------------------------------------------------------------------------------------------------------- table */ export function ModelsTable({ items, sort, order, sortHref, orgHrefTemplate, offset }: { items: ModelRow[]; sort: string; order?: string; sortHref: Record; /** URL with `__ORG__` where the organization slug goes (functions cannot cross the server → client boundary). */ orgHrefTemplate: string; offset: number }) { const orgHref = (slug: string) => orgHrefTemplate.replace('__ORG__', encodeURIComponent(slug)); const { selected, select } = useContext(InspectCtx); const [cols, setCols] = useState(DEFAULT_COLS); const [ready, setReady] = useState(false); const [chooser, setChooser] = useState(false); const bodyRef = useRef(null); useEffect(() => { try { const raw = localStorage.getItem(COLS_KEY); if (raw) { const arr = JSON.parse(raw) as unknown; if (Array.isArray(arr)) setCols(COLUMNS.map((c) => c.key).filter((k) => (arr as string[]).includes(k))); } } catch { /* ignore */ } setReady(true); }, []); const toggleCol = (k: ColKey) => { setCols((cur) => { const next = cur.includes(k) ? cur.filter((x) => x !== k) : COLUMNS.map((c) => c.key).filter((x) => x === k || cur.includes(x)); try { localStorage.setItem(COLS_KEY, JSON.stringify(next)); } catch { /* ignore */ } return next; }); }; const show = (k: ColKey) => !ready || cols.includes(k); const onRowKey = (e: React.KeyboardEvent, m: ModelRow, i: number) => { if (e.key === 'ArrowDown' || e.key === 'ArrowUp') { e.preventDefault(); const rows = bodyRef.current?.querySelectorAll('tr[data-row]'); rows?.[i + (e.key === 'ArrowDown' ? 1 : -1)]?.focus(); } else if (e.key === 'Enter' || e.key === ' ' || e.key.toLowerCase() === 'i') { if ((e.target as HTMLElement).closest('a, button, input')) return; e.preventDefault(); select(m, { sheet: e.key !== 'i' }); } }; const SortTh = ({ s, children, num: n, hide }: { s: string; children: ReactNode; num?: boolean; hide?: boolean }) => hide ? null : ( {children} {sort === s && {order === 'asc' ? '↑' : '↓'}} ); return (
{chooser && (
{COLUMNS.map((c) => ( ))}

Saved in this browser.

)}
{/* ≥ md: the dense table scrolls horizontally inside its pane when needed (a scroll container offsets a sticky header, so the header stays static); < md rows stack. */}
Model Params Context {show('openness') && } {show('license') && } Released Best price in / out Data quality {items.length === 0 && ( )} {items.map((m, i) => { const a = m.attributes ?? {}; const p = num(a.parameter_count); const ap = num(a.active_parameter_count); const on = selected?.slug === m.slug; const isArtifact = m.entity_type === 'artifact'; const licence = typeof a.license_key === 'string' ? a.license_key : typeof a.license === 'string' ? a.license : null; const pin = rowPrice(a, 'input'); const pout = rowPrice(a, 'output'); return ( onRowKey(e, m, i)} onClick={(e) => { if ((e.target as HTMLElement).closest('a, button, input')) return; select(m); }} className={cn('cursor-default focus-visible:outline-2 focus-visible:outline-accent', on && 'bg-accent-soft/40')} > {show('params') && ( )} {show('context') && ( )} {show('openness') && ( )} {show('license') && ( )} {show('release') && ( )} {show('price') && ( )} {show('quality') && ( )} ); })}
Models
# OpennessLicence Actions
No models match these filters.
{fmtInt(offset + i + 1)}
{isArtifact && }
{m.organization && ( {m.organization.name} )} {m.family ? ( <> · {m.family.name} ) : typeof a.family === 'string' ? ( <> · {a.family} ) : null} {isArtifact && m.canonical && ( <> · of )}
{p === null ? {DASH} : fmtParams(p)} {ap !== null && ap !== p && {fmtParams(ap)} active} {num(a.context_length) === null ? {DASH} : fmtTokens(a.context_length)} {typeof a.openness === 'string' ? : {DASH}} {licence ? {licence} : {DASH}} {typeof a.release_date === 'string' ? fmtDate(a.release_date) : {DASH}} {pin === null && pout === null ? ( {DASH} ) : ( {fmtUsdPerM(pin)} / {fmtUsdPerM(pout)} )}
); }