feat(studio): Anonymizer builder Source form [ASTD-327] - #884
Conversation
|
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:
📝 WalkthroughWalkthroughThe Anonymizer Builder now uses a validated, tabbed form with source, generation, columns, entity, and model settings. It builds strategy-specific job requests, submits anonymizer runs, handles errors and navigation, and adds a feature-gated anonymizer job detail route. ChangesAnonymizer Builder
Anonymizer Job Routing
Sequence Diagram(s)sequenceDiagram
participant User
participant AnonymizerBuilderRoute
participant ModelProviders
participant buildAnonymizerJobRequest
participant useAnonymizerCreateRunJob
participant AnonymizerJobDetailRoute
User->>AnonymizerBuilderRoute: fill form
AnonymizerBuilderRoute->>ModelProviders: load workspace models
ModelProviders-->>AnonymizerBuilderRoute: return model options
User->>AnonymizerBuilderRoute: submit form
AnonymizerBuilderRoute->>buildAnonymizerJobRequest: build run request
AnonymizerBuilderRoute->>useAnonymizerCreateRunJob: create anonymizer job
useAnonymizerCreateRunJob->>AnonymizerJobDetailRoute: navigate to created job
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts (1)
4-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueNormalize TypeScript import hygiene.
web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts#L4-L13: place external imports before internal aliases.web/packages/studio/src/routes/AnonymizerBuilderRoute/components/DataSourceSection.tsx#L4-L13: place React/RHF before internal aliases and changeFCtoimport type.web/packages/studio/src/routes/AnonymizerBuilderRoute/components/GenerationSection.tsx#L4-L13: place React/RHF before internal aliases and changeFCtoimport type.web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ColumnsSection.tsx#L4-L9: place React/RHF before internal aliases and changeFCtoimport type.web/packages/studio/src/routes/AnonymizerBuilderRoute/components/EntitiesSection.tsx#L4-L13: place React/RHF before internal aliases and changeFCtoimport type.web/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsx#L4-L36: group external imports before@studioaliases and changeFCtoimport type.As per coding guidelines: “Use
import typefor type-only imports” and “Group imports: external libraries, internal modules, relative imports in TypeScript.”🤖 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/AnonymizerBuilderRoute/schema.ts` around lines 4 - 13, Normalize imports across web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts (lines 4-13), components/DataSourceSection.tsx (lines 4-13), components/GenerationSection.tsx (lines 4-13), components/ColumnsSection.tsx (lines 4-9), components/EntitiesSection.tsx (lines 4-13), and index.tsx (lines 4-36): group external imports before internal aliases, and change type-only FC imports to import type in the affected React component files and AnonymizerBuilderRoute entry point.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/AnonymizerBuilderRoute/schema.ts`:
- Line 18: Update the source field validation in the schema to trim its input
before applying the required non-empty check, ensuring whitespace-only values
are rejected consistently with the request builder.
---
Nitpick comments:
In `@web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts`:
- Around line 4-13: Normalize imports across
web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts (lines 4-13),
components/DataSourceSection.tsx (lines 4-13), components/GenerationSection.tsx
(lines 4-13), components/ColumnsSection.tsx (lines 4-9),
components/EntitiesSection.tsx (lines 4-13), and index.tsx (lines 4-36): group
external imports before internal aliases, and change type-only FC imports to
import type in the affected React component files and AnonymizerBuilderRoute
entry point.
🪄 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: 6f6a3a78-bd80-472a-805e-ac5b581d6532
📒 Files selected for processing (8)
web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ColumnsSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/DataSourceSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/EntitiesSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/GenerationSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/constants.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.test.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts
7b70822 to
f676025
Compare
|
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/routes/AnonymizerBuilderRoute/components/DataSourceSection.tsx`:
- Around line 20-21: Update the DataSourceSection effect or field-change
handling around sourceType and isDataset to reset or unregister the shared
source field whenever sourceType changes between dataset and URL. Ensure the
previous branch’s value and validation error cannot persist into the newly
selected branch, while preserving the active branch’s normal source input
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: fda31ff0-da36-4a5e-8830-5cec4aecc0d4
📒 Files selected for processing (8)
web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ColumnsSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/DataSourceSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/EntitiesSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/components/GenerationSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/constants.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.test.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts
🚧 Files skipped from review as they are similar to previous changes (7)
- web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.test.ts
- web/packages/studio/src/routes/AnonymizerBuilderRoute/components/GenerationSection.tsx
- web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ColumnsSection.tsx
- web/packages/studio/src/routes/AnonymizerBuilderRoute/components/EntitiesSection.tsx
- web/packages/studio/src/routes/AnonymizerBuilderRoute/constants.ts
- web/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsx
- web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts
f676025 to
c74824c
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts (1)
5-21: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winGroup external imports before internal aliases.
web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts: movezodabove the@nemo/@studioimports.web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ModelSettingsSection.tsx: movereact,react-hook-form, and@nvidia/foundations-react-coreabove the@nemo/@studioimports.🤖 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/AnonymizerBuilderRoute/schema.ts` around lines 5 - 21, Reorder imports so external packages precede internal aliases: in web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts lines 5-21, move zod above the `@nemo` and `@studio` imports; in web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ModelSettingsSection.tsx lines 4-12, move react, react-hook-form, and `@nvidia/foundations-react-core` above the `@nemo` and `@studio` imports. No other changes are needed.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/AnonymizerBuilderRoute/components/ModelSettingsSection.tsx`:
- Line 11: Update the React import in ModelSettingsSection to import FC as a
type-only symbol while retaining useMemo as a runtime import.
---
Outside diff comments:
In `@web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts`:
- Around line 5-21: Reorder imports so external packages precede internal
aliases: in web/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts
lines 5-21, move zod above the `@nemo` and `@studio` imports; in
web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ModelSettingsSection.tsx
lines 4-12, move react, react-hook-form, and `@nvidia/foundations-react-core`
above the `@nemo` and `@studio` imports. No other changes are needed.
🪄 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: 51b01ee8-4b7e-40a7-8c69-6e005eb25234
📒 Files selected for processing (5)
web/packages/studio/src/routes/AnonymizerBuilderRoute/components/ModelSettingsSection.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/constants.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsxweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.test.tsweb/packages/studio/src/routes/AnonymizerBuilderRoute/schema.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- web/packages/studio/src/routes/AnonymizerBuilderRoute/index.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
web/packages/studio/src/routes/AnonymizerJobDetailRoute/index.tsx (1)
4-10: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMove the React imports above the
@studioimports and markFCas a type import.
FCis type-only, andreact/react-router-domshould stay grouped with the other external imports.🤖 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/AnonymizerJobDetailRoute/index.tsx` around lines 4 - 10, Reorder the imports in AnonymizerJobDetailRoute so the external React and react-router-dom imports appear before the `@nvidia` and `@studio` imports, and import FC using type-only syntax. Keep the existing runtime imports unchanged.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 `@web/packages/studio/src/routes/AnonymizerJobDetailRoute/index.tsx`:
- Around line 4-10: Reorder the imports in AnonymizerJobDetailRoute so the
external React and react-router-dom imports appear before the `@nvidia` and
`@studio` imports, and import FC using type-only syntax. Keep the existing runtime
imports unchanged.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: cdc1366b-f9db-4bcc-9bf8-7728bc7396f3
📒 Files selected for processing (2)
web/packages/studio/src/routes/AnonymizerJobDetailRoute/index.tsxweb/packages/studio/src/routes/groups/anonymizerRoutes.tsx
7b9c57e to
e522b80
Compare
Replace the /anonymizer/new placeholder with the builder shell: a left config panel (Source / Model Settings tabs) + a preview-panel placeholder. Source tab (react-hook-form + Zod -> AnonymizerRequest): - Data Source: source type (URL | Dataset) + reference input - Generation: strategy select (substitute/redact/annotate/hash/rewrite) + description + preview rows - Columns: text column + data summary - Entities: Custom | Auto-detect toggle + include-defaults checkbox Submit via useAnonymizerCreateRunJob -> navigate to the job. Strategy is sent at its no-arg default (rewrite -> config.rewrite, others -> config.replace); strategy params, entity-label picker, model settings, and live preview are follow-ups. Gated behind VITE_FF_ANONYMIZER_ENABLED (default false). Signed-off-by: mschwab <mschwab@nvidia.com>
…-327] Model Settings tab selects an inference provider model (via useModelsListProviders / modelsFromProviders) and the create request now sends spec.model_configs plus spec.selected_models, mapping the active strategy's workflow roles (detection always; +replace for substitute; +rewrite roles for rewrite) to the single chosen model — required for remote execution. Also send the replace 'kind' discriminator tag. Verified end-to-end against a local platform: create returns 201. Signed-off-by: mschwab <mschwab@nvidia.com>
Model Settings tab now exposes one model select per workflow role (Entity Detector / Validator / Augmenter / Latent Detector, plus Replacement Generator for substitute or the rewrite roles for rewrite), matching the Figma. Roles are seeded with sensible defaults on load (GLiNER for the detector, an LLM for the rest) and validated per the selected strategy. Build dedups identical role models into a model_configs pool (one entry per unique model+provider) and maps selected_models role -> alias. Per-role inference Params dropdown is a follow-up. Signed-off-by: mschwab <mschwab@nvidia.com>
…ngs [ASTD-327] Swap the per-role model picker to ControlledSearchableSelect (the same component as the Clone Agent modal) for a searchable, grouped dropdown. Keep provider-aware options from modelsFromProviders rather than buildSuggestedModelOptions, since the latter filters out the GLiNER detector model and drops the provider that model_configs requires. Signed-off-by: mschwab <mschwab@nvidia.com>
Add a Params dropdown next to each role's model select (reusing ModelSelectV2 ParamsDropdown), storing inference parameters per role. Build attaches inference_parameters to the model_config and splits the dedup so a shared model with different params yields distinct configs. Signed-off-by: mschwab <mschwab@nvidia.com>
…[ASTD-327] Model Settings only mounted when its tab was open, so its default-model seeding never ran if the user submitted from the Source tab — surfacing a spurious 'Select a model' error. Keep both tab panels mounted (hide the inactive one) so seeding runs on load. Signed-off-by: mschwab <mschwab@nvidia.com>
Gate the Full Run button on the providers query loading state (shared with ModelSettingsSection via react-query dedup) so the user can't submit before role model defaults are seeded. Signed-off-by: mschwab <mschwab@nvidia.com>
onInvalid only switched tabs for model errors, so a Source-tab error (e.g. missing data source) while on the Model Settings tab left the submit doing nothing visible. Always jump to the offending tab and show an inline banner. Signed-off-by: mschwab <mschwab@nvidia.com>
The searchable model selects render a hidden required search input; native HTML5 validation tried to focus it on submit and blocked the form with 'invalid form control is not focusable'. Disable native validation and rely on the RHF/Zod resolver. Signed-off-by: mschwab <mschwab@nvidia.com>
Disable the Anonymization Strategy select until the other strategies' parameter UIs are built. Substitute is the default and only selectable option. Signed-off-by: mschwab <mschwab@nvidia.com>
Custom mode (without 'include all defaults') shows a multi-select of the default entity labels from useAnonymizerListEntityLabels; the selection restricts detection via config.detect.entity_labels. Auto-detect and include-defaults leave detect unset (library default set). Categorized grouping, custom-typed labels, and chip coloring are a follow-up. Signed-off-by: mschwab <mschwab@nvidia.com>
…327] Swap the Source / Model Settings tab bar from Tabs to SegmentedControl. Signed-off-by: mschwab <mschwab@nvidia.com>
…-327] When a Dataset source file is selected, read its columns (via the size-capped useDatasetFileContent + getContentColumns) and render Text Column as a dropdown of those columns. Falls back to a text input for URL sources or when the file exceeds MAX_COLUMN_INTROSPECTION_BYTES (50MB). Signed-off-by: mschwab <mschwab@nvidia.com>
…-327] The role-model seed fell back to models[0], which could be a flaky model (e.g. 01-ai/yi-large failing health checks). Use pickDefaultModelName to prefer a suggested chat model for the LLM roles. Signed-off-by: mschwab <mschwab@nvidia.com>
…TD-327] Signed-off-by: mschwab <mschwab@nvidia.com>
…TD-327] Reasoning models (e.g. nemotron-nano) exceeded the anonymizer's default per-request timeout during entity validation (ModelTimeoutError, rows dropped). Default inference_parameters.timeout to 300s on every model_config; user-supplied params still override. Signed-off-by: mschwab <mschwab@nvidia.com>
Signed-off-by: mschwab <mschwab@nvidia.com>
dad9f36 to
2b92580
Compare
…-327] The dedicated Anonymizer job page is still a placeholder (ASTD-330), so route create-success to the generic /jobs/:name detail (anonymizer jobs are platform jobs) which shows real status and logs. Signed-off-by: mschwab <mschwab@nvidia.com>
Reasoning models truncated their structured-output validation responses. Default inference_parameters.max_tokens to 16384 (matching the library gpt-oss default) so they can complete; user params override. Signed-off-by: mschwab <mschwab@nvidia.com>
…-327] Per Vercel React best practices: memoize the Text Column select options (new array each render) and hoist the static SegmentedControl tab items to module scope. Signed-off-by: mschwab <mschwab@nvidia.com>
Signed-off-by: mschwab <mschwab@nvidia.com>
…D-327] Address CodeRabbit: clear the shared source field (and its error) when the source type toggles between URL and Dataset, and trim the source in the Zod schema so whitespace-only input fails validation. Signed-off-by: mschwab <mschwab@nvidia.com>
…STD-327] Signed-off-by: mschwab <mschwab@nvidia.com>
Address review: move the generic trim helper out of the anonymizer schema into @studio/util/strings with a test. Signed-off-by: mschwab <mschwab@nvidia.com>
What
Builds the Anonymizer builder page at
/anonymizer/new(ASTD-327) — a working v1 that creates and runs real anonymization jobs. Part of ASTD-215. Builds on #876 (routes/flag) and #879 (jobs API + SDK), both merged.Layout
Left config panel (
Source/Model Settingssegmented control) + a preview-panel placeholder. React Hook Form + Zod throughout.Source tab
Dataset(fileset+file picker, csv/parquet) orURL→spec.data.sourceuseAnonymizerListEntityLabels) →config.detect.entity_labelsModel Settings tab
model_configspool and mapsselected_modelsrole → alias; defaults a generoustimeout(500s) andmax_tokens(16384) so slower models completeSubmit
Full Run→useAnonymizerCreateRunJob(sends thereplace.kinddiscriminator,model_configs,selected_models), then redirects to the platform job detail (/jobs/:name) for live status/logs until the dedicated Anonymizer job page (ASTD-330) lands. Disabled while models load; validation errors surface an inline banner and jump to the offending tab.noValidateso RHF/Zod owns validation.Verified
Create returns 201 and the job runs end-to-end against a local platform.
Scoped out (follow-up tickets, all under ASTD-215)
kind500-not-422 & missing-from-OpenAPI — ASTD-328 / ASTD-329Testing
schema.test.ts— 10 tests on the request mapper (strategy routing +kind, model_configs dedup + defaults, selected_models role mapping, detect labels). Pass.@nemo/studiotsc --noEmit— no new errors (17 pre-existing customizer-SDK, unchanged). eslint clean.VITE_FF_ANONYMIZER_ENABLED(default false).Notes