feat: add experiment results to the overview - #242
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f75a8076-a032-4c34-8135-97855d56fd80
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new trial-selection UI has state/control issues that can lead to inconsistent selection behavior, and the homepage overview loader currently does potentially expensive full run loading per experiment.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 3
New issues introduced by this change (3)
| Severity | Finding |
|---|---|
website/src/app/components/RunDetailsPage.tsx — When switching models, selectedTrial is not reset to a trial that exists in the newly selected… |
|
website/src/app/components/RunDetailsPage.tsx — The Treatment select is controlled by selectedResult.treatment, but updates selectedTreatment… |
|
website/src/experiment-page-data.ts — getExperimentsOverview() calls listForExperiment(experiment.id), which loads all dated runs… |
What changed in this PR
This PR extends the website to surface experiment results alongside the existing design-system benchmark, adds latest-run treatment + per-scenario summaries to experiment pages, and enhances the shared run viewer with per-trial selection for repeated trials.
Changes:
- Add experiment result aggregation/summarization and render it on
/and/experiments/:id. - Add a trial selector (and scenario anchor IDs) to the shared run details viewer.
- Add website-focused Vitest coverage for the new aggregation + page-data behaviors and wire it into the root Vitest projects.
| File | Description |
|---|---|
| website/vitest.config.ts | Adds a dedicated Vitest project/config for website tests. |
| website/src/test/experiment.ts | Introduces helpers to build experiment run/result fixtures for tests. |
| website/src/experiment-results.ts | Implements aggregation for treatment/scenario summaries from a run bundle. |
| website/src/experiment-results.test.ts | Adds unit tests validating aggregation rules and edge cases. |
| website/src/experiment-page-data.ts | Adds data loaders for experiment pages and homepage overview summaries. |
| website/src/experiment-page-data.test.ts | Tests newest-run selection, empty/latest-run behavior, and error propagation. |
| website/src/app/page.tsx | Renders experiments overview on the homepage alongside benchmarks. |
| website/src/app/experiments/[id]/page.tsx | Switches to shared getExperimentPageData loader. |
| website/src/app/experiments/[id]/components/Page.tsx | Displays “Latest results” section on experiment pages. |
| website/src/app/components/RunDetailsPage.tsx | Adds trial selection and scenario anchors to the run viewer. |
| website/src/app/components/ExperimentResults.tsx | Adds overview + latest-results UI tables for experiment summaries. |
| website/README.md | Documents updated routes and metric definitions/output-navigation flow. |
| vitest.config.ts | Registers the website Vitest project in the root config. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Merge main, reset trial selection when models or treatments change, and load only the latest experiment bundle for the overview. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f75a8076-a032-4c34-8135-97855d56fd80
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The new website Vitest tests use a non-existent matcher (toHaveBeenCalledExactlyOnceWith), which will fail test execution.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review tier: Lite
Findings: 1
New issues introduced by this change (2)
| Severity | Finding |
|---|---|
website/src/runs.test.ts — toHaveBeenCalledExactlyOnceWith is not a Vitest matcher (and there’s no website vitest setup… |
|
website/src/app/components/RunDetailsPage.tsx — The scenario anchor ID is built from the raw scenarioId, but links to scenario output use… |
Issues resolved since last review (3)
| Severity | Finding |
|---|---|
website/src/experiment-page-data.ts — getExperimentsOverview() calls listForExperiment(experiment.id), which loads all dated runs… View resolved comment |
|
website/src/app/components/RunDetailsPage.tsx — The Treatment select is controlled by selectedResult.treatment, but updates selectedTreatment… View resolved comment |
|
website/src/app/components/RunDetailsPage.tsx — When switching models, selectedTrial is not reset to a trial that exists in the newly selected… View resolved comment |
Suppressed comments (2)
website/src/runs.test.ts:69
toHaveBeenCalledExactlyOnceWithis not a Vitest matcher (and there’s no website vitest setup extendingexpect), so this assertion will fail at runtime. UsetoHaveBeenCalledTimes(1)plustoHaveBeenCalledWith(...)instead.
expect(read).toHaveBeenCalledExactlyOnceWith(latest)
website/src/runs.test.ts:100
toHaveBeenCalledExactlyOnceWithis not a Vitest matcher (and there’s no website vitest setup extendingexpect), so this assertion will fail at runtime. UsetoHaveBeenCalledTimes(1)plustoHaveBeenCalledWith(...)instead.
expect(read).toHaveBeenCalledExactlyOnceWith(latest)
Share fragment and target generation, cover encoded scenario IDs, and simplify run-loader mock assertions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f75a8076-a032-4c34-8135-97855d56fd80
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The changes are cohesive, well-tested (including edge cases like empty latest runs and invalid bundles), and I didn’t find any correctness or maintainability issues that block merging.
Review tier: Lite
Findings: None
Issues resolved since last review (2)
| Severity | Finding |
|---|---|
website/src/app/components/RunDetailsPage.tsx — The scenario anchor ID is built from the raw scenarioId, but links to scenario output use… View resolved comment |
|
website/src/runs.test.ts — toHaveBeenCalledExactlyOnceWith is not a Vitest matcher (and there’s no website vitest setup… View resolved comment |
Render Primer's deterministic focus-visible markers in the root layout so pre-hydration polyfill initialization does not cause an attribute mismatch. Add server-rendering coverage without suppressing hydration warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: f75a8076-a032-4c34-8135-97855d56fd80
There was a problem hiding this comment.
Copilot review overview
🔵 Needs a closer look
It introduces broad UI + data-loading behavior changes (homepage aggregation, latest-run resolution, fragment/anchor semantics, and run viewer state) that warrant final human verification despite good test coverage.
Review tier: Lite
Findings: None
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
website/src/runs.test.ts:20
- The test creates temporary fixtures under a repo-relative
.agents/tmpdirectory. Other tests in this repo useos.tmpdir()withfs.mkdtemp(...), which avoids leaving behind project-local directories and is more robust when the checkout is read-only or shared.
Consider switching this test to use os.tmpdir() directly and removing the explicit .agents/tmp mkdir.


This PR adds experiment results to the overview alongside the existing design-system benchmark. Experiment pages now show how treatments perform in the latest run, with per-scenario comparisons and direct links to walkthroughs, test results, and transcripts.
The run viewer already supported switching models and treatments, but only showed the first matching trial. This also adds trial selection so repeated trials can be inspected individually.
Changelog
New
/with each experiment's description, latest run, and treatment results./experiments/:id, while preserving dated run history.Changed
main, preserving its Judges tab and website tests alongside the trial selector.Removed
None.
Visual comparisons
Both versions use the same synthetic result bundles for the
noopexperiment. These screenshots illustrate the UI, not measured model performance. No benchmark bundles were loaded, so the benchmark's existing empty state is visible.The original before/after pairs predate the merge of judge support from
main. The integrated Judges view is shown below them.Before / After: overview
The existing benchmark overview is preserved. Experiment summaries, latest-run links, and treatment results are now shown below it.
Before / After: experiment details
The experiment page previously listed dated runs only. It now includes latest-run treatment comparisons, per-scenario results, and direct output links above the run history.
Before / After: scenario output and trial selection
The before view always displays the first matching trial. The after view has Trial 2 selected, so its summary and transcript are different even though the underlying result bundle is identical.
After review feedback: Judges tab and trial selection
The Judges tab from
mainis preserved and follows the selected trial. This uses a separate synthetic fixture to verify that switching treatments or models resets to the first matching trial, including when a model does not have the previous treatment.Validation
gh-awv0.87.9.This is a website-only change and does not change the published
@primer/agent-evalAPI, so no changeset is included.