MicroFish/backend/tests/test_openai_chat_compat.py

124 lines
3.2 KiB
Python

from types import SimpleNamespace
import pytest
from app.utils.openai_chat_compat import (
create_chat_completion,
extract_chat_completion_text,
is_gpt5_family,
)
class CompletionRecorder:
def __init__(self, result=None, error=None):
self.result = result or object()
self.error = error
self.calls = []
def create(self, **kwargs):
self.calls.append(kwargs)
if self.error is not None:
raise self.error
return self.result
def client_for(recorder):
return SimpleNamespace(chat=SimpleNamespace(completions=recorder))
def test_gpt5_uses_completion_token_limit_without_temperature():
recorder = CompletionRecorder()
messages = [{"role": "user", "content": "hello"}]
result = create_chat_completion(
client_for(recorder),
model="gpt-5-2025-08-07",
messages=messages,
temperature=0.2,
max_tokens=123,
response_format={"type": "json_object"},
)
assert result is recorder.result
assert recorder.calls == [
{
"model": "gpt-5-2025-08-07",
"messages": messages,
"max_completion_tokens": 123,
"response_format": {"type": "json_object"},
}
]
def test_legacy_model_preserves_original_request_shape():
recorder = CompletionRecorder()
messages = [{"role": "user", "content": "hello"}]
create_chat_completion(
client_for(recorder),
model="third-party-chat-model",
messages=messages,
temperature=0.7,
max_tokens=456,
response_format={"type": "json_object"},
)
assert recorder.calls == [
{
"model": "third-party-chat-model",
"messages": messages,
"temperature": 0.7,
"max_tokens": 456,
"response_format": {"type": "json_object"},
}
]
def test_provider_error_is_propagated_without_guessing_or_retrying():
provider_error = RuntimeError("unsupported max_tokens due to a server outage")
recorder = CompletionRecorder(error=provider_error)
with pytest.raises(RuntimeError) as captured:
create_chat_completion(
client_for(recorder),
model="legacy-model",
messages=[],
max_tokens=10,
)
assert captured.value is provider_error
assert len(recorder.calls) == 1
@pytest.mark.parametrize(
("model", "expected"),
[
("gpt-5", True),
(" GPT-5.1-mini ", True),
("gpt-4.1", False),
("my-gpt-5-proxy", False),
(None, False),
],
)
def test_gpt5_family_detection(model, expected):
assert is_gpt5_family(model) is expected
def test_extracts_text_from_supported_content_shapes():
response = SimpleNamespace(
choices=[
SimpleNamespace(
message=SimpleNamespace(
content=[
{"text": {"value": "first"}},
{"content": " second"},
SimpleNamespace(text=" third"),
]
)
)
]
)
assert extract_chat_completion_text(response) == "first second third"
assert extract_chat_completion_text(SimpleNamespace(choices=[])) == ""