"""/benchmarks · /benchmarks/{slug} · /benchmarks/{slug}/results · /benchmarks/{slug}/leaderboard · /benchmarks/{slug}/history · /benchmarks/{slug}/frontier · /benchmarks/matrix. API 1.1: results are organised in comparability GROUPS (canonical metric × config_key); leaderboards are ONE row per canonical model (best current row inside the chosen group); benchmarks resolve by slug, alias or id; every benchmark exposes `family`, `variant`, `metric`, `direction`, `groups`, `trust_mix`.""" from __future__ import annotations from collections import defaultdict from datetime import UTC, datetime from typing import Any from fastapi import APIRouter, Query, Request from aiatlas.api.common import ( PAGINATION, RESULT_COLS, RESULT_FROM, ApiError, Pagination, cached, csv, entity_summary, page, parse_ts, resolve_entity, resolve_id, result_row, ) from aiatlas.api.detail import leaderboard as legacy_leaderboard from aiatlas.api.routers.entities import detail_for_type from aiatlas.db import connection, fetch_all, fetch_val from aiatlas.ontology.benchmarks import TRUST_LABELS, comparability from aiatlas.services.frontier import ( all_primary_groups, benchmark_meta, frontier_series, group_rows, group_summary, leaderboard_rows, load_results, primary_group, rank_rows, ) router = APIRouter(prefix="/api/v1/benchmarks", tags=["benchmarks"]) GROUPING_NOTE = ("Rows are grouped by comparability group = canonical metric × config_key (hash of the task-defining configuration keys: variant, " "evaluator, harness, shots, pass regime…). A leaderboard shows one row per canonical model: its best current row inside the group. " "Reasoning effort, temperature or judge differences keep rows in the same group but mark them partially comparable.") async def _resolve_benchmark(conn: Any, slug: str) -> dict[str, Any]: return await resolve_entity(conn, slug, ("benchmark",), aliases=True) def _pick_group(groups: list[dict[str, Any]], attrs: dict[str, Any] | None, *, metric: str | None, config_key: str | None) -> dict[str, Any] | None: cands = groups if metric: m = metric.strip().lower() cands = [g for g in cands if g["metric"] == m or (g["metric"] or "").lower() == m] if config_key: cands = [g for g in cands if g["config_key"] == config_key] if metric or config_key: return max(cands, key=lambda g: (g["model_count"], g["n"])) if cands else None return primary_group(attrs, groups) # ------------------------------------------------------------------------------------------------------------------ listing @router.get("") @cached(300) async def list_benchmarks(request: Request, category: str | None = None) -> dict[str, Any]: async with connection() as conn: meta = await benchmark_meta(conn) rows = await load_results(conn) by_bench: dict[str, list[dict[str, Any]]] = defaultdict(list) for r in rows: by_bench[r["benchmark_id"]].append(r) items = [] for bid, m in meta.items(): if category and (m.get("category") or "").lower() != category.lower(): continue brows = by_bench.get(bid, []) groups = list(group_rows(brows).values()) pg = primary_group(m["attributes"], groups) leader = None second = None if pg: ranked = rank_rows(pg["rows"], pg["higher_is_better"]) if ranked: lb = leaderboard_rows(pg) leader = lb[0] if lb else None second = lb[1] if len(lb) > 1 else None trust_mix: dict[str, int] = defaultdict(int) for r in brows: trust_mix[r["trust_level"]] += 1 items.append({ "id": bid, "entity_type": "benchmark", "slug": m["slug"], "name": m["name"], "category": m.get("category"), "family": m.get("family"), "variant": m.get("variant"), "metric": m.get("metric"), "unit": m.get("unit"), "direction": m.get("direction"), "attributes": m["attributes"], "result_count": len(brows), "model_count": len({r["model_id"] for r in brows}), "leader": leader, "second": second, "top": {"model": leader["model"], "score": leader["score"]} if leader else None, "primary_group": group_summary(pg) if pg else None, "groups": sorted((group_summary(g) for g in groups), key=lambda g: (-g["model_count"], g["label"])), "trust_mix": dict(trust_mix), "trust_labels": {k: TRUST_LABELS.get(k, k) for k in trust_mix}, }) items.sort(key=lambda x: (-x["result_count"], x["name"])) return {"items": items, "total": len(items), "note": GROUPING_NOTE} @router.get("/matrix") @cached(300) async def matrix(request: Request, benchmarks: str | None = None, models: str | None = None, org: str | None = None, family: str | None = None, limit: int = Query(60, ge=1, le=300), comparable_only: int = Query(0, ge=0, le=1), min_cells: int = Query(3, ge=1, le=30), since: str | None = Query(None, description="model release_date ≥ YYYY-MM-DD"), until: str | None = Query(None, description="model release_date ≤ YYYY-MM-DD")) -> dict[str, Any]: """Rows = canonical models, columns = benchmarks, cell = best current score in the primary comparability group (+ trust, config_key, observed_at).""" from aiatlas.api.common import parse_date since_d, until_d = parse_date(since, "since"), parse_date(until, "until") async with connection() as conn: groups = await all_primary_groups(conn) meta = await benchmark_meta(conn) wanted_b: list[str] | None = None if benchmarks: wanted_b = [] for key in csv(benchmarks): b = await _resolve_benchmark(conn, key) wanted_b.append(b["id"]) wanted_m: set[str] | None = None if models: wanted_m = {await resolve_id(conn, k, ("model",)) or "" for k in csv(models)} if org: rows = await fetch_all(conn, "select e.id from entities e join entities o on o.id = e.organization_id where e.entity_type = 'model' and e.merged_into is null and (o.slug = :o or o.id = :o or o.canonical_name ilike :o)", o=org) wanted_m = (wanted_m or set()) | {r["id"] for r in rows} if family: rows = await fetch_all(conn, "select e.id from entities e left join entities f on f.id = e.family_id where e.entity_type = 'model' and e.merged_into is null and (f.slug = :f or f.id = :f or e.attributes->>'family' ilike :f)", f=family) wanted_m = (wanted_m or set()) | {r["id"] for r in rows} if wanted_b is None: wanted_b = [bid for bid, _ in sorted(groups.items(), key=lambda kv: -kv[1]["n"])[:12]] columns = [] cells: dict[str, dict[str, dict[str, Any]]] = defaultdict(dict) model_ref: dict[str, dict[str, Any]] = {} for bid in wanted_b: g = groups.get(bid) m = meta.get(bid) or {"id": bid, "slug": None, "name": None} columns.append({"id": bid, "slug": m.get("slug"), "name": m.get("name"), "category": m.get("category"), "metric": g["metric"] if g else m.get("metric"), "config_key": g["config_key"] if g else None, "group_label": g["label"] if g else None, "higher_is_better": g["higher_is_better"] if g else None, "n_models": g["model_count"] if g else 0}) if not g: continue leader_cfg = None ranked = rank_rows(g["rows"], g["higher_is_better"]) if ranked: leader_cfg = ranked[0] for r in ranked: if wanted_m is not None and r["model_id"] not in wanted_m: continue rel = str((r.get("model_attrs") or {}).get("release_date") or "")[:10] if (since_d or until_d) and (not rel or (since_d and rel < since_d.isoformat()) or (until_d and rel > until_d.isoformat())): continue level, _ = comparability(leader_cfg["config"] if leader_cfg else None, r.get("config"), leader_cfg["metric"] if leader_cfg else None, r.get("metric")) if leader_cfg else ("comparable", []) if comparable_only and level != "comparable": continue cells[r["model_id"]][bid] = {"score": r["score"], "rank": r["rank"], "trust_level": r["trust_level"], "config_key": r["config_key"], "comparability": level, "result_id": r["id"], "observed_at": r["observed_at"], "evaluated_at": r.get("evaluated_at")} model_ref.setdefault(r["model_id"], {"id": r["model_id"], "slug": r["model_slug"], "name": r["model_name"], "organization": r.get("org_name"), "organization_slug": r.get("org_slug"), "openness": (r.get("model_attrs") or {}).get("openness"), "release_date": (r.get("model_attrs") or {}).get("release_date")}) rows_out = [] for mid, c in cells.items(): if wanted_m is None and len(c) < min_cells: continue rows_out.append({"model": model_ref[mid], "cells": {bid: c.get(bid) for bid in wanted_b}, "n_cells": len(c), "mean_rank": round(sum(x["rank"] for x in c.values()) / len(c), 2)}) rows_out.sort(key=lambda x: (-x["n_cells"], x["mean_rank"], x["model"]["name"] or "")) return {"columns": columns, "rows": rows_out[:limit], "total_rows": len(rows_out), "comparable_only": bool(comparable_only), "min_cells": min_cells if wanted_m is None else None, "filters": {k: v for k, v in {"since": since, "until": until, "org": org, "family": family, "models": models}.items() if v}, "methodology": GROUPING_NOTE + " Each cell is the model's best current row in the benchmark's primary group; `mean_rank` is only a sort key, not a composite score."} # ------------------------------------------------------------------------------------------------------------------ one benchmark @router.get("/{slug}") @cached(300) async def get_benchmark(request: Request, slug: str) -> dict[str, Any]: async with connection() as conn: bench = await _resolve_benchmark(conn, slug) rows = await load_results(conn, benchmark_ids=[bench["id"]]) meta = (await benchmark_meta(conn, [bench["id"]])).get(bench["id"], {}) detail = await detail_for_type(bench["slug"], ("benchmark",)) groups = list(group_rows(rows).values()) pg = primary_group(bench.get("attributes"), groups) detail.update({"family": meta.get("family"), "variant": meta.get("variant"), "metric": meta.get("metric"), "direction": meta.get("direction"), "category": meta.get("category"), "groups": sorted((group_summary(g) for g in groups), key=lambda g: (-g["model_count"], g["label"])), "primary_group": group_summary(pg) if pg else None, "result_count": len(rows), "model_count": len({r["model_id"] for r in rows}), "leaderboard": leaderboard_rows(pg)[:25] if pg else [], "trust_mix": dict(defaultdict(int, {k: sum(1 for r in rows if r["trust_level"] == k) for k in {r["trust_level"] for r in rows}}))}) return detail @router.get("/{slug}/results") @cached(300) async def benchmark_results(request: Request, slug: str, p: Pagination = PAGINATION, config: str | None = Query(None, max_length=200), history: int = Query(0, ge=0, le=1), metric: str | None = Query(None, max_length=80), config_key: str | None = Query(None, max_length=40)) -> dict[str, Any]: """v1 behaviour (one row per result, sorted by score) + `metric=` and `config_key=` filters.""" async with connection() as conn: bench = await _resolve_benchmark(conn, slug) items = await legacy_leaderboard(conn, bench["id"], limit=p.limit, offset=p.offset, config=config, history=bool(history), metric=metric, config_key=config_key) where = "r.benchmark_id = :id" + ("" if history else " and r.valid_to is null") + (" and r.config::text ilike :cfg" if config else "") \ + (" and lower(r.metric) = lower(:metric)" if metric else "") + (" and r.config_key = :ck" if config_key else "") total = await fetch_val(conn, f"select count(*) from benchmark_results r where {where}", id=bench["id"], cfg=f"%{config}%" if config else None, metric=metric, ck=config_key) out = page(items, int(total or 0), p) out["benchmark"] = entity_summary(bench) return out @router.get("/{slug}/leaderboard") @cached(300) async def benchmark_leaderboard(request: Request, slug: str, metric: str | None = None, config_key: str | None = None, trust: str | None = None, org: str | None = None, since: str | None = None, until: str | None = None, comparable_only: int = Query(0, ge=0, le=1), limit: int = Query(100, ge=1, le=1000), offset: int = Query(0, ge=0)) -> dict[str, Any]: """ONE row per canonical model — best current row inside the chosen comparability group (default: primary group).""" since_ts, until_ts = parse_ts(since, "since"), parse_ts(until, "until") async with connection() as conn: bench = await _resolve_benchmark(conn, slug) rows = await load_results(conn, benchmark_ids=[bench["id"]]) closed = await load_results(conn, benchmark_ids=[bench["id"]], current_only=False) org_id = await resolve_id(conn, org) if org else None groups = list(group_rows(rows).values()) g = _pick_group(groups, bench.get("attributes"), metric=metric, config_key=config_key) if not g: return {"benchmark": entity_summary(bench), "group": None, "groups": [group_summary(x) for x in groups], "items": [], "total": 0, "note": "no current results in the requested group" if (metric or config_key) else "no current results for this benchmark"} trust_set = set(csv(trust)) if trust else None sel = [r for r in g["rows"] if (trust_set is None or r["trust_level"] in trust_set) and (org_id is None or r.get("organization_id") == org_id) and (since_ts is None or (r.get("evaluated_at") or r["observed_at"]) >= since_ts) and (until_ts is None or (r.get("evaluated_at") or r["observed_at"]) <= until_ts)] history_rows = [r for r in closed if r.get("valid_to") is not None and r["metric_canonical"] == g["metric"] and r["config_key"] == g["config_key"]] sub = {**g, "rows": sel} items = leaderboard_rows(sub, history_rows=history_rows or None, comparable_only=bool(comparable_only)) return {"benchmark": entity_summary(bench), "group": group_summary(g), "groups": sorted((group_summary(x) for x in groups), key=lambda x: (-x["model_count"], x["label"])), "items": items[offset:offset + limit], "total": len(items), "limit": limit, "offset": offset, "comparable_only": bool(comparable_only), "filters": {k: v for k, v in {"metric": metric, "config_key": config_key, "trust": trust, "org": org, "since": since, "until": until}.items() if v}, "history_available": bool(history_rows), "methodology": GROUPING_NOTE + " delta_rank compares with the ranking built from the closed (previous) rows of the same group."} @router.get("/{slug}/frontier") @cached(300) async def benchmark_frontier(request: Request, slug: str, metric: str | None = None, config_key: str | None = None) -> dict[str, Any]: """History of the leader per comparability group: a point each time a new best score appears (ordered by coalesce(evaluated_at, observed_at)).""" async with connection() as conn: bench = await _resolve_benchmark(conn, slug) rows = await load_results(conn, benchmark_ids=[bench["id"]], current_only=False) groups = list(group_rows(rows).values()) if metric or config_key: groups = [g for g in groups if (not metric or g["metric"] == metric.strip().lower()) and (not config_key or g["config_key"] == config_key)] pg = primary_group(bench.get("attributes"), groups) series = [] for g in sorted(groups, key=lambda x: (-x["model_count"], x["label"])): pts = frontier_series(g["rows"], g["higher_is_better"]) series.append({"group": group_summary(g), "primary": pg is not None and g["config_key"] == pg["config_key"] and g["metric"] == pg["metric"], "points": pts, "current_leader": pts[-1] if pts else None}) return {"benchmark": entity_summary(bench), "series": series, "generated_at": datetime.now(UTC), "methodology": "Includes closed rows (history). A point is emitted whenever a result beats every earlier result of the same group, " "ordered by evaluated_at when the source publishes it, else observed_at."} @router.get("/{slug}/history") @cached(300) async def benchmark_history(request: Request, slug: str, model: str | None = None, limit: int = Query(1000, ge=1, le=5000)) -> dict[str, Any]: async with connection() as conn: bench = await _resolve_benchmark(conn, slug) where = ["r.benchmark_id = :id"] params: dict[str, Any] = {"id": bench["id"], "lim": limit} if model: where.append("r.model_id = :model") params["model"] = await resolve_id(conn, model) rows = await fetch_all(conn, f"select {RESULT_COLS}, r.config_key, r.trust_level from {RESULT_FROM} where {' and '.join(where)} order by r.observed_at asc, r.id limit :lim", **params) items = [] for r in rows: it = result_row(r) it["config_key"], it["trust_level"] = r.get("config_key"), r.get("trust_level") items.append(it) return {"benchmark": entity_summary(bench), "items": items} __all__ = ["ApiError", "router"]