Skip to content

feat(studio): DD AI config - #961

Closed
steramae-nvidia wants to merge 2 commits into
mainfrom
steramae/ai-dd-details
Closed

feat(studio): DD AI config#961
steramae-nvidia wants to merge 2 commits into
mainfrom
steramae/ai-dd-details

Conversation

@steramae-nvidia

@steramae-nvidia steramae-nvidia commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

This PR adds the ability to create a DD config and subsequent DD job with natural language

Signed-off-by: Sean Teramae steramae@nvidia.com

Summary by CodeRabbit

  • New Features

    • Added “Describe with AI” as a new way to create data designer jobs.
    • Users can select an AI model, describe their dataset, and generate a job configuration.
    • Added validation feedback, warnings, raw configuration preview, and options to fix issues or regenerate.
    • Valid configurations now open directly in the job builder.
    • Continue remains disabled until required selections or a valid AI-generated configuration are available.
  • Bug Fixes

    • Improved handling of model selection, configuration validation, missing columns, and invalid settings.
    • Added sensible defaults for missing dataset names and invalid row counts.

@steramae-nvidia

Copy link
Copy Markdown
Contributor Author

This change is part of the following stack:

Change managed by git-spice.

@github-actions github-actions Bot added the feat label Jul 28, 2026
@steramae-nvidia
steramae-nvidia force-pushed the steramae/model-fetch-perf branch from 552f2e7 to bb7a44a Compare July 29, 2026 16:37
@steramae-nvidia
steramae-nvidia force-pushed the steramae/ai-dd-details branch from ed71c61 to 482d7c6 Compare July 29, 2026 16:37
Base automatically changed from steramae/model-fetch-perf to main July 29, 2026 21:31
@steramae-nvidia
steramae-nvidia force-pushed the steramae/ai-dd-details branch from 482d7c6 to 966ae02 Compare July 29, 2026 21:44
@github-actions

github-actions Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 29341/37347 78.6% 63.2%
Integration Tests 17281/36065 47.9% 20.5%

@steramae-nvidia
steramae-nvidia marked this pull request as ready for review July 29, 2026 22:16
@steramae-nvidia
steramae-nvidia requested review from a team as code owners July 29, 2026 22:16
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an AI-assisted Data Designer flow that generates and validates job configurations, supports fixing validation issues, gates continuation on valid output, and seeds the build route through navigation state.

Changes

AI generation and continuation

