polyglot-tutor / tests /test_llm.py
blizzarman's picture
feat: M0 walking skeleton (app, service protocols, CI/CD, Space deploy)
00d5ae5
Raw
History Blame Contribute Delete
1.96 kB
import pytest
from tutor.config import Settings
from tutor.services.llm.base import ChatMessage, LLMClient
from tutor.services.llm.factory import GEMINI_OPENAI_BASE_URL, create_llm_client
from tutor.services.llm.fake import FakeLLMClient
from tutor.services.llm.openai_compat import OpenAICompatClient
def _settings(**overrides: object) -> Settings:
return Settings(_env_file=None, **overrides) # type: ignore[arg-type]
async def test_fake_client_is_deterministic_and_records_calls() -> None:
client = FakeLLMClient(responses=["first", "second"])
messages = [ChatMessage(role="user", content="hello")]
first = await client.complete(messages)
second = await client.complete(messages)
third = await client.complete(messages) # queue exhausted -> default
assert (first.text, second.text) == ("first", "second")
assert third.text == "(fake) pong"
assert len(client.calls) == 3
assert client.calls[0][0].content == "hello"
def test_fake_satisfies_protocol() -> None:
assert isinstance(FakeLLMClient(), LLMClient)
def test_factory_returns_fake_by_default() -> None:
client = create_llm_client(_settings())
assert isinstance(client, FakeLLMClient)
def test_factory_requires_api_key_for_remote_providers() -> None:
with pytest.raises(ValueError, match="LLM_API_KEY"):
create_llm_client(_settings(llm_provider="gemini"))
def test_factory_builds_openai_compat_client_with_gemini_preset() -> None:
settings = _settings(llm_provider="gemini", llm_api_key="sk-test", llm_model="gemini-2.5-flash")
client = create_llm_client(settings)
assert isinstance(client, OpenAICompatClient)
assert client.model == "gemini-2.5-flash"
assert str(client._client.base_url) == GEMINI_OPENAI_BASE_URL
def test_factory_allows_keyless_ollama() -> None:
client = create_llm_client(_settings(llm_provider="ollama", llm_model="llama3"))
assert isinstance(client, OpenAICompatClient)