Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
87c318d
feat(report-ui): persist inspection state in the URL
astahmer Aug 31, 2026
99e7010
feat(report-ui): sort the case ledger by column
astahmer Aug 31, 2026
c33ee9d
feat(report-ui): filter the ledger from outcome count links
astahmer Aug 31, 2026
90e6247
feat(report-ui): inspect raw case JSON in a collapsible tree
astahmer Aug 31, 2026
dc2d3ef
feat(report-ui): copy JSON with temporary Copied! feedback
astahmer Aug 31, 2026
fc01313
feat(report-ui): make failure messages easier to scan
astahmer Aug 31, 2026
41515a5
feat(report-ui): open the case file in a local editor
astahmer Aug 31, 2026
6513ac3
feat(report-ui): copy a case as Markdown for an agent
astahmer Aug 31, 2026
f046b37
feat(report-ui): keep header totals on the full workspace
astahmer Aug 31, 2026
ac33489
feat(report-ui): show and sort the recorded model
astahmer Aug 31, 2026
86f3dc2
feat(report-ui): show passed judges on score hover
astahmer Aug 31, 2026
7866f8b
feat(report-ui): open relative paths from the CLI workspace
astahmer Aug 31, 2026
e42abe2
feat(report-ui): inspect case output like the Raw tab
astahmer Aug 31, 2026
91fbeb2
feat(report-ui): estimate eval cost from models.dev rates
astahmer Aug 31, 2026
f312ddc
feat(report-ui): put the recorded model in the drawer header
astahmer Aug 31, 2026
ca5c2fb
feat(report-ui): expand JSON inspector trees three levels
astahmer Aug 31, 2026
324a663
feat(report-ui): copy the absolute path from the editor menu
astahmer Aug 31, 2026
232f83d
feat(report-ui): copy a case failure without the whole JSON
astahmer Aug 31, 2026
6d5f96e
feat(report-ui): filter the ledger by recorded model
astahmer Aug 31, 2026
32c8040
feat(report-ui): price cached tokens when usage splits them
astahmer Aug 31, 2026
0532038
feat(report-ui): explain how estimated cost is computed
astahmer Aug 31, 2026
23fe8c7
feat(report-ui): show estimated cost as a ledger column
astahmer Aug 31, 2026
797f4f0
feat(report-ui): make cost help readable and one line
astahmer Aug 31, 2026
8ca637b
feat(report-ui): show dataset input and expected values
astahmer Aug 31, 2026
d33c249
feat(report-ui): compare cases across runs and models
astahmer Aug 31, 2026
44b2fbe
feat(report-ui): suggest a cheaper model with the same capabilities
astahmer Aug 31, 2026
9f9b378
feat(report-ui): write JUnit and pull-request comment files
astahmer Aug 31, 2026
52385c3
feat(report-ui): wire cost, compare, and model hints into the ledger
astahmer Aug 31, 2026
733083f
feat(report-ui): bump the Vite React plugin onto Vite 8
astahmer Aug 31, 2026
3fb6229
feat(report-ui): only suggest cheaper models in the same family
astahmer Aug 31, 2026
cd77fed
feat(report-ui): keep score tooltips inside the viewport
astahmer Aug 31, 2026
47a076b
feat(report-ui): color case scores from pass or fail
astahmer Aug 31, 2026
c06adfa
feat(report-ui): jump cases and clear filters from the keyboard
astahmer Aug 31, 2026
2aba096
feat(report-ui): open a command palette for filters and exports
astahmer Aug 31, 2026
b69db25
feat(report-ui): show the header cost breakdown
astahmer Aug 31, 2026
e92ed45
feat(report-ui): shrink the report header to one strip
astahmer Aug 31, 2026
4d92c81
feat(report-ui): keep drawer chrome on the facts that exist
astahmer Aug 31, 2026
cfb4937
feat(report-ui): re-run one eval case from the report
astahmer Aug 31, 2026
ac6465b
feat(report-ui): hide unused ledger chrome and fail first
astahmer Aug 31, 2026
04a3eb7
feat(report-ui): keep the re-run confirm above the drawer
astahmer Aug 31, 2026
e218bbb
feat(report-ui): stream re-run jobs into a task tray
astahmer Aug 31, 2026
585e934
feat(report-ui): list every visible case in the command palette
astahmer Aug 31, 2026
23550ca
feat(report-ui): pin the task tray to the bottom-right corner
astahmer Aug 31, 2026
83fa6fd
feat(report-ui): run evals with their vitest config
astahmer Aug 31, 2026
fd6d49a
feat(report-ui): keep popover copy inside the box
astahmer Aug 31, 2026
0cb5446
feat(report-ui): keep other cases when one eval is re-run
astahmer Aug 31, 2026
0295950
feat(report-ui): show vitest logs as a readable terminal
astahmer Aug 31, 2026
d717760
feat(report-ui): merge local report viewer UX
astahmer Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion packages/core/src/report/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { z } from "zod";
import { HarnessRunSchema, ToolCallSchema } from "../harness";
import { JsonObjectSchema, JsonValueSchema } from "../json";
import { isJsonObject, NullableFiniteNumberSchema } from "../schema-utils";
import { NullableFiniteNumberSchema, isJsonObject } from "../schema-utils";

