import type { Metadata } from 'next'; import Link from 'next/link'; import { RailFilters } from '@/components/changes/rail-filters'; import { TerminalLayout } from '@/components/layout/terminal'; import { ActiveFilters } from '@/components/listing/filters'; import { BreadcrumbLd } from '@/components/meta/breadcrumb-ld'; import { Chip, EntityBadge } from '@/components/ui/badges'; import { DataTable, EmptyRow, Td, Th } from '@/components/ui/data-table'; import { EntityLink } from '@/components/ui/entity'; import { Hint } from '@/components/ui/hint'; import { Pagination, withParams } from '@/components/ui/pagination'; import { Container, Note, PageHeader } from '@/components/ui/section'; import { EmptyState, Unavailable } from '@/components/ui/unavailable'; import { api, safe } from '@/lib/api'; import { fmtDate, fmtInt } from '@/lib/format'; import { routes, SITE_NAME } from '@/lib/site'; import type { EntityDetail, EntitySummary } from '@/lib/types'; export const metadata: Metadata = { title: 'AI research papers — authors, models introduced, datasets, benchmarks', description: 'Research papers in the atlas with their authors, publication dates, arXiv categories and the models, datasets and benchmarks they are linked to — as stated by model cards and paper metadata.', alternates: { canonical: '/papers' } }; export const revalidate = 300; type SP = Record; const LIMIT = 25; const KEYS = ['q', 'category', 'org', 'since', 'until', 'sort', 'offset'] as const; const SORTS = [ { value: 'published', label: 'Recently published' }, { value: 'updated', label: 'Recently updated' }, { value: 'name', label: 'Title' }, ]; function str(v: unknown): string | null { return typeof v === 'string' && v.trim() ? v : null; } function list(v: unknown): string[] { return Array.isArray(v) ? v.filter((x) => x !== null && x !== undefined).map(String) : []; } type Linked = { models: EntitySummary[]; datasets: EntitySummary[]; benchmarks: EntitySummary[]; code: EntitySummary[] }; function linked(d: EntityDetail | null): Linked { const out: Linked = { models: [], datasets: [], benchmarks: [], code: [] }; if (!d) return out; const seen = new Set(); for (const g of d.relations ?? []) for (const it of g.items) { if (seen.has(it.id)) continue; seen.add(it.id); if (it.entity_type === 'model' || it.entity_type === 'artifact') out.models.push(it); else if (it.entity_type === 'dataset') out.datasets.push(it); else if (it.entity_type === 'benchmark') out.benchmarks.push(it); else if (['repository', 'framework', 'library'].includes(it.entity_type)) out.code.push(it); } return out; } export default async function PapersPage({ searchParams }: { searchParams: Promise }) { const sp = await searchParams; const current: Record = {}; for (const k of KEYS) if (sp[k]) current[k] = sp[k]; const offset = Math.max(0, Number(current.offset) || 0); const sort = current.sort ?? 'published'; const [page, orgs] = await Promise.all([safe(api.papers({ ...current, sort, limit: LIMIT, offset })), safe(api.companies({ limit: 40, sort: 'models' }))]); // "Introduces" needs each paper's relations: fetch the page's details in parallel (local API, ISR-cached). const details = page ? await Promise.all(page.items.map((p) => safe(api.entity(p.slug)))) : []; const href = (patch: Record) => withParams('/papers', current, patch); const cats = new Map(); for (const p of page?.items ?? []) for (const c of list(p.attributes?.categories)) cats.set(c, (cats.get(c) ?? 0) + 1); const activeCount = Object.keys(current).filter((k) => !['sort', 'offset'].includes(k)).length; const filters = ( o.slug === current.org).map((o) => ({ value: o.slug, label: o.name })), note: 'Stated publisher only — arXiv metadata carries no affiliation.' }, { kind: 'row', fields: [{ kind: 'date', name: 'since', label: 'Since', value: current.since }, { kind: 'date', name: 'until', label: 'Until', value: current.until }] }, { kind: 'select', name: 'sort', label: 'Sort', value: sort, any: SORTS[0]!.label, options: SORTS.slice(1) }, ]} /> ); const inspector = (

Categories on this page

{cats.size === 0 ? (

—

) : (
    {[...cats.entries()] .sort((a, b) => b[1] - a[1]) .slice(0, 16) .map(([c, n]) => (
  • {c} {n}
  • ))}
)}

“Introduces” lists the models whose cards cite the paper (described_by). Author names link to researcher pages when a record exists. Research graph →

); return ( <> {fmtInt(page.total)} papers

: undefined} className="pb-3"> href(p)} className="mt-3" />
{!page ? ( ) : page.items.length === 0 ? ( Try another title, category or organization. ) : ( <> Title Authors Organization Published Introduces Datasets Benchmarks Code {page.items.length === 0 && No rows.} {page.items.map((e, i) => { const a = e.attributes ?? {}; const authors = list(a.authors); const l = linked(details[i] ?? null); const code = str(a.code_url); const primary = str(a.primary_category); return ( {str(a.arxiv_id) && arXiv:{str(a.arxiv_id)}} {primary && ( {primary} )} {authors.length ? ( <> {authors.slice(0, 3).join(', ')} {authors.length > 3 && +{authors.length - 3}} ) : ( — )} {e.organization ? ( {e.organization.name} ) : str(a.venue) ? ( {str(a.venue)} ) : ( — )} {str(a.published_at) ? fmtDate(str(a.published_at)) : —} {l.models.length ? ( {l.models.slice(0, 3).map((m) => ( ))} {l.models.length > 3 && +{l.models.length - 3}} ) : details[i] === null ? ( unavailable ) : ( — )} {l.datasets.length ? l.datasets.slice(0, 2).map((x) => ) : —} {l.benchmarks.length ? l.benchmarks.slice(0, 2).map((x) => ) : —} {l.code.length ? ( l.code.slice(0, 2).map((x) => ) ) : code ? ( {code.replace(/^https?:\/\/(www\.)?/, '').slice(0, 32)} ) : ( — )} ); })} href({ offset: o || undefined })} className="mt-4" /> Author lists and categories are copied from the paper's own metadata (arXiv, publisher). Linked models, datasets, benchmarks and code come from stated relations only; a dash means no source stated one. )}
); }