init
This commit is contained in:
@@ -0,0 +1,123 @@
|
||||
from types import SimpleNamespace
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from pydantic import BaseModel
|
||||
|
||||
from resume_agent.llm import LLMError, OpenAILLM
|
||||
|
||||
|
||||
class LoggedResult(BaseModel):
|
||||
answer: str
|
||||
|
||||
|
||||
def fake_client(parsed: BaseModel) -> Any:
|
||||
class Completions:
|
||||
def parse(self, **kwargs: Any) -> Any:
|
||||
return SimpleNamespace(
|
||||
choices=[SimpleNamespace(message=SimpleNamespace(parsed=parsed))]
|
||||
)
|
||||
|
||||
return SimpleNamespace(
|
||||
base_url="https://llm.example/v1/",
|
||||
chat=SimpleNamespace(completions=Completions()),
|
||||
)
|
||||
|
||||
|
||||
def test_custom_endpoint_defaults_to_chat(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.setenv("RESUME_AGENT_MODEL", "example-model")
|
||||
monkeypatch.delenv("RESUME_AGENT_API_STYLE", raising=False)
|
||||
monkeypatch.delenv("RESUME_AGENT_LLM_TIMEOUT_SECONDS", raising=False)
|
||||
|
||||
llm = OpenAILLM()
|
||||
|
||||
assert llm.model == "example-model"
|
||||
assert llm.api_style == "chat"
|
||||
assert llm.timeout_seconds == 1800
|
||||
assert str(llm.client.base_url) == "https://llm.example/v1/"
|
||||
|
||||
|
||||
def test_custom_endpoint_allows_model_discovery(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.delenv("RESUME_AGENT_MODEL", raising=False)
|
||||
|
||||
llm = OpenAILLM()
|
||||
|
||||
assert llm.model is None
|
||||
|
||||
|
||||
def test_parse_requires_model(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.delenv("RESUME_AGENT_MODEL", raising=False)
|
||||
|
||||
with pytest.raises(LLMError, match="RESUME_AGENT_MODEL"):
|
||||
OpenAILLM().parse(dict, "instructions", "input") # type: ignore[type-var]
|
||||
|
||||
|
||||
def test_custom_llm_timeout(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.setenv("RESUME_AGENT_MODEL", "example-model")
|
||||
monkeypatch.setenv("RESUME_AGENT_LLM_TIMEOUT_SECONDS", "2700")
|
||||
|
||||
llm = OpenAILLM()
|
||||
|
||||
assert llm.timeout_seconds == 2700
|
||||
assert llm.client.timeout.read == 2700
|
||||
assert llm.client.timeout.connect == 30
|
||||
|
||||
|
||||
def test_llm_timeout_must_be_positive(monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.setenv("RESUME_AGENT_MODEL", "example-model")
|
||||
monkeypatch.setenv("RESUME_AGENT_LLM_TIMEOUT_SECONDS", "0")
|
||||
|
||||
with pytest.raises(LLMError, match="greater than zero"):
|
||||
OpenAILLM()
|
||||
|
||||
|
||||
def test_model_queries_log_payloads_to_stdout(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.setenv("RESUME_AGENT_MODEL", "example-model")
|
||||
monkeypatch.setenv("RESUME_AGENT_LOG_MODEL_PAYLOADS", "true")
|
||||
llm = OpenAILLM()
|
||||
llm.client = fake_client(LoggedResult(answer="done"))
|
||||
|
||||
with caplog.at_level("INFO", logger="resume_agent.model"):
|
||||
llm.parse(LoggedResult, "System logging test", "Private resume input")
|
||||
|
||||
output = caplog.text
|
||||
assert "event=start" in output
|
||||
assert "System logging test" in output
|
||||
assert "Private resume input" in output
|
||||
assert '"answer": "done"' in output
|
||||
assert "test-token" not in output
|
||||
|
||||
|
||||
def test_model_payload_logging_can_be_disabled(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
monkeypatch.setenv("RESUME_AGENT_API_KEY", "test-token")
|
||||
monkeypatch.setenv("RESUME_AGENT_BASE_URL", "https://llm.example/v1")
|
||||
monkeypatch.setenv("RESUME_AGENT_MODEL", "example-model")
|
||||
monkeypatch.setenv("RESUME_AGENT_LOG_MODEL_PAYLOADS", "false")
|
||||
llm = OpenAILLM()
|
||||
llm.client = fake_client(LoggedResult(answer="done"))
|
||||
|
||||
with caplog.at_level("INFO", logger="resume_agent.model"):
|
||||
llm.parse(LoggedResult, "Hidden system prompt", "Hidden resume input")
|
||||
|
||||
output = caplog.text
|
||||
assert "event=start" in output
|
||||
assert "Hidden system prompt" not in output
|
||||
assert "Hidden resume input" not in output
|
||||
Reference in New Issue
Block a user