import Link from 'next/link'; import type { ReactNode } from 'react'; import { cn } from '@/lib/cn'; import { fmtDate, fmtInt, fmtParams, fmtTokens, fmtUsdPerM, num } from '@/lib/format'; import { routes, typeLabel } from '@/lib/site'; import type { EntitySummary } from '@/lib/types'; import { EntityBadge, OpennessBadge, StatusBadge } from './badges'; export function EntityLink({ e, className, children }: { e: { entity_type: string; slug: string; name: string }; className?: string; children?: ReactNode }) { return ( {children ?? e.name} ); } /** Key attribute chips for a summary, type-aware (model: params · context · release; company: country; …). */ export function keyAttributes(e: EntitySummary): { label: string; value: string }[] { const a = e.attributes ?? {}; const out: { label: string; value: string }[] = []; const push = (label: string, value: string | null | undefined) => { if (value && value !== '—') out.push({ label, value }); }; switch (e.entity_type) { case 'model': case 'quantization': { const p = num(a.parameter_count); const ap = num(a.active_parameter_count); if (p !== null) push('params', ap !== null && ap !== p ? `${fmtParams(p)} (${fmtParams(ap)} active)` : fmtParams(p)); if (num(a.context_length) !== null) push('context', fmtTokens(a.context_length)); if (typeof a.release_date === 'string') push('released', fmtDate(a.release_date)); if (typeof a.license === 'string') push('license', a.license); break; } case 'company': case 'organization': case 'lab': case 'university': if (typeof a.country === 'string') push('country', a.country); if (a.founded) push('founded', String(a.founded).slice(0, 4)); if (typeof a.org_kind === 'string') push('kind', a.org_kind); break; case 'paper': if (typeof a.published_at === 'string') push('published', fmtDate(a.published_at)); if (Array.isArray(a.authors) && a.authors.length) push('authors', `${a.authors.length}`); if (typeof a.venue === 'string') push('venue', a.venue); if (typeof a.arxiv_id === 'string') push('arXiv', a.arxiv_id); break; case 'provider': if (Array.isArray(a.regions) && a.regions.length) push('regions', `${a.regions.length}`); break; case 'benchmark': if (typeof a.category === 'string') push('category', a.category); if (typeof a.metric === 'string') push('metric', a.metric); break; case 'hardware': case 'robot': if (typeof a.kind === 'string') push('kind', a.kind); if (num(a.memory_gb) !== null) push('memory', `${fmtInt(a.memory_gb)} GB`); if (num(a.memory_bandwidth_gbs) !== null) push('bandwidth', `${fmtInt(a.memory_bandwidth_gbs)} GB/s`); if (num(a.tdp_watts) !== null) push('TDP', `${fmtInt(a.tdp_watts)} W`); break; case 'framework': case 'library': case 'runtime': case 'repository': if (typeof a.latest_version === 'string') push('version', a.latest_version); if (typeof a.language === 'string') push('language', a.language); if (num(a['metric.stars']) !== null) push('stars', fmtInt(a['metric.stars'])); if (typeof a.license === 'string') push('license', a.license); break; case 'dataset': if (typeof a.modality === 'string') push('modality', a.modality); if (a.size) push('size', String(a.size)); if (typeof a.license === 'string') push('license', a.license); break; default: break; } return out.slice(0, 4); } export function cheapestPrice(e: EntitySummary): string | null { const a = e.attributes ?? {}; const v = num(a.min_input_per_mtok ?? a.best_input_per_mtok); return v === null ? null : fmtUsdPerM(v); } /** Dense list row: badge · name (link) · org · key attributes · quality. Used by search results, related, explore. */ export function EntityRow({ e, showType = true, trailing, className, showDescription = true }: { e: EntitySummary; showType?: boolean; trailing?: ReactNode; className?: string; showDescription?: boolean }) { const attrs = keyAttributes(e); const openness = typeof e.attributes?.openness === 'string' ? e.attributes.openness : null; return (
{e.description}
} {attrs.length > 0 && ({attrs.map((x) => ( {x.label} {x.value} ))}
)}