/** Harness metadata stored by vitest-evals on Vitest task metadata. */
export const HarnessMetaSchema = z
Expand Down Expand Up @@ -31,6 +31,8 @@ export const EvalMetaSchema = z
.object({
scores: z.array(EvalScoreSchema).optional(),
avgScore: NullableFiniteNumberSchema,
input: JsonValueSchema.optional(),
expected: JsonValueSchema.optional(),
output: JsonValueSchema.optional(),
thresholdFailed: z.boolean().optional(),
toolCalls: z.array(ToolCallSchema).optional(),
Expand Down
10 changes: 5 additions & 5 deletions packages/report-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"files": [
"dist"
],
"files": ["dist"],
"publishConfig": {
"access": "public"
},
Expand All @@ -41,13 +39,15 @@
},
"devDependencies": {
"@tailwindcss/vite": "^4.3.0",
"@tanstack/react-router": "^1.170.32",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"@vitejs/plugin-react": "^6.1.1",
"react": "^19.2.3",
"react-dom": "^19.2.3",
"react18-json-view": "^0.2.10",
"tailwindcss": "^4.3.0",
"vite": "^7.3.0",
"vite": "^8.2.2",
"vite-tsconfig-paths": "^6.1.1"
}
}
48 changes: 47 additions & 1 deletion packages/report-ui/src/app/App.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { afterEach, describe, expect, test, vi } from "vitest";
import type { ReportWorkspace } from "@vitest-evals/core";
import { afterEach, describe, expect, test, vi } from "vitest";
import {
adjacentVisibleCase,
loadWorkspace,
nextSortSearch,
resolveSelectedCase,
resolveSelectedCaseId,
summarizeVisibleWorkspace,
Expand Down Expand Up @@ -40,6 +42,46 @@ afterEach(() => {
vi.unstubAllGlobals();
});

describe("nextSortSearch", () => {
test("starts a new column with its default direction and toggles the active one", () => {
expect(nextSortSearch(undefined, "asc", "score")).toEqual({
dir: "desc",
sort: "score",
});
expect(nextSortSearch("score", "desc", "score")).toEqual({
dir: "asc",
sort: "score",
});
expect(nextSortSearch("score", "asc", "case")).toEqual({
dir: "asc",
sort: "case",
});
expect(nextSortSearch(undefined, "asc", "model")).toEqual({
dir: "asc",
sort: "model",
});
});
});

describe("adjacentVisibleCase", () => {
test("opens the first or last case when nothing is selected", () => {
expect(adjacentVisibleCase(cases, undefined, 1)?.id).toBe("failed-case");
expect(adjacentVisibleCase(cases, undefined, -1)?.id).toBe("passed-case");
});

test("moves to the next visible case and stays at the ends", () => {
expect(adjacentVisibleCase(cases, "failed-case", 1)?.id).toBe(
"passed-case",
);
expect(adjacentVisibleCase(cases, "passed-case", 1)?.id).toBe(
"passed-case",
);
expect(adjacentVisibleCase(cases, "passed-case", -1)?.id).toBe(
"failed-case",
);
});
});

describe("case selection", () => {
test("keeps selection scoped to visible filtered cases", () => {
const visibleCases = [cases[1]!];
Expand Down Expand Up @@ -109,6 +151,7 @@ describe("visible summary", () => {
},
{
query: "",
model: "all",
runId: "run-2",
status: "passed",
},
Expand All @@ -134,6 +177,7 @@ describe("visible summary", () => {
runs,
{
query: "",
model: "all",
runId: "run-2",
status: "passed",
},
Expand All @@ -151,6 +195,7 @@ describe("visible summary", () => {
runs,
{
query: "",
model: "all",
runId: "all",
status: "all",
},
Expand Down Expand Up @@ -183,6 +228,7 @@ describe("visible summary", () => {
},
{
query: "",
model: "all",
runId: "all",
status: "all",
},
Expand Down
Loading