Skip to content
Open
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
6 changes: 5 additions & 1 deletion backend/src/services/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import os

from pydantic_ai.models.google import GoogleModel
from pydantic_ai.models.openai import OpenAIModel
from pydantic_ai.providers.google import GoogleProvider

from services.llm_model_spec import normalize_provider_model_spec
Expand All @@ -24,7 +25,7 @@ def _google_api_key() -> str | None:
return key or None


def build_native_gemini_model(normalized_spec: str) -> str | GoogleModel:
def build_native_gemini_model(normalized_spec: str) -> str | GoogleModel | OpenAIModel:
"""À partir d’une spec déjà normalisée (``google-gla:…``, ``openai:…``), retourne un modèle ou la chaîne OpenAI."""
spec = normalize_provider_model_spec(normalized_spec)
low = spec.lower()
Expand All @@ -34,4 +35,7 @@ def build_native_gemini_model(normalized_spec: str) -> str | GoogleModel:
if low.startswith("google-vertex:"):
model_id = spec.split(":", 1)[1].strip()
return GeminiModel(model_id, provider=GoogleProvider(vertexai=True))
if low.startswith("openai:"):
model_id = spec.split(":", 1)[1].strip()
return OpenAIModel(model_id, api_key=os.getenv("OPENAI_API_KEY"))
Comment on lines +38 to +40
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Guard against empty or missing model id in the openai: spec

When normalized_spec is just "openai:" (or otherwise has nothing after the colon), model_id becomes an empty string and you end up constructing OpenAIModel(""), which may fail in a confusing way. Consider validating that model_id is non-empty and either returning spec unchanged or raising a clearer error for malformed specs.

return spec
8 changes: 6 additions & 2 deletions backend/tests/test_llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import pytest
from pydantic_ai.models.google import GoogleModel
from pydantic_ai.models.openai import OpenAIModel

from services.llm import GeminiModel, build_native_gemini_model

Expand All @@ -10,8 +11,11 @@ def test_gemini_model_alias_is_google_model() -> None:
assert GeminiModel is GoogleModel


def test_build_native_openai_returns_string() -> None:
assert build_native_gemini_model("openai:gpt-4o-mini") == "openai:gpt-4o-mini"
def test_build_native_openai_returns_openai_model(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("OPENAI_API_KEY", "test-openai-key")
m = build_native_gemini_model("openai:gpt-4o-mini")
assert isinstance(m, OpenAIModel)
assert m.model_name == "gpt-4o-mini"
Comment on lines +14 to +18
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Also assert the OpenAIModel api_key to verify that OPENAI_API_KEY wiring works as expected.

The current test only checks that we build an OpenAIModel with the expected model_name. Please also assert that m.api_key == "test-openai-key" (or equivalent) so the test verifies the OPENAI_API_KEY env var is correctly wired into the model.

Suggested change
def test_build_native_openai_returns_openai_model(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("OPENAI_API_KEY", "test-openai-key")
m = build_native_gemini_model("openai:gpt-4o-mini")
assert isinstance(m, OpenAIModel)
assert m.model_name == "gpt-4o-mini"
def test_build_native_openai_returns_openai_model(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("OPENAI_API_KEY", "test-openai-key")
m = build_native_gemini_model("openai:gpt-4o-mini")
assert isinstance(m, OpenAIModel)
assert m.model_name == "gpt-4o-mini"
assert m.api_key == "test-openai-key"



def test_build_native_google_gla_returns_google_model(monkeypatch: pytest.MonkeyPatch) -> None:
Expand Down
Loading