feat(studio): add experiment trace comparison view [ASE-186] - #641
Conversation
1057ed0 to
8d296fc
Compare
|
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughChangesExperiment trace comparison
Sequence Diagram(s)sequenceDiagram
participant Browser
participant ExperimentTraceDetailRoute
participant useCompareSession
participant ExperimentTraceCompare
participant IntakeTraceDetailView
Browser->>ExperimentTraceDetailRoute: Select compareWith experiment
ExperimentTraceDetailRoute->>useCompareSession: Query matching test_case_id
useCompareSession->>ExperimentTraceCompare: Return comparison state
ExperimentTraceCompare->>IntakeTraceDetailView: Render primary and matched traces
IntakeTraceDetailView->>Browser: Update linked span selection
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 11
🧹 Nitpick comments (3)
docs/superpowers/plans/2026-07-07-experiment-column-reordering.md (2)
1-33: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftAlign this page with the Markdown documentation guidelines.
The page mixes architecture explanation, implementation how-to steps, and reference material. It also lacks an explicit prerequisites section at the top and a
Next Stepssection at the end. Either classify this as an internal implementation-plan exception or restructure it into one Diataxis quadrant with the required sections.Also applies to: 544-554
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md` around lines 1 - 33, Restructure the document into a single Diataxis category, preferably an internal implementation plan, instead of mixing architecture, procedural instructions, and reference material. Add an explicit Prerequisites section near the top and a Next Steps section at the end, and reorganize or remove content that does not fit the chosen category while preserving the implementation plan’s actionable task structure.Source: Coding guidelines
500-540: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftAdd focused automated coverage for the opt-in behavior.
Existing DataView tests and manual checks do not lock down the new contract. Add tests for the disabled default, pinned-column exclusion, reordered
columnOrder, body-cell movement, sorting via the label, and column visibility.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md` around lines 500 - 540, Add focused automated tests for the DataView column-reordering contract, covering the disabled default, exclusion of pinned columns, reordered columnOrder, corresponding body-cell movement, sorting through the column label, and column visibility. Place the tests with the existing DataView test suite and use the relevant TableColumnHeader, TableContent, and ExperimentGroupDataView behaviors to verify both opt-in and unchanged default behavior.web/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsx (1)
125-173: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winConsider adding a test for the select → navigate flow.
Current compare-view tests assert rendered states but not that choosing an experiment from
CompareExperimentSelect(or clicking "Clear") actually updates the URL/route viahandleCompareChange/handleClearCompare.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsx` around lines 125 - 173, Add a compare-view interaction test that selects another experiment through CompareExperimentSelect and verifies navigation updates the compareWith query parameter via handleCompareChange; also cover the Clear action and assert it removes the compare parameter or returns to the primary route via handleClearCompare.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md`:
- Around line 180-185: Update the validation commands in the documented steps,
including the “Verify types pass” checks and the referenced validation sections,
to avoid masking failures through pipelines. Run typecheck/lint commands
directly where possible, or prepend `set -o pipefail` and ensure filtering
commands cannot replace the original command’s exit status.
- Around line 522-531: Update “Step 3: Run existing DataView tests to confirm
nothing regressed” to invoke the repository’s declared JavaScript test command
unconditionally, removing the uv run pytest fallback chain; retain the Vitest
command only if it is the documented web test runner, and ensure the command
targets packages/common/src/components/DataView.
- Around line 27-31: The column reordering logic must preserve pinned column IDs
in the table’s full column order. Update the DnD setup and reorder handler
around TableContent, SortableContext, and arrayMove so only non-pinned columns
are draggable while table.setColumnOrder() always receives the complete order;
merge reordered non-pinned IDs back with the original pinned IDs rather than
replacing the order with a filtered list.
- Around line 298-320: Update DragAlongCell to accept and forward the existing
TableDataCell props and children by extending ComponentProps<typeof
TableDataCell>; merge the sortable DnD styles with the incoming style rather
than replacing it, and render the provided children instead of reconstructing
content with flexRender. Apply the same forwarding pattern to the related
implementation noted around the second occurrence.
- Around line 82-109: Update the header drag wiring and DndContext setup to
configure KeyboardSensor with the required coordinate getter, pass
setActivatorNodeRef through DragProps, and apply it to the drag handle button.
Also set the handle’s type to "button" to prevent form submission, updating
related props and rendering paths such as TableColumnHeaderProps as needed.
- Around line 296-320: Wrap the body-cell rendering that contains DragAlongCell
in a SortableContext using items={columnOrder} and
horizontalListSortingStrategy, or move an equivalent context to a shared parent
that covers both headers and body cells. Ensure every DragAlongCell receives the
same column order and sorting strategy as the dragged headers so row cells
remain aligned during column reordering.
In `@scripts/seed_local_experiments.py`:
- Around line 34-36: Add a shared timeout constant and pass it to both
urllib.request.urlopen calls in the relevant request helpers, including get, so
endpoint requests cannot hang indefinitely.
- Around line 107-113: Update the session-selection logic in the experiment
seeding flow to fetch both experiment session lists, retain only sessions with
non-empty test_case_id values, and intersect them by shared test_case_id rather
than relying on page order or session_id fallback. Before seeding, fail
explicitly when fewer than three shared test cases remain, and use the matched
test_case_id values to select the corresponding sessions for both experiments.
- Around line 113-114: Update the agent.output construction in the
session-processing logic to derive its value from the already normalized `inp`
variable, using `inp[:500]` instead of calling `session.get("input", "")[:500]`,
so null inputs are handled safely and the existing truncation is reused.
In
`@web/packages/studio/src/routes/ExperimentTraceDetailRoute/ExperimentTraceCompare.tsx`:
- Around line 108-131: The compare column shows the no-test-case state while the
primary trace is still loading. Thread the primary trace loading flag from the
parent into the comparison logic, and update renderRightColumn and
useCompareSession usage to return the loading UI until the primary trace
resolves; only treat a falsy testCaseId as no-test-case-id after loading
completes. Use the existing renderRightColumn and useCompareSession symbols.
In
`@web/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.test.ts`:
- Line 10: Replace the relative useCompareSession import in the test with the
project’s configured absolute alias path, preserving the existing symbol and
import behavior.
---
Nitpick comments:
In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md`:
- Around line 1-33: Restructure the document into a single Diataxis category,
preferably an internal implementation plan, instead of mixing architecture,
procedural instructions, and reference material. Add an explicit Prerequisites
section near the top and a Next Steps section at the end, and reorganize or
remove content that does not fit the chosen category while preserving the
implementation plan’s actionable task structure.
- Around line 500-540: Add focused automated tests for the DataView
column-reordering contract, covering the disabled default, exclusion of pinned
columns, reordered columnOrder, corresponding body-cell movement, sorting
through the column label, and column visibility. Place the tests with the
existing DataView test suite and use the relevant TableColumnHeader,
TableContent, and ExperimentGroupDataView behaviors to verify both opt-in and
unchanged default behavior.
In `@web/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsx`:
- Around line 125-173: Add a compare-view interaction test that selects another
experiment through CompareExperimentSelect and verifies navigation updates the
compareWith query parameter via handleCompareChange; also cover the Clear action
and assert it removes the compare parameter or returns to the primary route via
handleClearCompare.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 34625f0e-0e3c-46f1-b783-ef1a39731a7e
📒 Files selected for processing (13)
docs/superpowers/plans/2026-07-07-experiment-column-reordering.mdscripts/seed_local_experiments.pyweb/packages/studio/src/components/IntakeDetail/TraceDetailView.tsxweb/packages/studio/src/components/IntakeDetail/TraceSpanAccordions.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/CompareExperimentSelect.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/ExperimentTraceCompare.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/index.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.test.tsweb/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.tsweb/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsxweb/packages/studio/src/routes/constants.tsweb/packages/studio/src/routes/utils.ts
There was a problem hiding this comment.
🧹 Nitpick comments (1)
docs/superpowers/plans/2026-07-07-experiment-column-reordering.md (1)
1-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winKeep this page in one Diátaxis quadrant.
This page mixes a HOW-TO, architecture explanation, reference table, and manual checklist. Add prerequisites before the goal, classify the page (likely HOW-TO), split reference/architecture material into linked pages if needed, and add a
Next Stepssection with cross-links.As per coding guidelines, documentation pages must use one Diátaxis quadrant, list prerequisites first, apply progressive disclosure, and include Next Steps.
Also applies to: 544-554
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md` around lines 1 - 9, The implementation plan mixes Diátaxis content types instead of staying in one quadrant. Rework this page as a HOW-TO: add prerequisites before the Goal, keep the implementation steps and manual checklist as the primary content, move architecture and reference details to linked documentation where appropriate, and add a Next Steps section with relevant cross-links.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@docs/superpowers/plans/2026-07-07-experiment-column-reordering.md`:
- Around line 1-9: The implementation plan mixes Diátaxis content types instead
of staying in one quadrant. Rework this page as a HOW-TO: add prerequisites
before the Goal, keep the implementation steps and manual checklist as the
primary content, move architecture and reference details to linked documentation
where appropriate, and add a Next Steps section with relevant cross-links.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: ffe3de71-8e4a-4c0d-8e2f-f7fa772f57df
📒 Files selected for processing (15)
docs/superpowers/plans/2026-07-07-experiment-column-reordering.mdscripts/seed_local_experiments.pyweb/packages/studio/src/components/IntakeDetail/IntakeComponents/spanKeyValues.test.tsxweb/packages/studio/src/components/IntakeDetail/TraceDetailView.tsxweb/packages/studio/src/components/IntakeDetail/TraceSpanAccordions.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/CompareExperimentSelect.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/ExperimentTraceCompare.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/index.tsxweb/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.test.tsweb/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.tsweb/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsxweb/packages/studio/src/routes/constants.tsweb/packages/studio/src/routes/utils.tsweb/packages/studio/src/util/intakeTelemetry.ts
✅ Files skipped from review due to trivial changes (3)
- web/packages/studio/src/routes/utils.ts
- web/packages/studio/src/components/IntakeDetail/IntakeComponents/spanKeyValues.test.tsx
- web/packages/studio/src/routes/constants.ts
🚧 Files skipped from review as they are similar to previous changes (9)
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/CompareExperimentSelect.tsx
- web/packages/studio/src/routes/IntakeTraceDetailRoute/index.tsx
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.ts
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/useCompareSession.test.ts
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/index.test.tsx
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/ExperimentTraceCompare.tsx
- web/packages/studio/src/components/IntakeDetail/TraceDetailView.tsx
- web/packages/studio/src/components/IntakeDetail/TraceSpanAccordions.tsx
- web/packages/studio/src/routes/ExperimentTraceDetailRoute/index.tsx
89c4ae1 to
92599ee
Compare
walston
left a comment
There was a problem hiding this comment.
quick sync with @rrhyne has some UI and UX issues:
- The headers are wrong: use proper headings.
- Column layout doesn't have room for "Tree" view. switch to List view and hide/disable the toggle
- Breadcrumbs should render "[Experiment Name] > Compare > [Experiment Name]+"
- Compare To... dropdown should be in the page header (See figma).
- Compare To... dropdown should be populated by experiment names (it might be already, doublecheck).
- Columns need a "close" button
- Support 3-column layout
- when closing 3rd column, switch to 2-column.
- when closing last remaining column switch to an empty state view with "Compare To..." drop down
c22fd2c to
8cd7540
Compare
Side-by-side comparison of the same test case across two sibling experiments on the experiment trace detail page. - "Compare to..." selector in the page header lists same-dataset sibling experiments; picking one adds ?compareWith=<name> to the URL (preserving any active ?spanId= deep link) and splits into a two-column comparison - Each column: heading row (experiment name, expand/collapse/close), a metrics card (Correctness, Latency, Tkns In/Out, Cached Tkns), and the trace in list mode; missing sessions show "Test case not available" - TraceSpanAccordions is now controlled: single view binds selection to the URL, each compare column owns selection in local state keyed by traceId; expand/collapse surface to the column header via SlotHeaderRenderProp - Refresh invalidation scoped to the specific trace's query key Signed-off-by: Nathan Walston <nwalston@nvidia.com>
8cd7540 to
bb0233c
Compare
Address Shanaia's review — the comparison axis is now runs of the same test case, not experiments: - Compare selector lists every run (session) of the test case across the group's evaluations (FE fan-out per evaluation via useTestCaseRuns), labeled '<evaluation-name> · Trial <session_id last 5>'; ?compareWith= now carries the selected run's trace_id - Label above the selector: 'Compare against another run of this test case' - Page header: 'Test case comparison — Test case <test_case_id>'; subheader: 'See how this test case performed across different runs' - Metrics card is now per-session (not experiment rollups): cost, latency, tokens in/out, cached tokens, and all evaluator scores - Removed the per-column close buttons (kept the header Clear link) Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Refine the compare selector per design feedback (Rob/Shanaia):
- Replace the flat single-select with a grouped Dropdown menu: a panel
title, each evaluation run as a section heading, its trials listed as
'Trial XXXXX' rows (no repeated evaluation name per row)
- Descriptive text lives in the trigger ('Compare against evaluation run');
removed the separate label above the control
- Picking a trial swaps the comparison column (cap stays 1 compare run for
now); the primary run is a fixed anchor and never an option
- Add a test covering open -> grouped runs -> select -> enters comparison
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…ASE-186] - Rebuild the selector on the Select control (nv-input styling) instead of the Dropdown menu, keeping grouped runs via DropdownSection/DropdownHeading inside the listbox — matches the mockup and other grouped selects - Fixed trigger label via renderValue + placeholder (does not echo the selected run) - Loading now shows a disabled control with 'Loading other runs' across the whole group->evaluations->trace->runs chain; 'No runs to compare to' only once loaded with no siblings - Add CompareRunSelect state tests (loading/empty/ready) Signed-off-by: Nathan Walston <nwalston@nvidia.com>
- Drop DropdownSection (the source of the divider rules between runs) and use compact listbox density for a tighter list - Show hierarchy the way the mockup does: bold evaluation-run heading with its trials indented beneath as 'Trial XXXXX' - a11y: each option carries an aria-label of the full '<evaluation> · Trial XXXXX' so screen readers get self-describing options rather than relying on visual weight/indent alone Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…-186]
- Fix vertically clipped evaluation headings: the scroll container was a
flex Stack, so overflowing children were shrunk and clipped; use a block
div with overflow-y-auto so rows keep their height
- Collapse evaluations with a single trial onto one selectable line
('<evaluation> · Trial XXXXX'); evaluations with multiple trials keep the
nested heading + indented trials (per Shanaia)
- Cover both paths in CompareRunSelect tests
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
TextInputSpinner forces className=h-full, which stretched its wrapper and pinned the fixed-size spinner to the top of the trigger. Use a plain size=small Spinner so the trigger's centered slot aligns it vertically. Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…E-186] The loading affordance is the disabled control + 'Loading other runs' placeholder; the extra slotEnd spinner sat off-center next to the chevron and added nothing over the disabled state. Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…s, real indent [ASE-186] - Clickable rows (collapsed lines + nested trials) are now bold; labels (panel title + evaluation group headings) are secondary/subdued, so weight reads as 'bold = actionable' - Panel title gets extra bottom spacing to separate it from the list - Fix trial indentation: SelectItem's own padding overrode a className on the item, so indent the content (inner Text) instead Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…E-186] text-content-*/text-status-* aren't produced by the Foundations tailwind plugin (it namespaces semantic text colors as text-color-*), so those class names were silent no-ops and never subdued anything. - Group headings -> text-color-subtle (most muted, per feedback) - Panel title + Clear link + not-found body -> text-color-secondary - Not-found heading -> text-color-primary; warning icon -> text-color-feedback-warning Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
… [ASE-186] text-color-* is the CSS variable name (--text-color-*), not the generated utility; Tailwind emits the short form (text-secondary, text-primary, text-feedback-warning). Swap all compare-view text colors to those so they actually apply — group headings + title + Clear link now text-secondary, not-found heading text-primary, warning icon text-feedback-warning. Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Prefix nested trial options with a muted, decorative (aria-hidden) '↳' so their child relationship to the evaluation heading reads at a glance. The option's aria-label still carries the full '<evaluation> · Trial XXXXX'. Signed-off-by: Nathan Walston <nwalston@nvidia.com>
The 'test case not available' branch is the terminal state, shown only after the full group->evals->trace->run-fanout chain settles — the slowest path. Anchor on the mounted compare view, then wait for the terminal text with CI headroom, instead of relying on findByText's 1s default. Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* feat(studio): add experiment trace comparison view [ASE-186]
Side-by-side comparison of the same test case across two sibling
experiments on the experiment trace detail page.
- "Compare to..." selector in the page header lists same-dataset sibling
experiments; picking one adds ?compareWith=<name> to the URL (preserving
any active ?spanId= deep link) and splits into a two-column comparison
- Each column: heading row (experiment name, expand/collapse/close), a
metrics card (Correctness, Latency, Tkns In/Out, Cached Tkns), and the
trace in list mode; missing sessions show "Test case not available"
- TraceSpanAccordions is now controlled: single view binds selection to the
URL, each compare column owns selection in local state keyed by traceId;
expand/collapse surface to the column header via SlotHeaderRenderProp
- Refresh invalidation scoped to the specific trace's query key
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* feat(studio): compare test-case runs across a group [ASE-186]
Address Shanaia's review — the comparison axis is now runs of the same
test case, not experiments:
- Compare selector lists every run (session) of the test case across the
group's evaluations (FE fan-out per evaluation via useTestCaseRuns),
labeled '<evaluation-name> · Trial <session_id last 5>'; ?compareWith=
now carries the selected run's trace_id
- Label above the selector: 'Compare against another run of this test case'
- Page header: 'Test case comparison — Test case <test_case_id>';
subheader: 'See how this test case performed across different runs'
- Metrics card is now per-session (not experiment rollups): cost, latency,
tokens in/out, cached tokens, and all evaluator scores
- Removed the per-column close buttons (kept the header Clear link)
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* feat(studio): grouped run selector for trace comparison [ASE-186]
Refine the compare selector per design feedback (Rob/Shanaia):
- Replace the flat single-select with a grouped Dropdown menu: a panel
title, each evaluation run as a section heading, its trials listed as
'Trial XXXXX' rows (no repeated evaluation name per row)
- Descriptive text lives in the trigger ('Compare against evaluation run');
removed the separate label above the control
- Picking a trial swaps the comparison column (cap stays 1 compare run for
now); the primary run is a fixed anchor and never an option
- Add a test covering open -> grouped runs -> select -> enters comparison
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): correct compare run selector styling and loading state [ASE-186]
- Rebuild the selector on the Select control (nv-input styling) instead of
the Dropdown menu, keeping grouped runs via DropdownSection/DropdownHeading
inside the listbox — matches the mockup and other grouped selects
- Fixed trigger label via renderValue + placeholder (does not echo the
selected run)
- Loading now shows a disabled control with 'Loading other runs' across the
whole group->evaluations->trace->runs chain; 'No runs to compare to' only
once loaded with no siblings
- Add CompareRunSelect state tests (loading/empty/ready)
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): tighten compare run dropdown to match mockup [ASE-186]
- Drop DropdownSection (the source of the divider rules between runs) and
use compact listbox density for a tighter list
- Show hierarchy the way the mockup does: bold evaluation-run heading with
its trials indented beneath as 'Trial XXXXX'
- a11y: each option carries an aria-label of the full '<evaluation> · Trial
XXXXX' so screen readers get self-describing options rather than relying
on visual weight/indent alone
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): unclip run headings and collapse single-trial evals [ASE-186]
- Fix vertically clipped evaluation headings: the scroll container was a
flex Stack, so overflowing children were shrunk and clipped; use a block
div with overflow-y-auto so rows keep their height
- Collapse evaluations with a single trial onto one selectable line
('<evaluation> · Trial XXXXX'); evaluations with multiple trials keep the
nested heading + indented trials (per Shanaia)
- Cover both paths in CompareRunSelect tests
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): center loading spinner in compare run trigger [ASE-186]
TextInputSpinner forces className=h-full, which stretched its wrapper and
pinned the fixed-size spinner to the top of the trigger. Use a plain
size=small Spinner so the trigger's centered slot aligns it vertically.
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): drop off-center loading spinner from compare trigger [ASE-186]
The loading affordance is the disabled control + 'Loading other runs'
placeholder; the extra slotEnd spinner sat off-center next to the chevron
and added nothing over the disabled state.
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): compare dropdown hierarchy — bold options, subdued labels, real indent [ASE-186]
- Clickable rows (collapsed lines + nested trials) are now bold; labels
(panel title + evaluation group headings) are secondary/subdued, so weight
reads as 'bold = actionable'
- Panel title gets extra bottom spacing to separate it from the list
- Fix trial indentation: SelectItem's own padding overrode a className on the
item, so indent the content (inner Text) instead
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): use valid text-color-* utilities in compare dropdown [ASE-186]
text-content-*/text-status-* aren't produced by the Foundations tailwind
plugin (it namespaces semantic text colors as text-color-*), so those class
names were silent no-ops and never subdued anything.
- Group headings -> text-color-subtle (most muted, per feedback)
- Panel title + Clear link + not-found body -> text-color-secondary
- Not-found heading -> text-color-primary; warning icon -> text-color-feedback-warning
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* style(studio): compare group headings use text-color-secondary [ASE-186]
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* fix(studio): use real short-form text color utilities in compare view [ASE-186]
text-color-* is the CSS variable name (--text-color-*), not the generated
utility; Tailwind emits the short form (text-secondary, text-primary,
text-feedback-warning). Swap all compare-view text colors to those so they
actually apply — group headings + title + Clear link now text-secondary,
not-found heading text-primary, warning icon text-feedback-warning.
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* style(studio): add child marker to nested trial rows [ASE-186]
Prefix nested trial options with a muted, decorative (aria-hidden) '↳' so
their child relationship to the evaluation heading reads at a glance. The
option's aria-label still carries the full '<evaluation> · Trial XXXXX'.
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
* test(studio): stabilize not-available compare test for slow CI [ASE-186]
The 'test case not available' branch is the terminal state, shown only
after the full group->evals->trace->run-fanout chain settles — the slowest
path. Anchor on the mounted compare view, then wait for the terminal text
with CI headroom, instead of relying on findByText's 1s default.
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
---------
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Sam Oluwalana <soluwalana@nvidia.com>
Resolve conflicts from #641 (trace comparison view) landing on main: - Keep the session-detail direction for the shared IntakeDetail components (TraceDetailView, TraceSpanAccordions). - Drop the now-orphaned trace-based comparison (EvaluationTraceDetailRoute, IntakeTraceDetailRoute): the router points at session routes and the comparison is superseded by session detail views. It is re-homed onto the session pattern in a follow-up commit. Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
…r button [ASE-186] The session-based test-case comparison refactor lost several affordances from the original trace comparison (#641) after main merged into this branch and the shared trace components resolved to the session-view versions: * The "Compare against evaluation run" selector only rendered once ?compareWith was already set, so it was unreachable. Restore it as an entry point in the single session view's header (new useSessionCompareRuns hook shared by both the single and compare views); picking a run sets ?compareWith. * Compare columns fell back to the flat span tree. Rebuild SessionCompareColumn on the read-only SpanListView so each span renders as an expandable accordion row with Attributes / Evaluation Context, per-row feedback, and expand/collapse controls — local open-state keeps the two columns from fighting over ?spanId. * Re-add the Clear button beside the selector in compare mode. Add default MSW handlers + fixtures for experiment-groups / evaluations / evaluation-sessions (the single session view now fetches sibling runs) and a regression test for the compare entry point. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
…ws [ASE-186] Reworks the trace comparison from #641 to follow the session detail model: the test-case comparison now renders two side-by-side session (test case) views instead of two trace detail views, driven by ?compareWith on the evaluation session route. Studio: * Compare inside EvaluationSessionDetailRoute via ?compareWith, rendering two SessionCompareColumns; re-key the run selector and test-case run fetching from trace_id to session_id. New useSessionCompareRuns hook is shared by the single session view and the compare view (React Query dedupes the overlapping fetches). * Restore the "Compare against evaluation run" selector as an entry point in the single session view's header — picking a run sets ?compareWith — plus the Clear button beside it in compare mode. * Render each compare column on the read-only SpanListView so spans show as expandable accordion rows (Attributes / Evaluation Context, per-row feedback, expand/collapse) with local open-state, rather than the flat span tree. * Add default MSW handlers + fixtures for experiment-groups / evaluations / evaluation-sessions and a regression test for the compare entry point. Seed: * seed_experiments_demo.py gains a cost_usd_cycle knob and a secondary-sort-fixtures group with tied per-session and aggregate costs, so the tables' secondary (tie-break) sort can be exercised locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
* feat(studio): add session telemetry detail views Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * style(studio): format session detail views Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * test(studio): stabilize linked span hydration Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * fix(studio): encode session route identifiers Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * feat(studio): render test-case comparison as side-by-side session views [ASE-186] Reworks the trace comparison from NVIDIA-NeMo#641 to follow the session detail model: the test-case comparison now renders two side-by-side session (test case) views instead of two trace detail views, driven by ?compareWith on the evaluation session route. Studio: * Compare inside EvaluationSessionDetailRoute via ?compareWith, rendering two SessionCompareColumns; re-key the run selector and test-case run fetching from trace_id to session_id. New useSessionCompareRuns hook is shared by the single session view and the compare view (React Query dedupes the overlapping fetches). * Restore the "Compare against evaluation run" selector as an entry point in the single session view's header — picking a run sets ?compareWith — plus the Clear button beside it in compare mode. * Render each compare column on the read-only SpanListView so spans show as expandable accordion rows (Attributes / Evaluation Context, per-row feedback, expand/collapse) with local open-state, rather than the flat span tree. * Add default MSW handlers + fixtures for experiment-groups / evaluations / evaluation-sessions and a regression test for the compare entry point. Seed: * seed_experiments_demo.py gains a cost_usd_cycle knob and a secondary-sort-fixtures group with tied per-session and aggregate costs, so the tables' secondary (tie-break) sort can be exercised locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> * fix flaky test Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> --------- Signed-off-by: Brian Newsom <brnewsom@nvidia.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> Co-authored-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(studio): add session telemetry detail views Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * style(studio): format session detail views Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * test(studio): stabilize linked span hydration Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * fix(studio): encode session route identifiers Signed-off-by: Brian Newsom <brnewsom@nvidia.com> * feat(studio): render test-case comparison as side-by-side session views [ASE-186] Reworks the trace comparison from NVIDIA-NeMo#641 to follow the session detail model: the test-case comparison now renders two side-by-side session (test case) views instead of two trace detail views, driven by ?compareWith on the evaluation session route. Studio: * Compare inside EvaluationSessionDetailRoute via ?compareWith, rendering two SessionCompareColumns; re-key the run selector and test-case run fetching from trace_id to session_id. New useSessionCompareRuns hook is shared by the single session view and the compare view (React Query dedupes the overlapping fetches). * Restore the "Compare against evaluation run" selector as an entry point in the single session view's header — picking a run sets ?compareWith — plus the Clear button beside it in compare mode. * Render each compare column on the read-only SpanListView so spans show as expandable accordion rows (Attributes / Evaluation Context, per-row feedback, expand/collapse) with local open-state, rather than the flat span tree. * Add default MSW handlers + fixtures for experiment-groups / evaluations / evaluation-sessions and a regression test for the compare entry point. Seed: * seed_experiments_demo.py gains a cost_usd_cycle knob and a secondary-sort-fixtures group with tied per-session and aggregate costs, so the tables' secondary (tie-break) sort can be exercised locally. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> * fix flaky test Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> --------- Signed-off-by: Brian Newsom <brnewsom@nvidia.com> Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> Co-authored-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Closes ASE-186
Screen.Recording.2026-07-22.at.08.50.28.mov
Summary
Evaluation trace detail could only show one run of a test case at a time. This adds a side-by-side comparison of the same test case across different runs.
A "Compare against evaluation run" selector in the page header lists every run (session) of the current test case across the experiment group's evaluations. Because the sessions endpoint is scoped to a single evaluation, the list is built client-side by fanning out one query per evaluation (
GET /apis/intake/v2/workspaces/{ws}/evaluations/{name}/sessions?filter[test_case_id]=<id>) and flattening — a group-scoped endpoint is the eventual replacement (fast-follow). Picking a run adds?compareWith=<traceId>to the URL and splits into a "Test case comparison — Test case <id>" page with two columns.Each column shows:
<evaluation-name> · Trial <last 5 of session id>If the selected run has no matching session, the column shows "Test case not available".
Selector UX: single-trial evaluations collapse onto one selectable line; multi-trial evaluations render the evaluation as a subdued heading with each trial indented beneath (
↳ Trial XXXXX). Every option carries anaria-labelof the full<evaluation> · Trial XXXXXso screen readers get self-describing options. Loading shows a disabled control with "Loading other runs"; no siblings shows "No runs to compare to".Rendering two trace views also required two supporting fixes:
TraceSpanAccordionsis controlled — single view binds span selection to?spanId=(deep links unchanged); compare columns render independently in list mode. Expand/collapse surface to the column header via aSlotHeaderRenderProp.Test plan
/workspaces/<ws>/experiment/<group>/<evaluation>/traces/<traceId>) → "Compare against evaluation run" selector appears in the page header (top right)↳; disabled + "Loading other runs" while loading, "No runs to compare to" when there are none?compareWith=<traceId>, page shows "Test case comparison — Test case <id>" and splits into two columns, each with the run label, per-session metrics (Cost, Latency, Tkns In/Out, Cached, evaluator scores), and the trace in list mode?spanId=updates in the URL; reload the deep link → same span selectedReviewer note (dev data): most experiment groups have a single trial per evaluation (all collapsed). For a dropdown showing both collapsed and nested entries, use workspace
bugnemo-mc, groupopt-97d7f6d1-02b5-4f34-82db-a09b3feefc0f, test casettyb-028-...bug-432.