Skip to content

feat(experiments): Experiments UI misc QA#296

Open
shanaiabuggy wants to merge 7 commits into
mainfrom
sbuggy/experiment-ui-qa
Open

feat(experiments): Experiments UI misc QA#296
shanaiabuggy wants to merge 7 commits into
mainfrom
sbuggy/experiment-ui-qa

Conversation

@shanaiabuggy

@shanaiabuggy shanaiabuggy commented Jun 12, 2026

Copy link
Copy Markdown
Contributor
  • Breadcrumb root renamed from Experiments to Experiment Groups across the index, group detail, and experiment detail routes.
  • "Create experiment" modal tab renamed to Create group.
  • Data-view column Model Names renamed to Models
  • Group description now renders below the group name header on the group detail page.
  • Added an Experiments section header with a count badge above the experiments list, separated by a top border.
  • Removed per-evaluator score metrics from the group cards on the groups list page; kept only the experiment count.
  • Experiment detail KV header restructured: replaced Agent Name with Dataset Name + Dataset Version, added Models (with tooltip-on-truncate for multi-model cases), and right-justified the rollup-derived KVs (Models, Avg Cost, Avg Latency).
  • Added a Test cases section header with a count badge above the sessions list on the experiment detail page, separated by a top border (matches the Experiments header pattern).
  • Experiment row name cell tooltip now renders a structured popover with a Summary label above the summary text, instead of a bare string.
Screen.Recording.2026-06-12.at.1.09.03.AM.mov

Summary by CodeRabbit

  • New Features

    • API and UI now expose an experiment_count for experiment groups; listings and cards show experiment counts.
  • UI Improvements

    • Navigation and breadcrumbs updated to "Experiment Groups".
    • "Create" tab label changed to "Create group".
    • Experiment metrics reorganized: show Dataset, Dataset Version, Models (Agent removed).
    • Improved summary tooltips; "Model Names" column renamed to "Models".
    • Test cases and experiments sections display conditional run/exam counts; group cards simplified to show only experiment count.

Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
@shanaiabuggy shanaiabuggy requested review from a team as code owners June 12, 2026 07:07
@github-actions github-actions Bot added the feat label Jun 12, 2026
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6f3cf295-15f0-4e58-a8c6-868acd4302c9

📥 Commits

Reviewing files that changed from the base of the PR and between 57e27ea and 7c28b32.

📒 Files selected for processing (1)
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py

📝 Walkthrough

Walkthrough

Adds a server-side experiment_count to ExperimentGroupResponse and populates it in endpoints; updates breadcrumbs/modal labels to "Experiment Groups"; surfaces counts and layout/tooltip refinements across group list, detail, card, and metrics views.

Changes

Experiment Groups Count and Navigation Rebranding

Layer / File(s) Summary
Backend experiment count schema and endpoints
openapi/ga/individual/platform.openapi.yaml, openapi/ga/openapi.yaml, openapi/openapi.yaml, services/intake/src/nmp/intake/api/v2/experiments/schemas.py, services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
Adds experiment_count: integer (default 0) to ExperimentGroupResponse across OpenAPI specs and Pydantic schema; endpoints import asyncio, add _count_live_experiments_in_group, and populate experiment_count in list_experiment_groups, get_experiment_group, and update_experiment_group (concurrent aggregation for lists).
Breadcrumb and modal label updates
web/packages/studio/src/components/ExperimentGroupCreateModal/index.tsx, web/packages/studio/src/routes/ExperimentRoute/index.tsx, web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx
Renames UI text from "Experiments" to "Experiment Groups" in breadcrumbs and changes create-tab label to "Create group".
Experiment detail and group-detail route integration
web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx, web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx
ExperimentDetailRoute wraps sessions in a "Test cases" header with optional experiment.run_count Badge. ExperimentGroupDetailRoute loads group via useGetExperimentGroup, sets PageHeader.slotDescription from group?.description, and displays an "Experiments" header with conditional Badge(group.experiment_count).
Data view tooltip and metrics layout updates
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx, web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx
ExperimentGroupDataView changes Name tooltip to a labeled JSX body and renames "Model Names" → "Models". ExperimentDetailMetrics adds a "Models" KVPair (tooltip + truncated Text for multiple names), imports Flex/Text/Tooltip/tooltipClassName/ReactNode, and restructures metrics into two grouped columns adding Dataset Name/Version while removing Agent Name.
Group card simplification with server counts
web/packages/studio/src/routes/ExperimentRoute/ExperimentGroupCard.tsx
Removes Divider import and client-side experiment fetching/aggregation; Stats now shows a single "Experiments" metric using group.experiment_count (default 0).

