Resolve a provider's API key: configured value first, then env vars. The configured ``providers. .api_key`` always wins. When it is empty (the common case for a freshly-added provider the user hasn't run ``login`` for), fall back to the provider's known env-var candidates via :
(
provider_name: str, provider_cfg: dict[str, Any] | None = None
)
| 301 | |
| 302 | |
| 303 | def resolve_api_key( |
| 304 | provider_name: str, provider_cfg: dict[str, Any] | None = None |
| 305 | ) -> str: |
| 306 | """Resolve a provider's API key: configured value first, then env vars. |
| 307 | |
| 308 | The configured ``providers.<name>.api_key`` always wins. When it is empty |
| 309 | (the common case for a freshly-added provider the user hasn't run ``login`` |
| 310 | for), fall back to the provider's known env-var candidates via |
| 311 | :func:`src.secret_store.get_secret` — which itself checks the real process |
| 312 | environment, then the global config ``env`` block. This makes every |
| 313 | provider, including the registry additions, usable by simply exporting e.g. |
| 314 | ``TOGETHER_API_KEY`` without hand-editing ``config.json``. |
| 315 | |
| 316 | Returns ``""`` when no key is found; callers gate fatality on |
| 317 | :func:`provider_requires_api_key`. |
| 318 | """ |
| 319 | if provider_cfg is None: |
| 320 | try: |
| 321 | from src.config import get_provider_config |
| 322 | |
| 323 | provider_cfg = get_provider_config(provider_name) |
| 324 | except Exception: |
| 325 | provider_cfg = {} |
| 326 | configured = (provider_cfg or {}).get("api_key") |
| 327 | if isinstance(configured, str) and configured.strip(): |
| 328 | return configured |
| 329 | from src.secret_store import get_secret |
| 330 | |
| 331 | for env_name in provider_env_vars(provider_name): |
| 332 | value = get_secret(env_name) |
| 333 | if value and value.strip(): |
| 334 | return value |
| 335 | return "" |
| 336 | |
| 337 | |
| 338 | # Legacy registry for display purposes |