Skip to content

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 baseline

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/eval-results.json

Usage

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

PropTypeDefaultDescription
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.
selectedIdstring | 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.
classNamestring—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;
};