|
@@ -51,6 +51,113 @@ def test_cache_prompt_and_endpoint_are_sent():
|
|
|
assert calls[0]["__url__"] == LlmConfig().endpoint
|
|
assert calls[0]["__url__"] == LlmConfig().endpoint
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def test_model_is_sent_when_set():
|
|
|
|
|
+ cfg = LlmConfig(model="gpt-4o-mini")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["body"]["model"] == "gpt-4o-mini"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_model_omitted_when_empty():
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"))
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert "model" not in calls[0]["body"]
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_api_key_env_adds_bearer_header(monkeypatch):
|
|
|
|
|
+ monkeypatch.setenv("STT_TEST_LLM_KEY", "sekret")
|
|
|
|
|
+ cfg = LlmConfig(api_key_env="STT_TEST_LLM_KEY")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["headers"]["Authorization"] == "Bearer sekret"
|
|
|
|
|
+ assert calls[0]["headers"]["Content-Type"] == "application/json"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_missing_api_key_env_sends_no_authorization(monkeypatch):
|
|
|
|
|
+ monkeypatch.delenv("STT_TEST_LLM_KEY", raising=False)
|
|
|
|
|
+ cfg = LlmConfig(api_key_env="STT_TEST_LLM_KEY")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert "Authorization" not in calls[0]["headers"]
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_no_api_key_sends_only_content_type(monkeypatch):
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"))
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["headers"] == {"Content-Type": "application/json"}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_session_header_and_user_agent_sent_when_set():
|
|
|
|
|
+ cfg = LlmConfig(
|
|
|
|
|
+ session_header="x-opencode-session",
|
|
|
|
|
+ session_id="stt-chat",
|
|
|
|
|
+ user_agent="stt-daemon/1.0",
|
|
|
|
|
+ )
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["headers"]["x-opencode-session"] == "stt-chat"
|
|
|
|
|
+ assert calls[0]["headers"]["User-Agent"] == "stt-daemon/1.0"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_session_header_omitted_when_id_empty(caplog):
|
|
|
|
|
+ cfg = LlmConfig(session_header="x-opencode-session", session_id="")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert "x-opencode-session" not in calls[0]["headers"]
|
|
|
|
|
+ assert "session_id is empty" in caplog.text
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_session_header_omitted_when_header_empty():
|
|
|
|
|
+ cfg = LlmConfig(session_header="", session_id="stt-chat")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert "stt-chat" not in calls[0]["headers"].values()
|
|
|
|
|
+ assert calls[0]["headers"] == {"Content-Type": "application/json"}
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_reasoning_effort_is_sent_when_set():
|
|
|
|
|
+ cfg = LlmConfig(reasoning_effort="high")
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["body"]["reasoning_effort"] == "high"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_reasoning_effort_omitted_when_empty():
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"))
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert "reasoning_effort" not in calls[0]["body"]
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_extra_body_merged_and_overrides_defaults():
|
|
|
|
|
+ cfg = LlmConfig(extra_body={"enable_thinking": True, "temperature": 0.1})
|
|
|
|
|
+ client, calls = _make_client(lambda _p: _reply(content="ok"), cfg)
|
|
|
|
|
+
|
|
|
|
|
+ client.chat([{"role": "user", "content": "hi"}])
|
|
|
|
|
+
|
|
|
|
|
+ assert calls[0]["body"]["enable_thinking"] is True
|
|
|
|
|
+ assert calls[0]["body"]["temperature"] == 0.1
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def test_tools_sent_only_when_provided():
|
|
def test_tools_sent_only_when_provided():
|
|
|
client, calls = _make_client(lambda _p: _reply(content="ok"))
|
|
client, calls = _make_client(lambda _p: _reply(content="ok"))
|
|
|
client.chat([{"role": "user", "content": "hi"}])
|
|
client.chat([{"role": "user", "content": "hi"}])
|