Spaces:
Running
Route peer-ranks fetch through SNAPSHOT_URL sidecar
Browse filesThe model-detail benchmark grid was hardcoded to fetch
peer-ranks.json from the dataset *root* on `main`. The rest of
the app reads from the pinned `SNAPSHOT_URL=warehouse/<id>/`
snapshot, so peer ranks could drift from the views they were
paired with — different eval IDs, totals, or models than the
comparison-index showed.
The producer now emits peer-ranks.json as a Stage J sidecar
(eval_cards_backend_pipeline ffbfe71). Add `fetchPeerRanks()` to
`lib/sidecars.ts` (unwraps the new `{generated_at, ranks}`
envelope; gracefully returns `{}` for older snapshots that 404),
expose it through `lib/hf-data.ts` + `/api/peer-ranks` +
`dashboard-data-client.ts`, and switch `loadPeerRanks()` in
benchmark-detail.tsx off the hardcoded URL.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- app/api/peer-ranks/route.ts +22 -0
- components/benchmark-detail.tsx +9 -8
- lib/backend-artifacts.ts +20 -0
- lib/dashboard-data-client.ts +11 -1
- lib/hf-data.ts +14 -0
- lib/sidecars.ts +27 -0
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { NextResponse } from "next/server"
|
| 2 |
+
|
| 3 |
+
import { fetchPeerRanks } from "@/lib/hf-data"
|
| 4 |
+
|
| 5 |
+
export async function GET() {
|
| 6 |
+
try {
|
| 7 |
+
const ranks = await fetchPeerRanks()
|
| 8 |
+
return NextResponse.json(ranks, {
|
| 9 |
+
headers: {
|
| 10 |
+
// Per-snapshot file, recomputed by the producer per pipeline run.
|
| 11 |
+
// Hot-cache aggressively in the browser; HF's own CDN handles
|
| 12 |
+
// dataset-side caching for us.
|
| 13 |
+
"Cache-Control": "public, max-age=600, stale-while-revalidate=3600",
|
| 14 |
+
},
|
| 15 |
+
})
|
| 16 |
+
} catch (err) {
|
| 17 |
+
return NextResponse.json(
|
| 18 |
+
{ error: err instanceof Error ? err.message : "failed to load peer ranks" },
|
| 19 |
+
{ status: 500 }
|
| 20 |
+
)
|
| 21 |
+
}
|
| 22 |
+
}
|
|
@@ -47,8 +47,10 @@ import type {
|
|
| 47 |
ComparisonMetricEntry,
|
| 48 |
ComparisonScoreEntry,
|
| 49 |
EvalHierarchy,
|
|
|
|
| 50 |
SubmissionAxis,
|
| 51 |
} from "@/lib/backend-artifacts"
|
|
|
|
| 52 |
import {
|
| 53 |
buildHierarchyEvalIndex,
|
| 54 |
type HierarchyEvalLocation,
|
|
@@ -1371,18 +1373,17 @@ function getGroupPeerRank(
|
|
| 1371 |
return best ?? (group.bestRankPosition != null ? { position: group.bestRankPosition, total: group.bestRankTotal ?? 0 } : null)
|
| 1372 |
}
|
| 1373 |
|
| 1374 |
-
|
| 1375 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1376 |
let peerRanksPromise: Promise<PeerRanksMap> | null = null
|
| 1377 |
|
| 1378 |
-
const DATASET_PEER_RANKS_URL =
|
| 1379 |
-
"https://huggingface.co/datasets/evaleval/card_backend/resolve/main/peer-ranks.json"
|
| 1380 |
-
|
| 1381 |
function loadPeerRanks(): Promise<PeerRanksMap> {
|
| 1382 |
if (!peerRanksPromise) {
|
| 1383 |
-
peerRanksPromise =
|
| 1384 |
-
.then((r) => (r.ok ? r.json() : {}))
|
| 1385 |
-
.catch(() => ({}))
|
| 1386 |
}
|
| 1387 |
return peerRanksPromise
|
| 1388 |
}
|
|
|
|
| 47 |
ComparisonMetricEntry,
|
| 48 |
ComparisonScoreEntry,
|
| 49 |
EvalHierarchy,
|
| 50 |
+
PeerRanksMap,
|
| 51 |
SubmissionAxis,
|
| 52 |
} from "@/lib/backend-artifacts"
|
| 53 |
+
import { fetchPeerRanks } from "@/lib/dashboard-data-client"
|
| 54 |
import {
|
| 55 |
buildHierarchyEvalIndex,
|
| 56 |
type HierarchyEvalLocation,
|
|
|
|
| 1373 |
return best ?? (group.bestRankPosition != null ? { position: group.bestRankPosition, total: group.bestRankTotal ?? 0 } : null)
|
| 1374 |
}
|
| 1375 |
|
| 1376 |
+
// peer-ranks.json now ships as a sidecar inside the pinned `SNAPSHOT_URL`
|
| 1377 |
+
// snapshot (Stage J emits it alongside hierarchy.json / comparison-index.json
|
| 1378 |
+
// — see eval_cards_backend_pipeline commit ffbfe71). Routing through the
|
| 1379 |
+
// same `/api/peer-ranks` endpoint as the other sidecars keeps peer ranks
|
| 1380 |
+
// pinned to the snapshot the rest of the page is reading from, instead of
|
| 1381 |
+
// drifting to the unversioned `main`-branch copy at the dataset root.
|
| 1382 |
let peerRanksPromise: Promise<PeerRanksMap> | null = null
|
| 1383 |
|
|
|
|
|
|
|
|
|
|
| 1384 |
function loadPeerRanks(): Promise<PeerRanksMap> {
|
| 1385 |
if (!peerRanksPromise) {
|
| 1386 |
+
peerRanksPromise = fetchPeerRanks().catch(() => ({} as PeerRanksMap))
|
|
|
|
|
|
|
| 1387 |
}
|
| 1388 |
return peerRanksPromise
|
| 1389 |
}
|
|
@@ -467,3 +467,23 @@ export interface ComparisonIndex {
|
|
| 467 |
evals: Record<string, ComparisonEvalEntry>
|
| 468 |
by_model: Record<string, Record<string, Record<string, ComparisonByModelEntry>>>
|
| 469 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 467 |
evals: Record<string, ComparisonEvalEntry>
|
| 468 |
by_model: Record<string, Record<string, Record<string, ComparisonByModelEntry>>>
|
| 469 |
}
|
| 470 |
+
|
| 471 |
+
// ---------------------------------------------------------------------------
|
| 472 |
+
// peer-ranks.json — primary-metric peer rank per (eval, model)
|
| 473 |
+
// ---------------------------------------------------------------------------
|
| 474 |
+
|
| 475 |
+
/** Bare map shape consumed by the model-detail benchmark grid. */
|
| 476 |
+
export type PeerRanksMap = Record<
|
| 477 |
+
string,
|
| 478 |
+
Record<string, { position: number; total: number }>
|
| 479 |
+
>
|
| 480 |
+
|
| 481 |
+
/** Wrapped sidecar payload emitted by the v2 producer. Older (unversioned)
|
| 482 |
+
* publishings of peer-ranks.json at the dataset root were a bare map; the
|
| 483 |
+
* v2 snapshot wraps it with the same `{generated_at, config_version, ...}`
|
| 484 |
+
* envelope as the other sidecars. */
|
| 485 |
+
export interface PeerRanksSidecar {
|
| 486 |
+
generated_at: string
|
| 487 |
+
config_version: number
|
| 488 |
+
ranks: PeerRanksMap
|
| 489 |
+
}
|
|
@@ -1,4 +1,10 @@
|
|
| 1 |
-
import type {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
import { decorateHierarchyDerivedTags } from "@/lib/benchmark-tags"
|
| 3 |
import type { BenchmarkEvaluationCardData } from "@/components/benchmark-evaluation-card"
|
| 4 |
import type { HFEvalDetail } from "@/lib/hf-data"
|
|
@@ -104,3 +110,7 @@ export function fetchComparisonIndex() {
|
|
| 104 |
export function fetchCorpusAggregates() {
|
| 105 |
return fetchJson<CorpusAggregates>("/api/corpus-aggregates")
|
| 106 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import type {
|
| 2 |
+
BackendManifestStatus,
|
| 3 |
+
ComparisonIndex,
|
| 4 |
+
CorpusAggregates,
|
| 5 |
+
EvalHierarchy,
|
| 6 |
+
PeerRanksMap,
|
| 7 |
+
} from "@/lib/backend-artifacts"
|
| 8 |
import { decorateHierarchyDerivedTags } from "@/lib/benchmark-tags"
|
| 9 |
import type { BenchmarkEvaluationCardData } from "@/components/benchmark-evaluation-card"
|
| 10 |
import type { HFEvalDetail } from "@/lib/hf-data"
|
|
|
|
| 110 |
export function fetchCorpusAggregates() {
|
| 111 |
return fetchJson<CorpusAggregates>("/api/corpus-aggregates")
|
| 112 |
}
|
| 113 |
+
|
| 114 |
+
export function fetchPeerRanks() {
|
| 115 |
+
return fetchJson<PeerRanksMap>("/api/peer-ranks")
|
| 116 |
+
}
|
|
@@ -16,6 +16,7 @@ import type {
|
|
| 16 |
HierarchyMetric,
|
| 17 |
HierarchySlice,
|
| 18 |
HierarchyTags,
|
|
|
|
| 19 |
RowAnnotations,
|
| 20 |
SignalSummaries,
|
| 21 |
} from "@/lib/backend-artifacts"
|
|
@@ -971,6 +972,19 @@ export async function fetchComparisonIndex(): Promise<ComparisonIndex> {
|
|
| 971 |
return fetchHFJson<ComparisonIndex>("comparison-index.json")
|
| 972 |
}
|
| 973 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 974 |
export async function fetchCorpusAggregates(): Promise<CorpusAggregates | null> {
|
| 975 |
if (useViewLayerBackend()) {
|
| 976 |
return (await fetchSnapshotSidecars()).fetchHeadline()
|
|
|
|
| 16 |
HierarchyMetric,
|
| 17 |
HierarchySlice,
|
| 18 |
HierarchyTags,
|
| 19 |
+
PeerRanksMap,
|
| 20 |
RowAnnotations,
|
| 21 |
SignalSummaries,
|
| 22 |
} from "@/lib/backend-artifacts"
|
|
|
|
| 972 |
return fetchHFJson<ComparisonIndex>("comparison-index.json")
|
| 973 |
}
|
| 974 |
|
| 975 |
+
/**
|
| 976 |
+
* Per-(eval, model) primary-metric peer ranks. v2 reads the wrapped
|
| 977 |
+
* sidecar from the pinned snapshot; legacy reads the bare-map file
|
| 978 |
+
* historically published unversioned at the dataset root.
|
| 979 |
+
*/
|
| 980 |
+
export async function fetchPeerRanks(): Promise<PeerRanksMap> {
|
| 981 |
+
if (useViewLayerBackend()) {
|
| 982 |
+
return (await fetchSnapshotSidecars()).fetchPeerRanks()
|
| 983 |
+
}
|
| 984 |
+
|
| 985 |
+
return (await fetchHFJsonSafe<PeerRanksMap>("peer-ranks.json")) ?? {}
|
| 986 |
+
}
|
| 987 |
+
|
| 988 |
export async function fetchCorpusAggregates(): Promise<CorpusAggregates | null> {
|
| 989 |
if (useViewLayerBackend()) {
|
| 990 |
return (await fetchSnapshotSidecars()).fetchHeadline()
|
|
@@ -5,6 +5,8 @@ import type {
|
|
| 5 |
ComparisonIndex,
|
| 6 |
CorpusAggregates,
|
| 7 |
EvalHierarchy,
|
|
|
|
|
|
|
| 8 |
} from "@/lib/backend-artifacts"
|
| 9 |
|
| 10 |
let cache: {
|
|
@@ -12,6 +14,7 @@ let cache: {
|
|
| 12 |
headline?: Promise<CorpusAggregates>
|
| 13 |
hierarchy?: Promise<EvalHierarchy>
|
| 14 |
comparisonIndex?: Promise<ComparisonIndex>
|
|
|
|
| 15 |
} = {}
|
| 16 |
|
| 17 |
function getSnapshotUrl() {
|
|
@@ -65,6 +68,30 @@ export function fetchComparisonIndex(): Promise<ComparisonIndex> {
|
|
| 65 |
))
|
| 66 |
}
|
| 67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 68 |
/**
|
| 69 |
* Fail fast on contract regressions. Comparison-index rows must carry
|
| 70 |
* `family_id`; the model-page graph view collapses without it. See
|
|
|
|
| 5 |
ComparisonIndex,
|
| 6 |
CorpusAggregates,
|
| 7 |
EvalHierarchy,
|
| 8 |
+
PeerRanksMap,
|
| 9 |
+
PeerRanksSidecar,
|
| 10 |
} from "@/lib/backend-artifacts"
|
| 11 |
|
| 12 |
let cache: {
|
|
|
|
| 14 |
headline?: Promise<CorpusAggregates>
|
| 15 |
hierarchy?: Promise<EvalHierarchy>
|
| 16 |
comparisonIndex?: Promise<ComparisonIndex>
|
| 17 |
+
peerRanks?: Promise<PeerRanksMap>
|
| 18 |
} = {}
|
| 19 |
|
| 20 |
function getSnapshotUrl() {
|
|
|
|
| 68 |
))
|
| 69 |
}
|
| 70 |
|
| 71 |
+
/**
|
| 72 |
+
* Per-(eval, model) primary-metric peer ranks from
|
| 73 |
+
* `warehouse/<snapshot>/peer-ranks.json`. Resolves to the bare
|
| 74 |
+
* `eval_summary_id → model_route_id → {position, total}` map the
|
| 75 |
+
* model-detail benchmark grid expects, so callers don't have to reach
|
| 76 |
+
* into `.ranks` themselves.
|
| 77 |
+
*
|
| 78 |
+
* Returns an empty map if the snapshot doesn't carry the file yet —
|
| 79 |
+
* the producer started emitting it as a Stage J sidecar in May 2026,
|
| 80 |
+
* so older pinned snapshots may 404. Logs a warning in that case rather
|
| 81 |
+
* than throwing so the rest of the page still renders.
|
| 82 |
+
*/
|
| 83 |
+
export function fetchPeerRanks(): Promise<PeerRanksMap> {
|
| 84 |
+
return (cache.peerRanks ??= fetchJson<PeerRanksSidecar>("peer-ranks.json")
|
| 85 |
+
.then((payload) => payload?.ranks ?? {})
|
| 86 |
+
.catch((err) => {
|
| 87 |
+
console.warn(
|
| 88 |
+
`[sidecars] peer-ranks.json not available on snapshot; ` +
|
| 89 |
+
`falling back to empty map. ${err instanceof Error ? err.message : String(err)}`,
|
| 90 |
+
)
|
| 91 |
+
return {} as PeerRanksMap
|
| 92 |
+
}))
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
/**
|
| 96 |
* Fail fast on contract regressions. Comparison-index rows must carry
|
| 97 |
* `family_id`; the model-page graph view collapses without it. See
|