Observability
Eval Results
An eval run as a grid of cases — pass, fail or regressed vs the baseline — with per-case input, expected and actual.
2 variantsMIT
Preview
sql-generation
opus-5.5 vs sonnet-5.5 · 60 of 60 running
0.0%
Down84.9 pts vs baselineInstallation
Copies the component into components/ui and installs its dependencies and theme tokens.
pnpm dlx shadcn@latest add https://tuffui.com/r/eval-results.jsonUsage
Pass your own data and wire the callbacks to your agent runtime.
import { EvalResults } from "@/components/ui/eval-results";
export function EvalRun({ run }: { run: EvalRun }) {
return (
<EvalResults
data={{
suite: run.suite,
label: `${run.candidate} vs ${run.baseline}`,
// status: "pending" | "running" | "pass" | "fail" | "regressed" | "improved"
cases: run.cases,
baselinePassRate: run.baselinePassRate,
metrics: [
{ id: "acc", label: "Accuracy", baseline: 0.85, candidate: 0.88, better: "higher" },
{ id: "p50", label: "Latency p50", baseline: 1840, candidate: 1320, better: "lower" },
],
}}
onSelectCase={(c) => console.log(c.id)}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| data* | { suite: string; label?: string; cases: EvalCase[]; baselinePassRate?: number; metrics?: EvalMetric[] } | — | The suite, its cases in run order and, for the delta and the compare view, the baseline pass rate and metrics. |
| view | "grid" | "compare" | "grid" | A square per case, or baseline vs candidate bars per metric plus the regressed cases. |
| filter | "all" | "failed" | "regressed" | "improved" | — | Controlled filter. Non-matching cases dim instead of disappearing, so the grid stays put. |
| onFilterChange | (filter) => void | — | Called when a filter pill is picked. |
| selectedId | string | null | — | Controlled selection. The selected case shows its input, expected and actual output below. |
| onSelectCase | (testCase: EvalCase) => void | — | Called on click or Enter. Arrow keys, Home and End move between cases. |
| className | string | — | Extra classes for the root element. |
type EvalCase = {
id: string;
name: string;
status: "pending" | "running" | "pass" | "fail" | "regressed" | "improved";
score?: number; // 0–1
input?: string;
expected?: string;
actual?: string;
reason?: string;
};
type EvalMetric = {
id: string;
label: string;
baseline: number;
candidate: number;
better: "higher" | "lower";
format?: (value: number) => string;
};