import { ExternalLink } from 'lucide-react'; import Link from 'next/link'; import { Evidence } from '@/components/evidence/evidence'; import { ViewBeacon } from '@/components/layout/view-beacon'; import { ArtifactKindChip, OpennessChip } from '@/components/models/badges'; import { EntityBadge, StatusBadge } from '@/components/ui/badges'; import { EntityLink, QualityMark } from '@/components/ui/entity'; import { KeyValue, type KVRow } from '@/components/ui/key-value'; import { Container, Note } from '@/components/ui/section'; import { fmtAgo, fmtBytes, fmtDate, fmtGb, fmtInt, num } from '@/lib/format'; import { routes, SITE_NAME, SITE_URL } from '@/lib/site'; import type { ModelDetail } from '@/lib/types'; import { ProvenanceSummary, RelationsBlock, SourcesTable, TimelineList } from './blocks'; import { HardwareFitBlock } from './model-blocks'; /* Artifact page: a checkpoint / quantisation / conversion / packaging of a canonical model. Header points prominently to the canonical model; the artifact's own facts (file size, quant format, dtype, downloads, publisher) are shown with evidence. */ const FACT_KEYS = ['quant_format', 'quantization', 'weights_dtype', 'file_size_gb', 'metric.downloads', 'metric.likes', 'hf_repo', 'base_model', 'quantized_by', 'pipeline_tag', 'library_name', 'gated', 'access', 'license', 'release_date', 'last_modified', 'model_card_url', 'tags']; export function describeArtifact(d: ModelDetail): string { const a = d.attributes ?? {}; const bits: string[] = []; if (typeof a.quant_format === 'string') bits.push(String(a.quant_format).toUpperCase()); if (num(a.file_size_gb) !== null) bits.push(fmtGb(a.file_size_gb, 1)); if (num(a['metric.downloads']) !== null) bits.push(`${fmtInt(a['metric.downloads'])} downloads`); return `${d.name} is a ${d.artifact_kind ?? 'packaging'} of ${d.canonical?.name ?? 'a canonical model'}${d.organization ? ` published by ${d.organization.name}` : ''}${bits.length ? ` — ${bits.join(', ')}` : ''}. Not an independent model: parameters, benchmarks and prices live on the canonical model page. ${SITE_NAME}.`.slice(0, 300); } export function ArtifactPage({ d, canonical }: { d: ModelDetail; canonical: string }) { const a = d.attributes ?? {}; const entity = { name: d.name, entity_type: d.entity_type }; const format = typeof a.quant_format === 'string' ? String(a.quant_format).toUpperCase() : Array.isArray(a.weights_dtype) && a.weights_dtype.length ? (a.weights_dtype as string[]).join('/') : null; const rows: KVRow[] = FACT_KEYS.filter((k) => a[k] !== undefined && a[k] !== null && a[k] !== '' && !(Array.isArray(a[k]) && (a[k] as unknown[]).length === 0)).map((k) => ({ key: k, raw: a[k] })); const hf = typeof a.hf_repo === 'string' ? `https://huggingface.co/${a.hf_repo}` : typeof a.model_card_url === 'string' ? a.model_card_url : null; const ld = { '@context': 'https://schema.org', '@type': 'SoftwareSourceCode', name: d.name, url: `${SITE_URL}${canonical}`, description: d.description ?? describeArtifact(d), isBasedOn: d.canonical ? `${SITE_URL}${routes.entity(d.canonical)}` : undefined, publisher: d.organization ? { '@type': 'Organization', name: d.organization.name } : undefined, fileFormat: typeof a.quant_format === 'string' ? a.quant_format : undefined, contentSize: num(a.file_size_gb) !== null ? fmtBytes((num(a.file_size_gb) as number) * 1e9) : undefined, codeRepository: hf ?? undefined, }; const quants = Array.isArray(a.quantization) ? (a.quantization as string[]) : []; return (