Skip to content

refactor: deprecate implicit default model provider routing #589

@nabinchha

Description

@nabinchha

Summary

Start the deprecation cycle for the "implicit default provider" concept that causes the bug tracked in #588. Specifically, mark for deprecation:

  • ModelConfig.provider: str | None = None — when None, routes to the registry's default.
  • ModelProviderRegistry.default — the registry-level default field.
  • The YAML default: key in ~/.data-designer/model_providers.yaml.
  • The CLI's "Change default provider" workflow in provider_controller.py::_handle_change_default.

This prepares the ground for the cleanup in #590, which removes these concepts entirely.

Why

The runtime machinery behind "default provider" is a narrow shorthand:

  • The only runtime consumer of ModelProviderRegistry.default is get_provider(name=None).
  • The only path that reaches get_provider(name=None) is model_config.provider is None.

So the entire mechanism exists to support users writing ModelConfig(alias=..., model=...) without specifying a provider, in the single-provider-only case. That shorthand is the root cause of the ambiguity in #588 and every "which default wins?" question.

Evidence that the shorthand is essentially unused in practice:

  • All 12 built-in ModelConfigs already specify provider explicitly (asserted in packages/data-designer-config/tests/config/test_default_model_settings.py:60-94).
  • The docs example for custom configs shows provider= explicitly (docs/concepts/models/custom-model-settings.md:152, 162).

The shorthand's ergonomic value is marginal; its cost is architectural ambiguity that we keep paying for.

Scope of this issue

Land deprecation warnings (non-breaking), so that the cleanup in the follow-up issue can happen cleanly in a later release:

  1. ModelConfig.provider=None — emit DeprecationWarning on validation when provider is None, suggesting users specify provider= explicitly.
  2. YAML default: key — emit DeprecationWarning on load in ProviderRepository.load() if the default: key is present.
  3. CLI "Change default provider" workflow — emit a deprecation notice in the interactive menu and in any docs that mention setting a default.
  4. ModelProviderRegistry.default — mark the field deprecated in the Pydantic model or in a module-level __getattr__ / docstring note. Continue supporting it for now.
  5. get_default_provider_name() in default_model_settings.py — mark deprecated.

Add deprecation notices to docs:

  • docs/concepts/models/model-providers/ (if it mentions defaults)
  • docs/concepts/models/custom-model-settings.md
  • docs/concepts/models/default-model-settings.md
  • docs/concepts/models/configure-model-settings-with-the-cli.md

Out of scope (tracked separately)

Migration message

The deprecation warning should point users at the canonical pattern:

# Before (deprecated)
ModelConfig(alias="my-text-model", model="some-model-id")

# After
ModelConfig(alias="my-text-model", model="some-model-id", provider="my-provider")

Depends on

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions