Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,6 @@ data-designer config providers

**Delete all providers**: Remove all providers and their associated models.

**Change default provider**: Set which provider is used by default. This option is only available when multiple providers are configured.

!!! warning "Deprecated: 'Change default provider' workflow"
The "Change default provider" workflow is **deprecated** and will be removed in a future
release alongside the registry-level default. Specify `provider=` explicitly on each
`ModelConfig` instead — the workflow now emits a `DeprecationWarning` when entered.
See [issue #589](https://github.com/NVIDIA-NeMo/DataDesigner/issues/589).

## Managing Model Configurations

Run the interactive model configuration command:
Expand Down Expand Up @@ -117,7 +109,6 @@ data-designer config list
This command displays:

- **Model Providers**: All configured providers with their endpoints (API keys are masked)
- **Default Provider**: The currently selected default provider _(deprecated; see issue #589)_
- **Model Configurations**: All configured models with their settings

## Resetting Configurations
Expand Down
7 changes: 0 additions & 7 deletions docs/concepts/models/custom-model-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,6 @@ preview_result.display_sample_record()
!!! note "Default Providers Always Available"
When you only specify `model_configs`, the default model providers (NVIDIA, OpenAI, and OpenRouter) are still available. You only need to create custom providers if you want to connect to different endpoints or modify provider settings.

!!! warning "Always specify `provider=` on `ModelConfig`"
Leaving `provider` unset (or passing `provider=None`) on `ModelConfig` is **deprecated**.
The legacy "implicit default provider" routing — used when `provider` is omitted — emits
a `DeprecationWarning` and will be removed in a future release. Always reference the
intended provider by name, as the examples below do. See
[issue #589](https://github.com/NVIDIA-NeMo/DataDesigner/issues/589).

!!! tip "Mixing Custom and Default Models"
When you provide custom `model_configs` to `DataDesignerConfigBuilder`, they **replace** the defaults entirely. To use custom model configs in addition to the default configs, use the add_model_config method:

Expand Down
7 changes: 0 additions & 7 deletions docs/concepts/models/default-model-settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,6 @@ Both methods operate on the same files, ensuring consistency across your entire
!!! warning "API Key Requirements"
While default model configurations are always available, you need to set the appropriate API key environment variable (`NVIDIA_API_KEY`, `OPENAI_API_KEY`, or `OPENROUTER_API_KEY`) to actually use the corresponding models for data generation. Without a valid API key, any attempt to generate data using that provider's models will fail.

!!! warning "Deprecated: implicit default provider routing"
The `default:` key in `~/.data-designer/model_providers.yaml` and the registry-level
"default provider" concept are **deprecated** and will be removed in a future release.
Specify `provider=` explicitly on every `ModelConfig` instead — the built-in defaults
above already do this, and a `DeprecationWarning` is now emitted whenever the legacy
routing is exercised. See [issue #589](https://github.com/NVIDIA-NeMo/DataDesigner/issues/589).

!!! tip "Environment Variables"
Store your API keys in environment variables rather than hardcoding them in your scripts:

Expand Down
8 changes: 0 additions & 8 deletions docs/concepts/models/model-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ Model providers are external services that host and serve models. Data Designer

A `ModelProvider` defines how Data Designer connects to a provider's API endpoint. When you create a `ModelConfig`, you reference a provider by name, and Data Designer uses that provider's settings to make API calls to the appropriate endpoint.

!!! warning "Deprecated: implicit default provider routing"
Earlier versions of Data Designer let you omit `provider=` on `ModelConfig` and
fall back to a registry-level default — including the `default:` key in
`~/.data-designer/model_providers.yaml`. That implicit routing is **deprecated**
and will be removed in a future release. Always reference a provider by name on
every `ModelConfig`. A `DeprecationWarning` is now emitted when the legacy path
is exercised. See [issue #589](https://github.com/NVIDIA-NeMo/DataDesigner/issues/589).

## ModelProvider Configuration

The `ModelProvider` class has the following fields:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
PREDEFINED_PROVIDERS_MODEL_MAP,
)
from data_designer.config.utils.io_helpers import load_config_file, save_config_file
from data_designer.config.utils.warning_helpers import warn_at_caller

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -95,31 +94,6 @@ def get_default_providers() -> list[ModelProvider]:
return []


def get_default_provider_name() -> str | None:
"""Return the YAML's ``default:`` provider name, if set.

Deprecated: this function and the underlying YAML key are deprecated and
will be removed in a future release. Specify ``provider=`` explicitly on
each ``ModelConfig`` instead. See issue #589.
"""
default = _get_default_providers_file_content(MODEL_PROVIDERS_FILE_PATH).get("default")
if default is not None:
# ``warn_at_caller`` (rather than ``warnings.warn(stacklevel=2)``) so the
# warning attributes to the user's call site rather than this library
# module. The only real call path is ``DataDesigner.__init__``, which
# is itself a ``data_designer`` frame; under default Python filters,
# library-attributed ``DeprecationWarning`` entries are silenced
# (``ignore::DeprecationWarning``), so library attribution = invisible
# warning. See PR #594 review.
warn_at_caller(
f"The 'default:' key in {MODEL_PROVIDERS_FILE_PATH} is deprecated and will "
"be removed in a future release. Remove it and specify provider= explicitly "
"on each ModelConfig instead. See issue #589.",
DeprecationWarning,
)
return default


def resolve_seed_default_model_settings() -> None:
if not MODEL_CONFIGS_FILE_PATH.exists():
logger.debug(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
load_image_path_to_base64,
)
from data_designer.config.utils.io_helpers import smart_load_yaml
from data_designer.config.utils.warning_helpers import warn_at_caller

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -504,17 +503,15 @@ class ModelConfig(ConfigBase):
model: Model identifier (e.g., from build.nvidia.com or other providers).
inference_parameters: Inference parameters for the model (temperature, top_p, max_tokens, etc.).
The generation_type is determined by the type of inference_parameters.
provider: Name of the model provider. Required in a future release. Leaving
``provider`` unset (or ``None``) currently routes through the registry's
implicit default and is **deprecated**; specify ``provider=`` explicitly.
See issue #589.
provider: Name of the model provider. Must match the ``name`` field of a
``ModelProvider`` registered with the surrounding ``DataDesigner`` instance.
skip_health_check: Whether to skip the health check for this model. Defaults to False.
"""

alias: str
model: str
inference_parameters: InferenceParamsT = Field(default_factory=ChatCompletionInferenceParams)
provider: str | None = None
provider: str
skip_health_check: bool = False

@property
Expand All @@ -539,22 +536,6 @@ def _convert_inference_parameters(cls, value: Any) -> Any:
return ChatCompletionInferenceParams(**value)
return value

@model_validator(mode="after")
def _warn_on_implicit_provider(self) -> Self:
if self.provider is None:
# Use ``warn_at_caller`` so the warning is attributed to the user's
# ``ModelConfig(...)`` / ``model_validate(...)`` call rather than a
# pydantic-internal frame. Without this, every call dedupes to the
# same pydantic line and only the first emission is shown. See
# PR #594 review.
warn_at_caller(
f"ModelConfig.provider=None is deprecated and will be required in a future release. "
f"Specify provider= explicitly on ModelConfig(alias={self.alias!r}, ...). "
"See issue #589.",
DeprecationWarning,
)
return self


class ModelProvider(ConfigBase):
"""Configuration for a custom model provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def stub_data_designer_config_str() -> str:
model_configs:
- alias: my_own_code_model
model: openai/meta/llama-3.3-70b-instruct
provider: openai
inference_parameters:
temperature:
distribution_type: uniform
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ def test_from_config_auto_wraps_bare_dict() -> None:
{
"alias": "test-model",
"model": "openai/meta/llama-3.3-70b-instruct",
"provider": "openai",
}
],
"columns": [
Expand All @@ -219,6 +220,7 @@ def test_from_config_passthrough_when_already_wrapped() -> None:
{
"alias": "test-model",
"model": "openai/meta/llama-3.3-70b-instruct",
"provider": "openai",
}
],
"columns": [
Expand Down Expand Up @@ -253,6 +255,7 @@ def test_from_config_auto_wraps_bare_json_file() -> None:
{
"alias": "test-model",
"model": "openai/meta/llama-3.3-70b-instruct",
"provider": "openai",
}
],
"columns": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
# SPDX-License-Identifier: Apache-2.0

import json
import warnings
from pathlib import Path
from unittest.mock import patch

Expand All @@ -14,7 +13,6 @@
get_builtin_model_providers,
get_default_inference_parameters,
get_default_model_configs,
get_default_provider_name,
get_default_providers,
get_providers_with_missing_api_keys,
resolve_seed_default_model_settings,
Expand Down Expand Up @@ -142,63 +140,6 @@ def test_get_default_providers_path_does_not_exist():
get_default_providers()


def test_get_default_provider_name_with_default_key(tmp_path: Path):
"""When the YAML carries a non-None ``default:``, the function must
return that value AND emit a ``DeprecationWarning`` (regression for #589).
"""
providers_file_path = tmp_path / "providers.yaml"
providers_file_path.write_text(
json.dumps(dict(providers=[p.model_dump() for p in get_builtin_model_providers()], default="nvidia"))
)
with patch("data_designer.config.default_model_settings.MODEL_PROVIDERS_FILE_PATH", new=providers_file_path):
with pytest.warns(DeprecationWarning, match="'default:' key.*is deprecated"):
assert get_default_provider_name() == "nvidia"


def test_get_default_provider_name_without_default_key(tmp_path: Path):
"""Pin the post-deprecation happy path: a YAML without ``default:`` must
return ``None`` and NOT emit a ``DeprecationWarning``.
"""
providers_file_path = tmp_path / "providers.yaml"
providers_file_path.write_text(json.dumps({"providers": [p.model_dump() for p in get_builtin_model_providers()]}))
with patch("data_designer.config.default_model_settings.MODEL_PROVIDERS_FILE_PATH", new=providers_file_path):
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
assert get_default_provider_name() is None


def test_get_default_provider_name_warning_attributes_to_user_frame(tmp_path: Path):
"""Regression for PR #594 review (andreatgretel): the YAML-default warning
must attribute to the user's call site, not to ``default_model_settings.py``.
Python's default filter ignores library-attributed ``DeprecationWarning``
entries, so the previous ``stacklevel=2`` attribution rendered the warning
invisible under default filters on the only real call path
(``DataDesigner.__init__``). See issue #589.
"""
providers_file_path = tmp_path / "providers.yaml"
providers_file_path.write_text(
json.dumps(dict(providers=[p.model_dump() for p in get_builtin_model_providers()], default="nvidia"))
)
with patch("data_designer.config.default_model_settings.MODEL_PROVIDERS_FILE_PATH", new=providers_file_path):
with warnings.catch_warnings(record=True) as caught:
warnings.simplefilter("always", DeprecationWarning)
assert get_default_provider_name() == "nvidia"

matches = [w for w in caught if "'default:' key" in str(w.message)]
assert len(matches) == 1, [str(w.message) for w in caught]
assert matches[0].filename == __file__, (
f"Warning attributed to {matches[0].filename!r} (line {matches[0].lineno}) "
f"instead of the test file. Library-attributed DeprecationWarnings are "
f"silenced under default filters."
)


def test_get_default_provider_name_path_does_not_exist():
with patch("data_designer.config.default_model_settings.MODEL_PROVIDERS_FILE_PATH", new=Path("non_existent_path")):
with pytest.raises(FileNotFoundError, match=r"Default model providers file not found at 'non_existent_path'"):
get_default_provider_name()


def test_get_nvidia_api_key():
with patch("data_designer.config.utils.visualization.os.getenv", return_value="nvidia_api_key"):
assert get_nvidia_api_key() == "nvidia_api_key"
Expand Down
36 changes: 11 additions & 25 deletions packages/data-designer-config/tests/config/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import base64
import json
import tempfile
import warnings
from collections import Counter
from pathlib import Path

Expand Down Expand Up @@ -482,38 +481,25 @@ def test_model_config_construction():
assert model_config.generation_type == GenerationType.IMAGE


def test_model_config_provider_none_emits_deprecation_warning():
"""Regression for #589: omitting ``provider=`` (or passing ``provider=None``)
on a ``ModelConfig`` is deprecated; construction must emit a
``DeprecationWarning`` pointing users at the explicit-provider migration.
def test_model_config_provider_required():
"""Regression for #590: ``provider`` is required on ``ModelConfig`` —
construction without it (or with ``provider=None``) must raise.
"""
with pytest.warns(DeprecationWarning, match="ModelConfig.provider=None is deprecated"):
ModelConfig(alias="legacy", model="legacy-model")
with pytest.raises(ValidationError, match="provider"):
ModelConfig(alias="legacy", model="legacy-model") # type: ignore[call-arg]

with pytest.warns(DeprecationWarning, match="ModelConfig.provider=None is deprecated"):
ModelConfig(alias="legacy", model="legacy-model", provider=None)
with pytest.raises(ValidationError, match="provider"):
ModelConfig(alias="legacy", model="legacy-model", provider=None) # type: ignore[arg-type]


def test_model_config_provider_none_via_model_validate_emits_deprecation_warning():
"""Regression for #589 / PR #594 review: deserialising legacy on-disk configs
via ``ModelConfig.model_validate(...)`` must surface the same
``DeprecationWarning`` as direct construction. Both paths funnel through
the same validator today, so this pin protects against a future refactor
that, e.g., only runs the validator on construction and not on revalidation.
def test_model_config_provider_required_via_model_validate():
"""Regression for #590: deserialising legacy on-disk configs via
``ModelConfig.model_validate(...)`` without ``provider:`` must raise.
"""
with pytest.warns(DeprecationWarning, match="ModelConfig.provider=None is deprecated"):
with pytest.raises(ValidationError, match="provider"):
ModelConfig.model_validate({"alias": "legacy", "model": "legacy-model"})


def test_model_config_with_provider_does_not_warn():
"""Pin the post-deprecation happy path: specifying ``provider=`` must not
emit any deprecation warning.
"""
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
ModelConfig(alias="modern", model="modern-model", provider="some-provider")


def test_model_config_generation_type_from_dict():
# Test that generation_type in dict is used to create the right inference params type
model_config = ModelConfig.model_validate(
Expand Down
Loading
Loading