From 9ab70c6d61c378a98d6e93bd5aceb355f07849c8 Mon Sep 17 00:00:00 2001 From: 0xallam Date: Sun, 7 Jun 2026 22:42:03 +0300 Subject: [PATCH] Mirror LLM_API_KEY to provider env var (closes #504) LiteLLM's per-provider branches (deepseek, anthropic, groq, etc.) don't consult ``litellm.api_key`` (the module global Strix sets). They only check the per-call ``api_key`` kwarg and the ``_API_KEY`` env var. The SDK's LitellmModel passes ``api_key=None`` by default, so requests went out with an empty bearer and DeepSeek (and friends) returned 401. Mirror the user's LLM_API_KEY into the provider-specific env var (``DEEPSEEK_API_KEY`` for ``deepseek/...``, ``ANTHROPIC_API_KEY`` for ``anthropic/...``, etc.) using LiteLLM's documented convention. ``os.environ.setdefault`` is used so an explicit user env is never clobbered. The OpenAI branch was already working via ``set_default_openai_key`` + the existing ``litellm.api_key`` global fallback. Co-Authored-By: Claude Opus 4.7 --- strix/config/models.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/strix/config/models.py b/strix/config/models.py index 89ec38c..a0be563 100644 --- a/strix/config/models.py +++ b/strix/config/models.py @@ -49,6 +49,7 @@ def configure_sdk_model_defaults(settings: Settings) -> None: if llm.api_key: set_default_openai_key(llm.api_key, use_for_tracing=False) _configure_litellm_default("api_key", llm.api_key) + _mirror_api_key_to_provider_env(llm.model, llm.api_key) if llm.api_base: os.environ["OPENAI_BASE_URL"] = llm.api_base _configure_litellm_default("api_base", llm.api_base) @@ -57,6 +58,22 @@ def configure_sdk_model_defaults(settings: Settings) -> None: set_default_openai_api("responses") +def _mirror_api_key_to_provider_env(model_name: str | None, api_key: str) -> None: + if not model_name: + return + name = model_name.strip() + for prefix in ("litellm/", "any-llm/"): + if name.lower().startswith(prefix): + name = name[len(prefix) :] + break + if "/" not in name: + return + provider = name.split("/", 1)[0].strip().upper() + if not provider: + return + os.environ.setdefault(f"{provider}_API_KEY", api_key) + + def _configure_litellm_compatibility() -> None: """Enable LiteLLM's permissive param-handling mode.""" import litellm