Skip to content

Commit 0823345

Browse files
authored
Merge pull request #118 from sandialabs/fix/custom-llm-api-key-handling
feat(llm): enhance LiteLLMCaller to support custom API key handling a…
2 parents 0e38e8c + 027e58c commit 0823345

File tree

3 files changed

+694
-14
lines changed

3 files changed

+694
-14
lines changed

backend/modules/llm/litellm_caller.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,14 @@
2727

2828

2929
class LiteLLMCaller:
30-
"""Clean interface for all LLM calling patterns using LiteLLM."""
30+
"""Clean interface for all LLM calling patterns using LiteLLM.
31+
32+
Note: this class may set provider-specific LLM API key environment
33+
variables (for example ``OPENAI_API_KEY``) to maintain compatibility
34+
with LiteLLM's internal provider detection. These mutations are
35+
best-effort only and are not intended to provide strong isolation
36+
guarantees in multi-tenant or highly concurrent environments.
37+
"""
3138

3239
def __init__(self, llm_config=None, debug_mode: bool = False):
3340
"""Initialize with optional config dependency injection."""
@@ -85,20 +92,40 @@ def _get_model_kwargs(self, model_name: str, temperature: Optional[float] = None
8592
except ValueError as e:
8693
logger.error(f"Failed to resolve API key for model {model_name}: {e}")
8794
raise
88-
95+
8996
if api_key:
97+
# Always pass api_key to LiteLLM for all providers
98+
kwargs["api_key"] = api_key
99+
100+
# Additionally set provider-specific env vars for LiteLLM's internal logic
101+
def _set_env_var_if_needed(env_key: str, value: str) -> None:
102+
existing = os.environ.get(env_key)
103+
if existing is None:
104+
os.environ[env_key] = value
105+
elif existing != value:
106+
logger.warning(
107+
"Overwriting existing environment variable %s for model %s",
108+
env_key,
109+
model_name,
110+
)
111+
os.environ[env_key] = value
112+
90113
if "openrouter" in model_config.model_url:
91-
kwargs["api_key"] = api_key
92-
# LiteLLM will automatically set the correct env var
93-
os.environ["OPENROUTER_API_KEY"] = api_key
114+
_set_env_var_if_needed("OPENROUTER_API_KEY", api_key)
94115
elif "openai" in model_config.model_url:
95-
os.environ["OPENAI_API_KEY"] = api_key
116+
_set_env_var_if_needed("OPENAI_API_KEY", api_key)
96117
elif "anthropic" in model_config.model_url:
97-
os.environ["ANTHROPIC_API_KEY"] = api_key
118+
_set_env_var_if_needed("ANTHROPIC_API_KEY", api_key)
98119
elif "google" in model_config.model_url:
99-
os.environ["GOOGLE_API_KEY"] = api_key
120+
_set_env_var_if_needed("GOOGLE_API_KEY", api_key)
100121
elif "cerebras" in model_config.model_url:
101-
os.environ["CEREBRAS_API_KEY"] = api_key
122+
_set_env_var_if_needed("CEREBRAS_API_KEY", api_key)
123+
else:
124+
# Custom endpoint - set OPENAI_API_KEY as fallback for
125+
# OpenAI-compatible endpoints. This is a heuristic and
126+
# only updates the env var if it is unset or already
127+
# matches the same value.
128+
_set_env_var_if_needed("OPENAI_API_KEY", api_key)
102129

103130
# Set custom API base for non-standard endpoints
104131
if hasattr(model_config, 'model_url') and model_config.model_url:

0 commit comments

Comments
 (0)