"""Provider registry: map a provider name to a model factory and preset models. Each provider declares its default model plus the small/large presets the ``iterate`` / ``validate`` CLI loops fall back to, and a ``make_model`` factory that reads credentials lazily (so importing a provider never requires a key). """ from collections.abc import Callable from dataclasses import dataclass from langchain_core.language_models import BaseChatModel @dataclass(frozen=True) class Provider: """A model provider: presets plus a name-to-model factory.""" name: str default_model: str small_model: str large_model: str make_model: Callable[[str], BaseChatModel] _REGISTRY: dict[str, Provider] = {} def register(provider: Provider) -> None: """Register ``provider`` under its name (overwriting any existing entry).""" _REGISTRY[provider.name] = provider def get_provider(name: str) -> Provider: """Return the registered provider named ``name`` or raise ``KeyError``.""" if name not in _REGISTRY: available = ", ".join(sorted(_REGISTRY)) or "(none registered)" raise KeyError(f"Unknown provider '{name}'. Available: {available}") return _REGISTRY[name] def provider_names() -> list[str]: """Return the sorted names of all registered providers.""" return sorted(_REGISTRY) # Import built-in providers for their registration side effects. from skill_eval_runner.providers import anthropic, bedrock_claude # noqa: E402,F401