feat(studio): v0 experiment detail page - #260
Conversation
📝 WalkthroughWalkthroughAdds an experiment detail route and page at /workspaces/:workspace/experiment/:experimentGroupName/:experimentName with a metrics header and a paginated sessions table; enables row-click navigation from the experiment group list and provides an empty-state CLI/tab component, route helpers, docs link, and test update. ChangesExperiment Detail Page
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/packages/studio/src/routes/utils.ts (1)
324-334: 💤 Low valueAdd explicit return type.
Public route utilities should have explicit return types per TypeScript guidelines.
📝 Proposed fix
-export const getExperimentDetailRoute = ( +export const getExperimentDetailRoute = ( workspace: string, experimentGroupName: string, experimentName: string -) => { +): string => { return generatePath(ROUTES.workspace.experimentDetail, {🤖 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/utils.ts` around lines 324 - 334, The getExperimentDetailRoute function lacks an explicit return type; update its signature to declare the return type string (i.e., make getExperimentDetailRoute(...) : string) so callers and the compiler have an explicit type for the value produced by generatePath(ROUTES.workspace.experimentDetail, ...). Keep the implementation unchanged and ensure TypeScript infers the returned value matches string.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.
Inline comments:
In
`@web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx`:
- Around line 36-50: The Created and Updated KVPair components are missing the
loading prop, causing inconsistent skeletons; update the two KVPair instances
(the ones with label="Created" and label="Updated" that render RelativeTime) to
include the same loading prop used by the other fields (e.g., loading={loading}
or loading={isLoading} depending on the surrounding variable) so they show
skeletons during load, keeping the existing value logic (experiment?.created_at
/ experiment?.updated_at ? <RelativeTime .../> : undefined).
---
Nitpick comments:
In `@web/packages/studio/src/routes/utils.ts`:
- Around line 324-334: The getExperimentDetailRoute function lacks an explicit
return type; update its signature to declare the return type string (i.e., make
getExperimentDetailRoute(...) : string) so callers and the compiler have an
explicit type for the value produced by
generatePath(ROUTES.workspace.experimentDetail, ...). Keep the implementation
unchanged and ensure TypeScript infers the returned value matches string.
🪄 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: 08c215d1-df04-41f5-b5a1-4279ec1e90ec
📒 Files selected for processing (8)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsxweb/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsxweb/packages/studio/src/constants/routes.tsweb/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsxweb/packages/studio/src/routes/ExperimentDetailRoute/index.tsxweb/packages/studio/src/routes/index.tsxweb/packages/studio/src/routes/utils.tsweb/packages/studio/src/tests/title-change.spec.tsx
|
4c75f14 to
0360a77
Compare
There was a problem hiding this comment.
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
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx`:
- Around line 59-63: The columnVisibility includes updated_at but the
filter/columns in makeColumns only define created_by; remove updated_at from the
columnVisibility object used in useStudioDataViewState<ExperimentFilter> (and
update the adjacent comment to only mention created_by as filter-only) so the
visibility config matches the actual columns, or alternatively if updated_at is
intended to be filter-only, add its filter-only column id to makeColumns; update
the comment to reflect whichever choice you make.
In
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx`:
- Around line 57-62: The data-fetch call using useListExperimentSessions
currently ignores the error flag, so failures render as empty UI; update the
code that builds requestStatus for StudioDataView to include isError from
useListExperimentSessions (alongside isLoading and data) so error state is
propagated to StudioDataView; locate the useListExperimentSessions hook
invocation (const { data: sessionsResponse, isLoading } =
useListExperimentSessions(...)) and add isError to the destructure, then pass
that isError into the requestStatus object used when rendering StudioDataView
(also update the other occurrence at the second use of useListExperimentSessions
around the referenced lines 184-185).
🪄 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: 22353dbe-c0ab-4eba-be1d-84af9a7d55d8
📒 Files selected for processing (9)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsxweb/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsxweb/packages/studio/src/constants/links.tsweb/packages/studio/src/constants/routes.tsweb/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsxweb/packages/studio/src/routes/ExperimentDetailRoute/index.tsxweb/packages/studio/src/routes/index.tsxweb/packages/studio/src/routes/utils.tsweb/packages/studio/src/tests/title-change.spec.tsx
✅ Files skipped from review due to trivial changes (1)
- web/packages/studio/src/constants/links.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- web/packages/studio/src/constants/routes.ts
- web/packages/studio/src/routes/index.tsx
- web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx
- web/packages/studio/src/routes/utils.ts
- web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
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
`@web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx`:
- Around line 59-63: The columnVisibility includes updated_at but the
filter/columns in makeColumns only define created_by; remove updated_at from the
columnVisibility object used in useStudioDataViewState<ExperimentFilter> (and
update the adjacent comment to only mention created_by as filter-only) so the
visibility config matches the actual columns, or alternatively if updated_at is
intended to be filter-only, add its filter-only column id to makeColumns; update
the comment to reflect whichever choice you make.
In
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx`:
- Around line 57-62: The data-fetch call using useListExperimentSessions
currently ignores the error flag, so failures render as empty UI; update the
code that builds requestStatus for StudioDataView to include isError from
useListExperimentSessions (alongside isLoading and data) so error state is
propagated to StudioDataView; locate the useListExperimentSessions hook
invocation (const { data: sessionsResponse, isLoading } =
useListExperimentSessions(...)) and add isError to the destructure, then pass
that isError into the requestStatus object used when rendering StudioDataView
(also update the other occurrence at the second use of useListExperimentSessions
around the referenced lines 184-185).
🪄 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: 22353dbe-c0ab-4eba-be1d-84af9a7d55d8
📒 Files selected for processing (9)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsxweb/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsxweb/packages/studio/src/constants/links.tsweb/packages/studio/src/constants/routes.tsweb/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsxweb/packages/studio/src/routes/ExperimentDetailRoute/index.tsxweb/packages/studio/src/routes/index.tsxweb/packages/studio/src/routes/utils.tsweb/packages/studio/src/tests/title-change.spec.tsx
✅ Files skipped from review due to trivial changes (1)
- web/packages/studio/src/constants/links.ts
🚧 Files skipped from review as they are similar to previous changes (5)
- web/packages/studio/src/constants/routes.ts
- web/packages/studio/src/routes/index.tsx
- web/packages/studio/src/routes/ExperimentDetailRoute/index.tsx
- web/packages/studio/src/routes/utils.ts
- web/packages/studio/src/routes/ExperimentDetailRoute/ExperimentDetailMetrics.tsx
🛑 Comments failed to post (2)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx (1)
59-63:
⚠️ Potential issue | 🟡 Minor🧩 Analysis chain
🏁 Script executed:
#!/bin/bash # Check if updated_at is referenced or used elsewhere in experiment-related code. rg -nC3 'updated_at' --type=ts --type=tsx -g '!node_modules' -g '**/experiment**'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 97
🏁 Script executed:
#!/bin/bash set -euo pipefail FILE="web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx" echo "=== Grep for updated_at in target file ===" rg -n --hidden --no-ignore-vcs 'updated_at' "$FILE" || true echo echo "=== Show surrounding makeColumns definition (updated_at context) ===" # Print around any makeColumns usage if present rg -n 'makeColumns' "$FILE" || true rg -n -C 5 'columnVisibility' "$FILE" || true echo echo "=== Locate created_by column definition area ===" rg -n -C 5 'created_by' "$FILE" || trueRepository: NVIDIA-NeMo/nemo-platform
Length of output: 2482
🏁 Script executed:
#!/bin/bash set -euo pipefail FILE="web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx" echo "=== Grep for updated_at in target file ===" rg -n --hidden --no-ignore-vcs 'updated_at' "$FILE" || true echo echo "=== Show surrounding makeColumns definition (updated_at context) ===" rg -n 'makeColumns' "$FILE" || true rg -n -C 5 'columnVisibility' "$FILE" || true echo echo "=== Locate created_by column definition area ===" rg -n -C 5 'created_by' "$FILE" || true echo echo "=== Dump nearby lines around the reported snippet (lines 45-90) ===" nl -ba "$FILE" | sed -n '45,90p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 2613
🏁 Script executed:
#!/bin/bash set -euo pipefail FILE="web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx" echo "=== Grep for updated_at in target file ===" rg -n --hidden --no-ignore-vcs 'updated_at' "$FILE" || true echo echo "=== Show surrounding makeColumns definition (updated_at context) ===" rg -n 'makeColumns' "$FILE" || true rg -n -C 5 'columnVisibility' "$FILE" || true echo echo "=== Locate created_by column definition area ===" rg -n -C 5 'created_by' "$FILE" || true echo echo "=== Dump nearby lines around the reported snippet (lines 45-90) ===" nl -ba "$FILE" | sed -n '45,90p'Repository: NVIDIA-NeMo/nemo-platform
Length of output: 2613
🏁 Script executed:
#!/bin/bash set -euo pipefail FILE="web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsx" rg -n "id:\\s*'updated_at'|updatedAt|UPDATED_AT|updated-at|updated at" "$FILE" || trueRepository: NVIDIA-NeMo/nemo-platform
Length of output: 51
Fix
updated_atvisibility/comment mismatch.
columnVisibilityincludes{ updated_at: false }and the comment saysupdated_atis filter-only, butmakeColumnsonly defines the filter-only columncreated_by(noupdated_atcolumn/filter id). Removeupdated_atfromcolumnVisibilityand adjust the comment, or add the missingupdated_atfilter-only column.🤖 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/components/dataViews/ExperimentGroupDataView/index.tsx` around lines 59 - 63, The columnVisibility includes updated_at but the filter/columns in makeColumns only define created_by; remove updated_at from the columnVisibility object used in useStudioDataViewState<ExperimentFilter> (and update the adjacent comment to only mention created_by as filter-only) so the visibility config matches the actual columns, or alternatively if updated_at is intended to be filter-only, add its filter-only column id to makeColumns; update the comment to reflect whichever choice you make.web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx (1)
57-62:
⚠️ Potential issue | 🟠 Major | ⚡ Quick winPropagate query error state to
StudioDataView.Failed session fetches are currently treated as non-error UI states, so users can see “No test cases” instead of an error panel. Pass
isErrorthroughrequestStatus.Suggested fix
- const { data: sessionsResponse, isLoading } = useListExperimentSessions( + const { data: sessionsResponse, isLoading, isError } = useListExperimentSessions( workspace, experimentName, { page, page_size: pageSize }, { query: { placeholderData: keepPreviousData } } ); ... - requestStatus: isLoading && !sessionsData ? 'loading' : undefined, + requestStatus: isError ? 'error' : isLoading && !sessionsData ? 'loading' : undefined,Also applies to: 184-185
🤖 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/components/dataViews/ExperimentSessionsDataView/index.tsx` around lines 57 - 62, The data-fetch call using useListExperimentSessions currently ignores the error flag, so failures render as empty UI; update the code that builds requestStatus for StudioDataView to include isError from useListExperimentSessions (alongside isLoading and data) so error state is propagated to StudioDataView; locate the useListExperimentSessions hook invocation (const { data: sessionsResponse, isLoading } = useListExperimentSessions(...)) and add isError to the destructure, then pass that isError into the requestStatus object used when rendering StudioDataView (also update the other occurrence at the second use of useListExperimentSessions around the referenced lines 184-185).
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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
`@web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/Empty.tsx`:
- Around line 4-15: Reorder the import block so all external third-party
packages come first and internal project modules follow: move the
`@nvidia/foundations-react-core` imports (Button, CodeSnippet, TabsContent,
TabsList, TabsRoot, TabsTrigger, Text) and the lucide-react icon imports (Bot,
ChevronRight, File, FlaskConical, Terminal) above the internal imports; keep the
`@nemo/common` TableEmptyState and the `@studio/constants/links`
LINK_DOCS_EXPERIMENTS_CLI imports after those external imports; preserve
existing named imports and spacing while applying this ordering.
🪄 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: 4d0d3f46-9b66-4edf-8235-4392c7af914f
📒 Files selected for processing (3)
web/packages/studio/src/components/dataViews/ExperimentGroupDataView/index.tsxweb/packages/studio/src/components/dataViews/ExperimentSessionsDataView/Empty.tsxweb/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- web/packages/studio/src/components/dataViews/ExperimentSessionsDataView/index.tsx
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…, and ExperimentSessionsDataView Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…p view Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…ExperimentDetailMetrics Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…e with dynamic group and dataset Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…tate - Remove leftover conflict marker from ExperimentGroupDataView - Add tabbed CLI/coding-agent empty state to ExperimentSessionsDataView - Add LINK_DOCS_EXPERIMENTS_CLI constant Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
Signed-off-by: Nathan Walston <nwalston@nvidia.com>
…wClick Signed-off-by: Nathan Walston <nwalston@nvidia.com>
2de4656 to
531c967
Compare
Closes FP-184
Screen.Recording.2026-06-10.at.15.02.33.mov
Summary
Studio had no detail view for individual experiments — clicking an experiment row in the group detail table had no destination. This adds the v0 `ExperimentDetailRoute` at `/workspaces/:workspace/experiment/:experimentGroupName/:experimentName`, along with the route constant, utility function, and lazy-loaded registration.
The detail page shows a metadata bar (Agent Name, Created, Updated, Avg Cost, Avg Latency) sourced from `useGetExperiment`, and a paginated test cases table via `useListExperimentSessions` with columns: Case, Input, Started at, Ended at, Latency, Status, Tokens, Cost, and Evaluator scores. Long Case, Input, and Evaluator score values truncate with a tooltip. The `success` span status is mapped to the `completed` badge style. Row clicks in `ExperimentGroupDataView` now navigate to the new route.
Test plan
Summary by CodeRabbit
New Features
Documentation
Tests