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 (
{fmtDate(pulse.since)} → {fmtDateTime(pulse.until)}
}>
Window
({ href: href(d), label: `${d} days`, active: days === d }))} />
All counters use is_backfill = false and occurred_at inside the window. Sparklines show the daily stats history where a series exists ({historyDays} day{historyDays === 1 ? '' : 's'} recorded so far{historyDays < 2 ? ' — a line needs two' : ''}).
{/* --------------------------------------------------------------------------------------------- leaders */}
{leaders.length === 0 ? (
The primary-group leader of every benchmark is unchanged over these {days} days.
) : (
) : num(counters.new_models_1m_context?.value) === 0 ? (
<>
{ctxFallback?.items.length ? <>For reference, the most recently released models with a sourced context of at least 1M tokens (any date):> : null}
{ctxFallback?.items.length ? (