Layer / File(s) Summary
Generation contracts and completion flow
web/packages/studio/src/components/CreateFilesetStart/types.ts, web/packages/studio/src/components/CreateFilesetStart/useDescribeWithAi.ts, web/packages/studio/src/components/CreateFilesetStart/fixRequest.ts, web/packages/studio/src/components/NewDataDesignerJobForm/*, web/packages/studio/src/components/CreateFilesetStart/useDescribeWithAi.test.tsx
Adds AI form, validation, tool-call generation, raw-output retention, correction requests, and related tests.
AI panel and continuation gating
web/packages/studio/src/components/CreateFilesetStart/*
Enables the AI option, renders generation results and raw configuration, and only enables Continue after a valid generated request. Tests cover generation, validation, fixing, and selection behavior.

Generated job seeding

Layer / File(s) Summary
Generated request validation and seeding
web/packages/studio/src/routes/DataDesignerJobBuildRoute/aiSeed.ts, web/packages/studio/src/routes/DataDesignerJobBuildRoute/aiSeed.test.ts
Validates and normalizes generated requests, resolves model configurations, reports warnings and errors, and converts requests into builder seed data.

Route integration

Layer / File(s) Summary
AI selection navigation and builder initialization
web/packages/studio/src/routes/NewDataDesignerJobRoute/index.tsx, web/packages/studio/src/routes/DataDesignerJobBuildRoute/*
Passes AI selections through router state and initializes the build route from the generated request, with corresponding route tests.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CreateFilesetStart
  participant NewDataDesignerJobRoute
  participant DataDesignerJobBuildRoute
  User->>CreateFilesetStart: select AI and generate config
  CreateFilesetStart->>NewDataDesignerJobRoute: continue with jobRequest
  NewDataDesignerJobRoute->>DataDesignerJobBuildRoute: navigate with generatedJobRequest
  DataDesignerJobBuildRoute->>DataDesignerJobBuildRoute: validate and seed request
  DataDesignerJobBuildRoute-->>User: render initialized builder
Loading

Possibly related PRs

Suggested reviewers: htolentino-nvidia, nv-odrulea, aray12

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is related to the main change: adding AI-driven Data Designer configuration support in studio.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch steramae/ai-dd-details

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
web/packages/studio/src/components/CreateFilesetStart/fixRequest.ts (1)

7-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make repair inputs immutable.

buildFixMessages only reads this contract. Mark its fields and arrays readonly.

Proposed fix
 export interface FixRequestInput {
-  prompt: string;
-  config: string;
-  errors: string[];
-  warnings: string[];
+  readonly prompt: string;
+  readonly config: string;
+  readonly errors: readonly string[];
+  readonly warnings: readonly string[];
 }
 
-const bulletList = (items: string[]): string => items.map((item) => `- ${item}`).join('\n');
+const bulletList = (items: readonly string[]): string =>
+  items.map((item) => `- ${item}`).join('\n');

As per coding guidelines: “Use readonly for immutable properties in TypeScript interfaces and types.”

🤖 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/CreateFilesetStart/fixRequest.ts` around
lines 7 - 18, Update the FixRequestInput interface fields to readonly, including
the errors and warnings array properties, so buildFixMessages receives an
immutable repair request contract while preserving the existing field types and
behavior.

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/components/CreateFilesetStart/useDescribeWithAi.test.tsx`:
- Around line 12-16: Hoist the mock function used by the useChatCompletion mock
by defining mutateAsync through vi.hoisted before the vi.mock declaration.
Update the existing mutateAsync reference in the test so the mocked hook
continues returning it without accessing an uninitialized const during module
import.

In `@web/packages/studio/src/routes/DataDesignerJobBuildRoute/aiSeed.ts`:
- Around line 67-72: Update seedFromJobRequest to handle an undefined
jobRequest.spec consistently: guard access to spec.config and
spec.config.model_configs, and provide the established empty/default behavior
expected by buildColumnsFromConfig and buildModelsFromConfig. Preserve current
num_records and name fallbacks while ensuring the exported function does not
throw when spec is absent.

---

Nitpick comments:
In `@web/packages/studio/src/components/CreateFilesetStart/fixRequest.ts`:
- Around line 7-18: Update the FixRequestInput interface fields to readonly,
including the errors and warnings array properties, so buildFixMessages receives
an immutable repair request contract while preserving the existing field types
and behavior.
🪄 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: c13649f0-c1ff-4d78-9a47-ca7397fb8e39

📥 Commits

Reviewing files that changed from the base of the PR and between b861b34 and 966ae02.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (19)
  • web/packages/studio/src/components/CreateFilesetStart/DescribeWithAiPanel.tsx
  • web/packages/studio/src/components/CreateFilesetStart/GeneratedConfigPanel.tsx
  • web/packages/studio/src/components/CreateFilesetStart/GeneratedConfigResult.test.tsx
  • web/packages/studio/src/components/CreateFilesetStart/GeneratedConfigResult.tsx
  • web/packages/studio/src/components/CreateFilesetStart/StartOptionDetail.tsx
  • web/packages/studio/src/components/CreateFilesetStart/constants.ts
  • web/packages/studio/src/components/CreateFilesetStart/fixRequest.ts
  • web/packages/studio/src/components/CreateFilesetStart/index.test.tsx
  • web/packages/studio/src/components/CreateFilesetStart/index.tsx
  • web/packages/studio/src/components/CreateFilesetStart/types.ts
  • web/packages/studio/src/components/CreateFilesetStart/useDescribeWithAi.test.tsx
  • web/packages/studio/src/components/CreateFilesetStart/useDescribeWithAi.ts
  • web/packages/studio/src/components/NewDataDesignerJobForm/constants.ts
  • web/packages/studio/src/components/NewDataDesignerJobForm/tools.ts
  • web/packages/studio/src/routes/DataDesignerJobBuildRoute/aiSeed.test.ts
  • web/packages/studio/src/routes/DataDesignerJobBuildRoute/aiSeed.ts
  • web/packages/studio/src/routes/DataDesignerJobBuildRoute/index.test.tsx
  • web/packages/studio/src/routes/DataDesignerJobBuildRoute/index.tsx
  • web/packages/studio/src/routes/NewDataDesignerJobRoute/index.tsx

Comment on lines +12 to +16
const mutateAsync = vi.fn();

vi.mock('@nemo/common/src/hooks/useChatCompletion', () => ({
useChatCompletion: () => ({ mutateAsync, isPending: false }),
}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Vitest official documentation: can a vi.mock factory reference a top-level const declared outside the factory, and how should vi.hoisted be used?

💡 Result:

No, a vi.mock factory cannot directly reference top-level const variables declared outside the factory [1][2]. This is because vi.mock calls are hoisted to the top of the file and executed before other code, meaning any external variables referenced within the factory would be in the Temporal Dead Zone (TDZ) or undefined at the time of execution [3][1]. To use variables inside a vi.mock factory, you should use the vi.hoisted utility [1][2]. How to use vi.hoisted: 1. Define variables with vi.hoisted: Call vi.hoisted at the top level of your file, before any vi.mock calls [1][2][4]. This function accepts a factory that returns the values you need to share [3][4]. 2. Reference hoisted values: The values returned by vi.hoisted are moved to the top of the file alongside the mock, making them accessible both inside the vi.mock factory and within your test code [3][4]. Example usage: import { vi, expect, test } from 'vitest'; // Define hoisted variables const { myMockedValue } = vi.hoisted( => ({ myMockedValue: vi.fn, })); // Use hoisted variables inside vi.mock vi.mock('./my-module', => ({ someExport: myMockedValue, })); test('my test', => { myMockedValue.mockReturnValue(123); //... test implementation }); Alternatively, if you do not want to use hoisting, you can use vi.doMock, which is not hoisted and allows access to local variables, though it only affects subsequent dynamic imports [1][2].

Citations:


Hoist the mock value. vi.mock is hoisted, so this const is read before initialization and can break the test file on import. Use vi.hoisted here.

🤖 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/CreateFilesetStart/useDescribeWithAi.test.tsx`
around lines 12 - 16, Hoist the mock function used by the useChatCompletion mock
by defining mutateAsync through vi.hoisted before the vi.mock declaration.
Update the existing mutateAsync reference in the test so the mocked hook
continues returning it without accessing an uninitialized const during module
import.

Comment on lines +67 to +72
export const seedFromJobRequest = (jobRequest: DataDesignerJobRequest): JobBuilderSeed => ({
name: jobRequest.name?.trim() || DEFAULT_GENERATED_NAME,
rows: String(jobRequest.spec?.num_records ?? DEFAULT_GENERATED_ROWS),
columns: buildColumnsFromConfig(jobRequest.spec.config),
models: buildModelsFromConfig(jobRequest.spec.config.model_configs),
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Inconsistent null-safety on jobRequest.spec.

jobRequest.spec?.num_records is optional-chained but jobRequest.spec.config right below isn't. If spec is ever undefined (it's unknown-derived data from getGeneratedJobRequestFromState, which only checks 'spec' in request, not that the value is truthy), this exported function throws instead of degrading gracefully. Current callers (index.tsx) guard with generatedRequest?.spec ?, but that's an external contract this function shouldn't rely on.

🛡️ Proposed fix
 export const seedFromJobRequest = (jobRequest: DataDesignerJobRequest): JobBuilderSeed => ({
   name: jobRequest.name?.trim() || DEFAULT_GENERATED_NAME,
   rows: String(jobRequest.spec?.num_records ?? DEFAULT_GENERATED_ROWS),
-  columns: buildColumnsFromConfig(jobRequest.spec.config),
-  models: buildModelsFromConfig(jobRequest.spec.config.model_configs),
+  columns: buildColumnsFromConfig(jobRequest.spec?.config),
+  models: buildModelsFromConfig(jobRequest.spec?.config?.model_configs),
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const seedFromJobRequest = (jobRequest: DataDesignerJobRequest): JobBuilderSeed => ({
name: jobRequest.name?.trim() || DEFAULT_GENERATED_NAME,
rows: String(jobRequest.spec?.num_records ?? DEFAULT_GENERATED_ROWS),
columns: buildColumnsFromConfig(jobRequest.spec.config),
models: buildModelsFromConfig(jobRequest.spec.config.model_configs),
});
export const seedFromJobRequest = (jobRequest: DataDesignerJobRequest): JobBuilderSeed => ({
name: jobRequest.name?.trim() || DEFAULT_GENERATED_NAME,
rows: String(jobRequest.spec?.num_records ?? DEFAULT_GENERATED_ROWS),
columns: buildColumnsFromConfig(jobRequest.spec?.config),
models: buildModelsFromConfig(jobRequest.spec?.config?.model_configs),
});
🤖 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/DataDesignerJobBuildRoute/aiSeed.ts` around
lines 67 - 72, Update seedFromJobRequest to handle an undefined jobRequest.spec
consistently: guard access to spec.config and spec.config.model_configs, and
provide the established empty/default behavior expected by
buildColumnsFromConfig and buildModelsFromConfig. Preserve current num_records
and name fallbacks while ensuring the exported function does not throw when spec
is absent.

Signed-off-by: Sean Teramae <steramae@nvidia.com>
@steramae-nvidia
steramae-nvidia force-pushed the steramae/ai-dd-details branch from 966ae02 to 9cbed7c Compare July 31, 2026 18:30
Signed-off-by: Sean Teramae <steramae@nvidia.com>
@steramae-nvidia

Copy link
Copy Markdown
Contributor Author

Closing since other PRs got merged

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.

1 participant