Observability
Eval Race
Models racing through an eval set on an oval track — one lap per batch of cases, with standings, gaps and the fastest lap.
2 variantsMIT
Preview
Eval race
5 models · 400 cases · support-bench v3
Live
kestrel-4 leads by 2 cases
6 / 400
Cases scored · 1 lap = 100
| Position | Model | Cases scored | Lap | Gap | Last lap | Best lap |
|---|---|---|---|---|---|---|
| 1 | kestrel-4 | 6 of 400 | 1 of 4 | Leader | None | None |
| 2 | wren-2.5 | 4 of 400 | 1 of 4 | +2 | None | None |
| 3 | osprey-pro | 2 of 400 | 1 of 4 | +4 | None | None |
| 4 | heron-flash | 0 of 400 | 1 of 4 | +6 | None | None |
| 5 | puffin-mini | 0 of 400 | 1 of 4 | +6 | None | None |
kestrel-4 leads
Installation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/eval-race.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { EvalRace } from "@/components/ui/eval-race";
export function SuiteRace({ run }: { run: EvalRun }) {
return (
<EvalRace
title="Eval race"
subtitle={`${run.models.length} models · ${run.cases} cases · ${run.suite}`}
total={run.cases}
perLap={100} // one lap of the track per 100 cases
racers={run.models.map((m) => ({
id: m.id,
label: m.name,
scored: m.casesScored,
laps: m.lapSeconds, // duration of each completed batch of 100
}))}
onSelect={(id) => setHighlighted(id)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| racers* | EvalRacer[] | — | One per model. Ranked by cases scored, ties broken by total lap time. Order in the array only breaks exact ties. |
| total* | number | — | Cases in the eval set. A racer that reaches it has finished. |
| perLap* | number | — | Cases per lap of the track. A racer a full lap behind the leader shows +1 lap. |
| title | string | "Eval race" | Header title. |
| subtitle | string | "5 models · 400 cases" | Secondary line under the title. |
| layout | "race" | "standings" | "race" | `race` draws the full track with lap and fastest lap in the middle. `standings` leads with the table, a small track beside the headline and last and best lap columns. |
| status | "live" | "final" | — | Overrides the header state. By default the race is final once every racer has scored `total`. |
| formatTime | (seconds: number) => string | s.toFixed(1) + 's' | Formats lap times and time gaps between finished racers. |
| onSelect | (id: string | null) => void | — | Called when a racer is hovered on the track or in the table, or reached with the arrow keys. |
| className | string | — | Extra classes for the root element. |
type EvalRacer = {
id: string;
label: string; // short, e.g. a model id
name?: string; // full name for screen readers
scored: number; // cases scored so far, 0…total
laps?: number[]; // seconds per completed lap
};