feat(llm): auto-configure Google AI Studio URL when LLM_PROVIDER=gemini
When LLM_PROVIDER=gemini, LLMClient automatically uses the Google AI Studio OpenAI-compatible endpoint instead of requiring manual base_url configuration. An explicit base_url argument still takes precedence. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
788f9c29c9
commit
039de4ad8b
|
|
@ -28,6 +28,10 @@ class LLMClient:
|
|||
if not self.api_key:
|
||||
raise ValueError("LLM_API_KEY is not configured")
|
||||
|
||||
# Google AI Studio OpenAI-compatible endpoint
|
||||
if (Config.LLM_PROVIDER or "").lower() == "gemini" and not base_url:
|
||||
raw_url = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
||||
|
||||
# Azure Portal provides full endpoint URLs like:
|
||||
# https://<resource>.cognitiveservices.azure.com/openai/deployments/<model>/chat/completions?api-version=...
|
||||
# The OpenAI SDK expects a base_url and appends /chat/completions itself,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
import pytest
|
||||
from unittest.mock import patch, MagicMock
|
||||
|
||||
GEMINI_URL = "https://generativelanguage.googleapis.com/v1beta/openai/"
|
||||
|
||||
|
||||
def test_gemini_provider_sets_base_url_automatically():
|
||||
import backend.app.config as cfg
|
||||
orig_provider = cfg.Config.LLM_PROVIDER
|
||||
orig_key = cfg.Config.LLM_API_KEY
|
||||
orig_url = cfg.Config.LLM_BASE_URL
|
||||
try:
|
||||
cfg.Config.LLM_PROVIDER = "gemini"
|
||||
cfg.Config.LLM_API_KEY = "AIzatest"
|
||||
cfg.Config.LLM_BASE_URL = "https://api.openai.com/v1"
|
||||
|
||||
with patch("backend.app.utils.llm_client.OpenAI") as mock_openai:
|
||||
mock_openai.return_value = MagicMock()
|
||||
import importlib
|
||||
import backend.app.utils.llm_client as lm
|
||||
importlib.reload(lm)
|
||||
client = lm.LLMClient()
|
||||
assert GEMINI_URL in client.base_url
|
||||
finally:
|
||||
cfg.Config.LLM_PROVIDER = orig_provider
|
||||
cfg.Config.LLM_API_KEY = orig_key
|
||||
cfg.Config.LLM_BASE_URL = orig_url
|
||||
|
||||
|
||||
def test_non_gemini_provider_uses_configured_url():
|
||||
import backend.app.config as cfg
|
||||
orig_provider = cfg.Config.LLM_PROVIDER
|
||||
orig_key = cfg.Config.LLM_API_KEY
|
||||
orig_url = cfg.Config.LLM_BASE_URL
|
||||
try:
|
||||
cfg.Config.LLM_PROVIDER = ""
|
||||
cfg.Config.LLM_API_KEY = "sk-test"
|
||||
cfg.Config.LLM_BASE_URL = "https://api.openai.com/v1"
|
||||
|
||||
with patch("backend.app.utils.llm_client.OpenAI") as mock_openai:
|
||||
mock_openai.return_value = MagicMock()
|
||||
import importlib
|
||||
import backend.app.utils.llm_client as lm
|
||||
importlib.reload(lm)
|
||||
client = lm.LLMClient()
|
||||
assert "openai.com" in client.base_url
|
||||
finally:
|
||||
cfg.Config.LLM_PROVIDER = orig_provider
|
||||
cfg.Config.LLM_API_KEY = orig_key
|
||||
cfg.Config.LLM_BASE_URL = orig_url
|
||||
|
||||
|
||||
def test_explicit_base_url_overrides_gemini_auto():
|
||||
"""If base_url is passed explicitly, it should NOT be replaced even if LLM_PROVIDER=gemini."""
|
||||
import backend.app.config as cfg
|
||||
orig_provider = cfg.Config.LLM_PROVIDER
|
||||
orig_key = cfg.Config.LLM_API_KEY
|
||||
try:
|
||||
cfg.Config.LLM_PROVIDER = "gemini"
|
||||
cfg.Config.LLM_API_KEY = "AIzatest"
|
||||
|
||||
with patch("backend.app.utils.llm_client.OpenAI") as mock_openai:
|
||||
mock_openai.return_value = MagicMock()
|
||||
import importlib
|
||||
import backend.app.utils.llm_client as lm
|
||||
importlib.reload(lm)
|
||||
client = lm.LLMClient(base_url="https://custom.endpoint/v1")
|
||||
assert "custom.endpoint" in client.base_url
|
||||
assert GEMINI_URL not in client.base_url
|
||||
finally:
|
||||
cfg.Config.LLM_PROVIDER = orig_provider
|
||||
cfg.Config.LLM_API_KEY = orig_key
|
||||
Loading…
Reference in New Issue