Possibly Related PRs

Suggested Reviewers

  • walston
  • nakolean
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive Title is vague and generic, using 'misc QA' without specifying the actual changes made to experiments UI. Replace 'misc QA' with a specific change descriptor, e.g., 'Restructure experiment groups UI and metrics layout' or 'Rename experiment breadcrumb navigation and reorganize group cards'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sbuggy/experiment-ui-qa

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx (1)

19-19: 🏗️ Heavy lift

Handle loading and error states for useGetExperimentGroup.

ExperimentRoute explicitly handles loading/error states; this route should follow the same pattern for consistency.

♻️ Suggested implementation pattern

Destructure isLoading and error:

- const { data: group } = useGetExperimentGroup(workspace, experimentGroupName);
+ const { data: group, isLoading, error } = useGetExperimentGroup(workspace, experimentGroupName);

Add loading and error UI before the main render (similar to ExperimentRoute/index.tsx lines 47-61):

+ if (isLoading) {
+   return <Loading description="Loading experiment group..." />;
+ }
+
+ if (error) {
+   return (
+     <StatusMessage
+       className="mx-auto mt-density-2xl"
+       size="medium"
+       slotMedia={<CircleAlert width={65} height={65} />}
+       slotHeading="Error loading experiment group"
+       slotSubheading={error.message}
+     />
+   );
+ }
🤖 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/ExperimentGroupDetailRoute/index.tsx` at line
19, The hook call in ExperimentGroupDetailRoute only reads data and misses
loading/error handling; update the useGetExperimentGroup call to destructure
isLoading and error (e.g., const { data: group, isLoading, error } =
useGetExperimentGroup(workspace, experimentGroupName)), then add an early return
before the main render that shows the same loading UI when isLoading is true and
an error UI when error is present (matching the pattern used in ExperimentRoute)
so the component consistently handles fetch states.
web/packages/studio/src/routes/ExperimentRoute/ExperimentGroupCard.tsx (1)

26-26: ⚡ Quick win

Consider handling loading/error states for experiment count.

When the experiments query is loading or fails, the count defaults to "0", which users can't distinguish from an actual zero count. Destructuring isLoading and error from the hook would allow you to show a skeleton, error indicator, or placeholder.

💡 Example enhancement
- const { data: experimentsData } = useListExperiments(workspace, {
+ const { data: experimentsData, isLoading: isLoadingCount, error: countError } = useListExperiments(workspace, {
    filter: { experiment_group_id: group.id },
    page_size: 1,
  });

- const experimentCount = experimentsData?.pagination?.total_results ?? 0;
+ const experimentCount = isLoadingCount 
+   ? '...' 
+   : countError 
+   ? '—' 
+   : String(experimentsData?.pagination?.total_results ?? 0);

Then render as:

- <Metric title="Experiments" value={String(experimentCount)} />
+ <Metric title="Experiments" value={experimentCount} />
🤖 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/ExperimentRoute/ExperimentGroupCard.tsx` at
line 26, The experiments count currently falls back to 0 via the experimentCount
= experimentsData?.pagination?.total_results ?? 0 assignment, which hides
loading/error states; update the hook call inside ExperimentGroupCard to
destructure isLoading and error (e.g., const { data: experimentsData, isLoading,
error } = useYourExperimentsHook(...)), then replace direct rendering of
experimentCount with conditional rendering: show a skeleton/placeholder while
isLoading, an error indicator when error is truthy, and only use
experimentsData?.pagination?.total_results when neither loading nor error; keep
the experimentCount variable but only compute it when not loading/error to avoid
showing a misleading 0.
🤖 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 `@web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx`:
- Line 19: The hook call in ExperimentGroupDetailRoute only reads data and
misses loading/error handling; update the useGetExperimentGroup call to
destructure isLoading and error (e.g., const { data: group, isLoading, error } =
useGetExperimentGroup(workspace, experimentGroupName)), then add an early return
before the main render that shows the same loading UI when isLoading is true and
an error UI when error is present (matching the pattern used in ExperimentRoute)
so the component consistently handles fetch states.

In `@web/packages/studio/src/routes/ExperimentRoute/ExperimentGroupCard.tsx`:
- Line 26: The experiments count currently falls back to 0 via the
experimentCount = experimentsData?.pagination?.total_results ?? 0 assignment,
which hides loading/error states; update the hook call inside
ExperimentGroupCard to destructure isLoading and error (e.g., const { data:
experimentsData, isLoading, error } = useYourExperimentsHook(...)), then replace
direct rendering of experimentCount with conditional rendering: show a
skeleton/placeholder while isLoading, an error indicator when error is truthy,
and only use experimentsData?.pagination?.total_results when neither loading nor
error; keep the experimentCount variable but only compute it when not
loading/error to avoid showing a misleading 0.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e9fbe7ce-a26e-47ed-8626-3366699b90bd

📥 Commits

Reviewing files that changed from the base of the PR and between 2e8878f and 27d1b0b.

📒 Files selected for processing (8)
  • web/packages/studio/src/components/ExperimentGroupCreateModal/index.tsx
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx
  • web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx
  • web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx
  • web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx
  • web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx
  • web/packages/studio/src/routes/ExperimentRoute/ExperimentGroupCard.tsx
  • web/packages/studio/src/routes/ExperimentRoute/index.tsx

@github-actions

github-actions Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 19033/25227 75.4% 61.3%
Integration Tests 11028/23999 46.0% 20.4%

Comment thread web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx Outdated
Comment thread web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx Outdated
Comment thread web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx Outdated
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@services/intake/src/nmp/intake/api/v2/experiments/endpoints.py`:
- Around line 185-189: The update path returns
ExperimentGroupResponse.from_entity(updated) without populating
experiment_count, causing inconsistent responses; update the
update_experiment_group handler to set response.experiment_count the same way as
the other endpoint by calling await
_count_live_experiments_in_group(entity_client, workspace=workspace,
group_id=updated.id) and assigning it to the response returned (i.e., after
creating response = ExperimentGroupResponse.from_entity(updated) set
response.experiment_count = ...), ensuring you use the same workspace and
entity_client variables as the other endpoint.
- Around line 150-155: The code is doing an unbounded fan-out by calling
_count_live_experiments_in_group once per group (the asyncio.gather over
_count_live_experiments_in_group for each g in result.data), which creates an
N+1 hotspot; replace the per-group parallel calls with a single batched/grouped
count call that accepts all group IDs and returns counts per group (e.g.
implement count_live_experiments_by_group(entity_client, workspace, group_ids)
that issues one query with GROUP BY or an IN filter and maps results to group
IDs), then use that mapping to populate counts for each g in result.data instead
of awaiting many separate _count_live_experiments_in_group calls. Ensure callers
of counts use the new mapping and that page_size/large result pages are handled
efficiently.
🪄 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: 07df0815-9fdd-4fed-a838-4f2a86df2622

📥 Commits

Reviewing files that changed from the base of the PR and between 5dae609 and 045e622.

📒 Files selected for processing (10)
  • openapi/ga/individual/platform.openapi.yaml
  • openapi/ga/openapi.yaml
  • openapi/openapi.yaml
  • services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
  • services/intake/src/nmp/intake/api/v2/experiments/schemas.py
  • web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx
  • web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx
  • web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx
  • web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx
  • web/packages/studio/src/routes/ExperimentRoute/ExperimentGroupCard.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/packages/studio/src/routes/ExperimentGroupDetailRoute/index.tsx
  • web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx

Comment thread services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
Comment thread services/intake/src/nmp/intake/api/v2/experiments/endpoints.py
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Signed-off-by: shanaiabuggy <59746633+shanaiabuggy@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants