SPB Git forge

spb/ai-atlas

Public
41commits 1branches 0releases
4.6 MBsize
maindefault branch
12 days agolast push
HTML 77.2% TypeScript 10.5% Python 9.6% JavaScript 2.5%
5.4 KB · 82 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import Link from 'next/link';3import { EntityBadge } from '@/components/ui/badges';4import { Container, Note, PageHeader, Section } from '@/components/ui/section';5import { Unavailable } from '@/components/ui/unavailable';6import { api, safe } from '@/lib/api';7import { fmtInt, num } from '@/lib/format';8import { routes, typeLabel } from '@/lib/site';9import { type BuilderOptions, QueryBuilder } from './builder';1011export const metadata: Metadata = { title: 'Explore — structured query builder and every entity type', description: 'Build a structured query over the AI Atlas graph (organization, family, parameters, context, licence, openness, modality, release year, status, reasoning) and browse every entity type with live counts.', alternates: { canonical: '/explore' } };12export const revalidate = 300;1314const BLURB: Record<string, string> = {15  model: 'Canonical model releases: parameters, context, openness, prices, benchmarks, lineage.',16  artifact: 'Checkpoints, quantisations, conversions and packagings of canonical models.',17  model_family: 'Families grouping canonical models (Llama 4, Qwen3, Claude…).',18  company: 'Labs and companies that develop, serve or study AI.',19  organization: 'Organizations, labs and universities.',20  paper: 'Research papers linked to the models and benchmarks they describe.',21  researcher: 'Authors of the papers in the atlas (name-only rows for now).',22  provider: 'Inference providers and their published prices per 1M tokens.',23  benchmark: 'Evaluation suites with results and configurations.',24  hardware: 'GPUs, accelerators and devices with memory and bandwidth specs.',25  framework: 'Training, inference and agent frameworks.',26  library: 'Libraries and SDKs.',27  dataset: 'Training and evaluation datasets.',28  license: 'Licences from the ontology with their permissions.',29  tool: 'Developer tools, agents and MCP servers.',30  repository: 'Code repositories linked to models and frameworks.',31};3233export default async function ExplorePage({ searchParams }: { searchParams: Promise<Record<string, string | undefined>> }) {34  const sp = await searchParams;35  const [types, models, benches] = await Promise.all([safe(api.exploreTypes()), safe(api.models({ limit: 1, facets: 1 })), safe(api.benchmarks())]);36  const items = (types?.items ?? []).slice().sort((a, b) => (num(b.count) ?? 0) - (num(a.count) ?? 0));37  const total = items.reduce((n, t) => n + (num(t.count) ?? 0), 0);38  const f = models?.facets ?? {};39  const options: BuilderOptions = {40    types: items.map((t) => ({ entity_type: t.entity_type, count: num(t.count) ?? 0, label: t.label })),41    organizations: (f.organizations ?? []).map((o) => ({ slug: o.slug, name: o.name, count: num(o.count) ?? 0 })),42    families: ((f.families ?? []) as { value: string; label?: string; count: unknown }[]).map((x) => ({ value: x.value, label: x.label ?? x.value, count: num(x.count) ?? 0 })),43    licenses: ((f.licenses ?? []) as { value: string; label?: string; count: unknown }[]).map((x) => ({ value: x.value, label: x.label ?? x.value, count: num(x.count) ?? 0 })),44    openness: (f.openness ?? []).map((x) => ({ value: x.value, count: num(x.count) ?? 0 })),45    modalities: (f.modalities ?? []).map((x) => ({ value: x.value, count: num(x.count) ?? 0 })),46    status: (f.status ?? []).map((x) => ({ value: x.value, count: num(x.count) ?? 0 })),47    benchmarks: (benches?.items ?? []).map((b) => ({ slug: b.slug, name: b.name })),48  };49  const initial: Record<string, string> = {};50  for (const [k, v] of Object.entries(sp)) if (typeof v === 'string' && v) initial[k] = v;5152  return (53    <Container wide>54      <PageHeader eyebrow="Explore" title="Query builder" lede="Pick a type, set the filters the API understands, run — or save the query and share its link. Option counts are live facets from the graph." aside={types ? <p className="tnum text-sm text-ink-3">{fmtInt(total)} entities</p> : undefined} />55      <div className="pb-6">{!types ? <Unavailable what="Entity types" /> : <QueryBuilder options={options} initial={initial} />}</div>56      <Section eyebrow="By type" title="The atlas by entity type" lede="Counts are live from the graph. Types without a dedicated section open a generic listing.">57        {!types ? (58          <Unavailable what="Entity types" />59        ) : (60          <ul className="grid border-l border-t border-rule sm:grid-cols-2 lg:grid-cols-4">61            {items.map((t) => (62              <li key={t.entity_type} className="border-b border-r border-rule">63                <Link href={routes.listing(t.entity_type)} className="flex h-full flex-col px-4 py-4 hover:bg-surface-2">64                  <div className="flex items-center justify-between">65                    <EntityBadge type={t.entity_type} />66                    <span className="tnum text-xl font-semibold tracking-tight">{fmtInt(t.count)}</span>67                  </div>68                  <p className="mt-2 text-sm font-medium">{t.label || typeLabel(t.entity_type, true)}</p>69                  <p className="mt-0.5 text-xs text-ink-2">{BLURB[t.entity_type] ?? `All ${typeLabel(t.entity_type, true).toLowerCase()} in the graph.`}</p>70                </Link>71              </li>72            ))}73          </ul>74        )}75        <Note className="mt-3">76          Prefer words? <Link href={routes.search('')} className="link">Search</Link> compiles plain English into these same filters and shows them back as chips.77        </Note>78      </Section>79    </Container>80  );81}82