import type { Metadata } from 'next'; import Link from 'next/link'; import { Sparkline } from '@/components/charts'; import { ChangeRow } from '@/components/changes/change-row'; import { Methodology, TrustChip } from '@/components/intelligence/bits'; import { DataStrip, type StripItem } from '@/components/layout/terminal'; import { PriceMovers } from '@/components/prices/movers'; import { ChipRow } from '@/components/timeline/chip-row'; import { DataTable, EmptyRow, Td, Th } from '@/components/ui/data-table'; import { EntityLink } from '@/components/ui/entity'; import { Container, Note, PageHeader, Section } from '@/components/ui/section'; import { EmptyState, Unavailable } from '@/components/ui/unavailable'; import { api, intel, safe } from '@/lib/api'; import { fmtDate, fmtDateTime, fmtInt, fmtScore, fmtTokens, num } from '@/lib/format'; import { routes, SITE_NAME, SITE_URL } from '@/lib/site'; import type { ChangeEvent, EntitySummary, PulseLeaderItem } from '@/lib/types'; export const revalidate = 120; const WINDOWS = [7, 30, 90]; type SP = Record; const pickDays = (sp: SP) => (WINDOWS.includes(Number(sp.days)) ? Number(sp.days) : 7); const LABELS: Record = { new_models: 'New models', new_open_weight_models: 'New open-weight models', new_artifacts: 'New artifacts', new_papers: 'New papers', provider_listings: 'Provider listings', provider_delistings: 'Delistings', price_changes: 'Price changes', new_models_1m_context: 'New ≥ 1M-context models', new_benchmark_leaders: 'New benchmark leaders', documents_changed: 'Documents changed', sources_observed: 'Sources observed', events_total: 'Events total', }; const HREF: Record string> = { new_models: () => `${routes.changes()}?type=NEW_MODEL`, new_open_weight_models: () => `${routes.open()}`, new_papers: () => `${routes.papers()}?sort=published`, provider_listings: () => `${routes.changes()}?type=PROVIDER_LISTED`, provider_delistings: () => `${routes.changes()}?type=PROVIDER_DELISTED`, price_changes: () => `${routes.prices()}`, new_benchmark_leaders: () => routes.benchmarks(), documents_changed: () => `${routes.changes()}?type=DOCUMENT_CHANGED&include_documents=1`, sources_observed: () => routes.sources(), events_total: () => routes.changes(), }; /** stats/history series key per counter (only where the history payload carries one). */ const HISTORY_KEY: Record) => number | null> = { new_models: (c) => num((c.entities as Record | undefined)?.model), new_papers: (c) => num((c.entities as Record | undefined)?.paper), price_changes: (c) => num(c.prices_current), events_total: (c) => num(c.change_events), documents_changed: (c) => num(c.documents), sources_observed: (c) => num(c.sources), }; const TITLE = 'Ecosystem Pulse — what happened in AI this week'; const DESC = 'Deterministic counters over events that occurred in the window (7, 30 or 90 days) and are not back-filled history: new models, open-weight releases, artifacts, papers, provider listings and delistings, price changes, new 1M-context models, new benchmark leaders, documents and sources observed — each with its definition.'; export async function generateMetadata({ searchParams }: { searchParams: Promise }): Promise { const days = pickDays(await searchParams); const title = days === 7 ? TITLE : `Ecosystem Pulse — the last ${days} days in AI`; return { title, description: DESC, alternates: { canonical: routes.pulse() }, openGraph: { title: `${title} | ${SITE_NAME}`, description: DESC, url: `${SITE_URL}${routes.pulse()}`, type: 'website', siteName: SITE_NAME }, twitter: { card: 'summary_large_image', title, description: DESC }, robots: days !== 7 ? { index: false, follow: true } : undefined }; } const isLeader = (x: unknown): x is PulseLeaderItem => !!x && typeof x === 'object' && 'benchmark' in (x as object); const isEvent = (x: unknown): x is ChangeEvent => !!x && typeof x === 'object' && 'event_type' in (x as object); const isModel = (x: unknown): x is EntitySummary => !!x && typeof x === 'object' && 'entity_type' in (x as object) && 'slug' in (x as object); export default async function PulsePage({ searchParams }: { searchParams: Promise }) { const days = pickDays(await searchParams); const since = new Date(Date.now() - days * 86400000).toISOString().slice(0, 10); const [pulse, history, priceFallback, ctxFallback] = await Promise.all([safe(intel.pulse(days)), safe(api.statsHistory(Math.max(days, 14))), safe(api.changes({ type: 'PRICE_CHANGED', since, limit: 30 })), safe(api.models({ min_context: 1_000_000, sort: 'release', limit: 12 }))]); const href = (d: number) => (d === 7 ? routes.pulse() : `${routes.pulse()}?days=${d}`); if (!pulse) { return ( ); } const counters = pulse.counters ?? {}; const hist = history?.items ?? []; const spark = (key: string): number[] => { const f = HISTORY_KEY[key]; if (!f) return []; return hist.map((h) => f(h.counts as Record)).filter((v): v is number => v !== null); }; const strip: StripItem[] = Object.entries(counters).map(([key, c]) => { const vals = spark(key); return { label: LABELS[key] ?? key.replace(/_/g, ' '), value: fmtInt(c.value), definition: c.definition, href: HREF[key]?.(days), hint: vals.length >= 2 ? : num(c.median_percent) !== null ? `median ${fmtScore(c.median_percent)} %` : undefined, }; }); const leaders = (counters.new_benchmark_leaders?.items ?? []).filter(isLeader); const priceItems = (counters.price_changes?.items ?? []).filter(isEvent); const priceRows = priceItems.length ? priceItems : (priceFallback?.items ?? []); const ctxItems = (counters.new_models_1m_context?.items ?? []); const ctxModels: EntitySummary[] = ctxItems.filter(isModel); const ctxEvents: ChangeEvent[] = ctxItems.filter(isEvent); const historyDays = hist.length; const ld = { '@context': 'https://schema.org', '@type': 'Dataset', name: `AI Atlas Pulse · ${days} days`, description: DESC, url: `${SITE_URL}${routes.pulse()}`, temporalCoverage: `${pulse.since}/${pulse.until}`, creator: { '@type': 'Organization', name: SITE_NAME, url: SITE_URL } }; return (