You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
RunConfig controls operational behavior for a generation run, but data-designer create cannot load one from a file. Python callers can construct a RunConfig and call DataDesigner.set_run_config(...); CLI users must instead write a wrapper script or accept the defaults, apart from the existing --tui/--no-tui override.
This makes repeatable CLI execution awkward for settings such as buffer size, scheduler capacity, early-shutdown behavior, tracing, dropped-column preservation, Jinja rendering, and request-admission tuning. Adding one CLI flag per RunConfig field would duplicate a growing Pydantic schema and make the CLI harder to maintain.
The workflow/dataset config and the runtime config are different inputs. The existing positional CONFIG_SOURCE declares what data to generate; this request adds a second, optional YAML file that controls how that one create invocation runs.
Describe the solution you'd like
Add an optional --run-config / -c option to data-designer create:
DATASET_CONFIG remains required. A bare data-designer create -c run-config.yaml is not valid because the current command still needs a dataset configuration.
File contract
Accept one local .yaml or .yml file.
The YAML root is a direct mapping of RunConfig fields; do not require a run_config: wrapper.
If request_admission is present, validate it as one nested object. Deep-merging multiple runtime files is out of scope.
Parse with safe YAML loading and validate through RunConfig, so field constraints, nested validation, unknown-field rejection, normalization, and existing deprecation behavior stay identical to the Python API.
Apply the validated object through DataDesigner.set_run_config(...) before generation starts.
Show Run config: <path> in the create summary when the option is supplied.
When the option is omitted, preserve current behavior exactly.
explicit invocation flags, currently --tui / --no-tui.
The existing DATA_DESIGNER_ASYNC_TRACE=1 environment variable remains a field-specific exception: it forces tracing on even if YAML contains async_trace: false.
--num-records, --dataset-name, --artifact-path, --resume, and --output-format are execution arguments, not RunConfig fields, and remain separate CLI options.
Examples should use the canonical display_tui and request_admission names. Deprecated progress_bar and throttle input should receive the same compatibility warnings and normalization already provided by RunConfig; the CLI loader should not implement a second compatibility layer.
Validation and error behavior
Reject the runtime file before generation starts when it is:
missing, unreadable, or a directory;
not a .yaml or .yml file;
empty or malformed YAML;
a scalar or list instead of a mapping;
using an unknown field;
using an invalid scalar or nested request_admission value.
Report the path and relevant field without a traceback, exit nonzero, and do not call DataDesigner.create() or write generation artifacts. For example:
Failed to load run config from 'run-config.yaml':
buffer_size: Input should be greater than 0
“Match the YAML” means the validated, normalized effective RunConfig, not byte-for-byte equality. For example, disable_early_shutdown: true intentionally normalizes shutdown_error_rate to 1.0; display_tui: true still falls back to log output without a TTY.
Recommended implementation
Keep this in the existing thin CLI path; no engine or public-interface API change is needed.
Add run_config_source: str | None as --run-config/-c in the create command and pass it to GenerationController.run_create.
Add a small load_run_config helper beside load_config_builder. Reuse safe YAML parsing, validate with RunConfig.model_validate(...), and normalize failures to the existing ConfigLoadError.
To preserve partial-file and future persisted-default precedence, canonicalize only explicitly supplied fields (for example via a validated model's model_dump(exclude_unset=True)), shallow-overlay them onto data_designer.run_config.model_dump(), and validate the effective object again.
Apply an explicit TUI flag to the effective model after the YAML overlay.
Call DataDesigner.set_run_config(effective_run_config) exactly once. This is required because the method also rebuilds the request-admission controller.
Invoke DataDesigner.create().
Keep imports inside the lazily loaded create path so top-level CLI startup remains fast.
data-designer create dataset.yaml --run-config run.yaml and data-designer create dataset.yaml -c run.yaml both work.
create --help distinguishes the required dataset config from the optional runtime config and documents format, precedence, and examples.
A valid partial file overlays only the supplied top-level fields; omitted fields retain the active baseline.
A full file, including nested request_admission, becomes the active DataDesigner.run_config before generation.
The controller calls set_run_config(); it does not mutate _run_config or its fields directly.
--tui and --no-tui override YAML display_tui; without either flag, YAML wins.
The create summary shows the runtime-config path when supplied.
Existing deprecated keys receive the same warnings and normalization as direct RunConfig construction.
Every current canonical RunConfig field is accepted and reaches the active model, without hard-coding a second field list in orchestration code.
Missing, unreadable, empty, malformed, non-mapping, unknown-key, and constraint-invalid files fail clearly before create().
Existing invocations without --run-config behave identically.
Resume uses the loaded buffer_size and preserve_dropped_columns and retains the engine's existing compatibility checks and messages.
Tests cover lazy CLI parsing/help, command delegation, full and partial YAML, nested values, baseline/YAML/TUI precedence, and all validation failures.
Update the create-command examples, architecture/cli.md, and the RunConfig/architecture-and-performance documentation.
Targeted CLI tests and repository formatting/lint checks pass.
Current implementation gotchas
The positional dataset config is already the primary config source; -c is mechanically free, but --run-config must be the unambiguous documented name.
DataDesigner.set_run_config() recreates the request-admission controller. Direct assignment or in-place mutation would leave stale request-admission state.
RunConfig forbids unknown fields and performs compatibility translation and normalization. Reimplementing field assignment in the controller would drift as the schema evolves.
async_trace: false cannot disable DATA_DESIGNER_ASYNC_TRACE=1; this existing OR behavior must be documented rather than silently presented as YAML winning.
display_tui: true is conditional on a TTY.
Resume currently requires buffer_size and preserve_dropped_columns to match the interrupted run. Most other runtime settings are not part of the dataset-config fingerprint and may change on resume.
non_inference_max_parallel_workers is declared and documented but currently has no production consumer. This feature can load it into RunConfig, but must not claim that the existing engine knob changes execution until that separate engine gap is resolved.
The complete effective RunConfig is not persisted in artifacts. builder_config.json contains only the dataset builder config, and metadata records selected runtime identity fields. Persisting or copying the runtime YAML is a separate reproducibility feature.
Repairing the pre-existing non_inference_max_parallel_workers engine gap.
Describe alternatives you've considered
Add a CLI flag for every field. This duplicates the Pydantic model, does not scale to nested settings, and will drift as RunConfig evolves.
Embed runtime settings in the dataset config. This mixes operational tuning with the declarative dataset definition and weakens the existing separation between config and execution.
Require a Python wrapper. This works today but bypasses the simple, standard data-designer create workflow for a data-only runtime configuration.
Support every existing dataset-config source type. URLs, JSON, and executable Python modules are unnecessary for the requested local YAML use case and broaden the trust/error surface.
Agent Investigation
No exact duplicate was found after searching open and closed issues, PRs, and repository Discussions for RunConfig, per-run config, YAML, config-file, and CLI create variants.
The create command already owns the relevant option surface and delegates to a generation controller: create.py.
The controller constructs DataDesigner, applies the existing TUI override, and calls the public create() API: generation_controller.py.
set_run_config() replaces the model and rebuilds request admission: data_designer.py.
RunConfig owns the complete schema, constraints, deprecation translation, and normalization: run_config.py.
The shared config base rejects unknown fields: base.py.
Safe mapping-oriented YAML loading already exists, so no dependency is needed: io_helpers.py.
The CLI already centralizes friendly config-loading failures: config_loader.py.
Resume checks the runtime-sensitive buffer and dropped-column policy: dataset_builder.py.
Async trace uses existing environment-variable OR semantics: dataset_builder.py.
Artifacts currently serialize only BuilderConfig(data_designer=...), not the complete runtime model: dataset_builder.py.
Additional context
This is deliberately create-only and local-YAML-only for the first implementation. It gives the CLI one typed escape hatch for the whole runtime schema without adding a parallel option surface or changing engine behavior. If users need runtime files on preview/validation, remote sources, artifact provenance, or repair of currently ineffective engine settings, those can be scoped independently after this path is proven.
Checklist
I've reviewed existing issues and the documentation
This is a design proposal, not a "please build this" request
Priority Level
Medium (Nice to have)
Is your feature request related to a problem? Please describe.
RunConfigcontrols operational behavior for a generation run, butdata-designer createcannot load one from a file. Python callers can construct aRunConfigand callDataDesigner.set_run_config(...); CLI users must instead write a wrapper script or accept the defaults, apart from the existing--tui/--no-tuioverride.This makes repeatable CLI execution awkward for settings such as buffer size, scheduler capacity, early-shutdown behavior, tracing, dropped-column preservation, Jinja rendering, and request-admission tuning. Adding one CLI flag per
RunConfigfield would duplicate a growing Pydantic schema and make the CLI harder to maintain.The workflow/dataset config and the runtime config are different inputs. The existing positional
CONFIG_SOURCEdeclares what data to generate; this request adds a second, optional YAML file that controls how that onecreateinvocation runs.Describe the solution you'd like
Add an optional
--run-config/-coption todata-designer create:DATASET_CONFIGremains required. A baredata-designer create -c run-config.yamlis not valid because the current command still needs a dataset configuration.File contract
.yamlor.ymlfile.RunConfigfields; do not require arun_config:wrapper.DataDesigner.run_config; omitted top-level fields retain the active baseline (currently the built-inRunConfigdefaults, and compatible with a future persisted baseline from Support system-level RunConfig defaults in ~/.data-designer #559 or Consolidate Data Designer user configuration into a single TOML file #694).request_admissionis present, validate it as one nested object. Deep-merging multiple runtime files is out of scope.RunConfig, so field constraints, nested validation, unknown-field rejection, normalization, and existing deprecation behavior stay identical to the Python API.DataDesigner.set_run_config(...)before generation starts.Run config: <path>in the create summary when the option is supplied.Precedence
From lowest to highest:
RunConfigdefaults;--tui/--no-tui.The existing
DATA_DESIGNER_ASYNC_TRACE=1environment variable remains a field-specific exception: it forces tracing on even if YAML containsasync_trace: false.--num-records,--dataset-name,--artifact-path,--resume, and--output-formatare execution arguments, notRunConfigfields, and remain separate CLI options.Usage examples
Minimal
run-config.yaml:Use the long option:
Use the requested short option with other create settings:
The runtime file also works when the dataset config is a local Python module:
An explicit CLI flag wins over YAML:
# Even if run-config.yaml contains display_tui: true, this invocation disables it. data-designer create dataset.yaml -c run-config.yaml --no-tuiResume with the same runtime-sensitive settings:
Complete current top-level schema using defaults:
Advanced request-admission tuning:
Examples should use the canonical
display_tuiandrequest_admissionnames. Deprecatedprogress_barandthrottleinput should receive the same compatibility warnings and normalization already provided byRunConfig; the CLI loader should not implement a second compatibility layer.Validation and error behavior
Reject the runtime file before generation starts when it is:
.yamlor.ymlfile;request_admissionvalue.Report the path and relevant field without a traceback, exit nonzero, and do not call
DataDesigner.create()or write generation artifacts. For example:“Match the YAML” means the validated, normalized effective
RunConfig, not byte-for-byte equality. For example,disable_early_shutdown: trueintentionally normalizesshutdown_error_rateto1.0;display_tui: truestill falls back to log output without a TTY.Recommended implementation
Keep this in the existing thin CLI path; no engine or public-interface API change is needed.
run_config_source: str | Noneas--run-config/-cin the create command and pass it toGenerationController.run_create.load_run_confighelper besideload_config_builder. Reuse safe YAML parsing, validate withRunConfig.model_validate(...), and normalize failures to the existingConfigLoadError.model_dump(exclude_unset=True)), shallow-overlay them ontodata_designer.run_config.model_dump(), and validate the effective object again.DataDesigner.set_run_config(effective_run_config)exactly once. This is required because the method also rebuilds the request-admission controller.DataDesigner.create().Likely production files:
packages/data-designer/src/data_designer/cli/commands/create.pypackages/data-designer/src/data_designer/cli/controllers/generation_controller.pypackages/data-designer/src/data_designer/cli/utils/config_loader.pyAcceptance criteria
data-designer create dataset.yaml --run-config run.yamlanddata-designer create dataset.yaml -c run.yamlboth work.create --helpdistinguishes the required dataset config from the optional runtime config and documents format, precedence, and examples.request_admission, becomes the activeDataDesigner.run_configbefore generation.set_run_config(); it does not mutate_run_configor its fields directly.--tuiand--no-tuioverride YAMLdisplay_tui; without either flag, YAML wins.RunConfigconstruction.RunConfigfield is accepted and reaches the active model, without hard-coding a second field list in orchestration code.create().--run-configbehave identically.buffer_sizeandpreserve_dropped_columnsand retains the engine's existing compatibility checks and messages.architecture/cli.md, and the RunConfig/architecture-and-performance documentation.Current implementation gotchas
-cis mechanically free, but--run-configmust be the unambiguous documented name.DataDesigner.set_run_config()recreates the request-admission controller. Direct assignment or in-place mutation would leave stale request-admission state.RunConfigforbids unknown fields and performs compatibility translation and normalization. Reimplementing field assignment in the controller would drift as the schema evolves.async_trace: falsecannot disableDATA_DESIGNER_ASYNC_TRACE=1; this existing OR behavior must be documented rather than silently presented as YAML winning.display_tui: trueis conditional on a TTY.buffer_sizeandpreserve_dropped_columnsto match the interrupted run. Most other runtime settings are not part of the dataset-config fingerprint and may change on resume.non_inference_max_parallel_workersis declared and documented but currently has no production consumer. This feature can load it intoRunConfig, but must not claim that the existing engine knob changes execution until that separate engine gap is resolved.RunConfigis not persisted in artifacts.builder_config.jsoncontains only the dataset builder config, and metadata records selected runtime identity fields. Persisting or copying the runtime YAML is a separate reproducibility feature.progress_barandthrottlenames. This issue and its docs should use the currentdisplay_tuiandrequest_admissionschema.Non-goals
preview,validate, orcheck-modelsin the first change.RunConfigin the dataset/workflow config.RunConfigor generating a starter file.non_inference_max_parallel_workersengine gap.Describe alternatives you've considered
RunConfigevolves.data-designer createworkflow for a data-only runtime configuration.Agent Investigation
No exact duplicate was found after searching open and closed issues, PRs, and repository Discussions for
RunConfig, per-run config, YAML, config-file, and CLI create variants.Related work:
RunConfigdefaults. This request is the explicit per-invocation layer that should take precedence over those defaults.create,preview, andvalidatewith a positional workflow config.--run-configremains a first-class Data Designer option before any future--separator.Code findings at current
main:DataDesigner, applies the existing TUI override, and calls the publiccreate()API: generation_controller.py.set_run_config()replaces the model and rebuilds request admission: data_designer.py.RunConfigowns the complete schema, constraints, deprecation translation, and normalization: run_config.py.BuilderConfig(data_designer=...), not the complete runtime model: dataset_builder.py.Additional context
This is deliberately create-only and local-YAML-only for the first implementation. It gives the CLI one typed escape hatch for the whole runtime schema without adding a parallel option surface or changing engine behavior. If users need runtime files on preview/validation, remote sources, artifact provenance, or repair of currently ineffective engine settings, those can be scoped independently after this path is proven.
Checklist