Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 36 additions & 9 deletions backend/modules/llm/litellm_caller.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,14 @@


class LiteLLMCaller:
"""Clean interface for all LLM calling patterns using LiteLLM."""
"""Clean interface for all LLM calling patterns using LiteLLM.

Note: this class may set provider-specific LLM API key environment
variables (for example ``OPENAI_API_KEY``) to maintain compatibility
with LiteLLM's internal provider detection. These mutations are
best-effort only and are not intended to provide strong isolation
guarantees in multi-tenant or highly concurrent environments.
"""

def __init__(self, llm_config=None, debug_mode: bool = False):
"""Initialize with optional config dependency injection."""
Expand Down Expand Up @@ -85,20 +92,40 @@ def _get_model_kwargs(self, model_name: str, temperature: Optional[float] = None
except ValueError as e:
logger.error(f"Failed to resolve API key for model {model_name}: {e}")
raise

if api_key:
# Always pass api_key to LiteLLM for all providers
kwargs["api_key"] = api_key

# Additionally set provider-specific env vars for LiteLLM's internal logic
def _set_env_var_if_needed(env_key: str, value: str) -> None:
existing = os.environ.get(env_key)
if existing is None:
os.environ[env_key] = value
elif existing != value:
logger.warning(
"Overwriting existing environment variable %s for model %s",
env_key,
model_name,
)
os.environ[env_key] = value

if "openrouter" in model_config.model_url:
kwargs["api_key"] = api_key
# LiteLLM will automatically set the correct env var
os.environ["OPENROUTER_API_KEY"] = api_key
_set_env_var_if_needed("OPENROUTER_API_KEY", api_key)
elif "openai" in model_config.model_url:
os.environ["OPENAI_API_KEY"] = api_key
_set_env_var_if_needed("OPENAI_API_KEY", api_key)
elif "anthropic" in model_config.model_url:
os.environ["ANTHROPIC_API_KEY"] = api_key
_set_env_var_if_needed("ANTHROPIC_API_KEY", api_key)
elif "google" in model_config.model_url:
os.environ["GOOGLE_API_KEY"] = api_key
_set_env_var_if_needed("GOOGLE_API_KEY", api_key)
elif "cerebras" in model_config.model_url:
os.environ["CEREBRAS_API_KEY"] = api_key
_set_env_var_if_needed("CEREBRAS_API_KEY", api_key)
else:
# Custom endpoint - set OPENAI_API_KEY as fallback for
# OpenAI-compatible endpoints. This is a heuristic and
# only updates the env var if it is unset or already
# matches the same value.
_set_env_var_if_needed("OPENAI_API_KEY", api_key)

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