ppt-web / tests /test_openai_provider_responses_api.py
26fwyzpz6f-max
Clean deploy without binary files
6aecb2e
Raw
History Blame Contribute Delete
6.07 kB
import os
import sys
import types
import pytest
os.environ["DEBUG"] = "false"
from landppt.ai.base import AIMessage, MessageRole
from landppt.ai.providers import OpenAIProvider
class _FailingChatCompletions:
async def create(self, **kwargs):
raise AssertionError("chat.completions.create should not be used when responses API is enabled")
class _FakeChatCompletions:
def __init__(self):
self.create_calls = []
async def create(self, **kwargs):
self.create_calls.append(kwargs)
return types.SimpleNamespace(
model=kwargs["model"],
choices=[
types.SimpleNamespace(
message=types.SimpleNamespace(content="Hello from chat completions"),
finish_reason="stop",
)
],
usage=types.SimpleNamespace(prompt_tokens=13, completion_tokens=8, total_tokens=21),
)
class _FakeResponsesStream:
def __init__(self, events):
self._events = list(events)
def __aiter__(self):
async def _iterate():
for event in self._events:
yield event
return _iterate()
class _FakeResponsesStreamManager:
def __init__(self, events):
self._events = events
async def __aenter__(self):
return _FakeResponsesStream(self._events)
async def __aexit__(self, exc_type, exc, tb):
return None
class _FakeResponsesAPI:
def __init__(self):
self.create_calls = []
self.stream_calls = []
async def create(self, **kwargs):
self.create_calls.append(kwargs)
return types.SimpleNamespace(
model=kwargs["model"],
output_text="Hello from responses",
usage=types.SimpleNamespace(input_tokens=11, output_tokens=7, total_tokens=18),
status="completed",
incomplete_details=None,
)
def stream(self, **kwargs):
self.stream_calls.append(kwargs)
events = [
types.SimpleNamespace(type="response.output_text.delta", delta="Hello "),
types.SimpleNamespace(type="response.output_text.delta", delta="from "),
types.SimpleNamespace(type="response.output_text.delta", delta="responses"),
]
return _FakeResponsesStreamManager(events)
@pytest.mark.asyncio
async def test_openai_provider_chat_completion_uses_responses_api(monkeypatch):
instances = []
class _FakeAsyncOpenAI:
def __init__(self, **kwargs):
self.responses = _FakeResponsesAPI()
self.chat = types.SimpleNamespace(completions=_FailingChatCompletions())
instances.append(self)
monkeypatch.setitem(sys.modules, "openai", types.SimpleNamespace(AsyncOpenAI=_FakeAsyncOpenAI))
provider = OpenAIProvider(
{
"api_key": "test-key",
"base_url": "https://api.openai.com/v1",
"model": "gpt-4.1",
"use_responses_api": True,
"enable_reasoning": True,
"reasoning_effort": "high",
}
)
response = await provider.chat_completion(
[AIMessage(role=MessageRole.USER, content="hello")],
max_output_tokens=16,
)
assert response.content == "Hello from responses"
assert response.usage == {"prompt_tokens": 11, "completion_tokens": 7, "total_tokens": 18}
assert response.metadata["transport"] == "responses"
assert len(instances) == 1
assert instances[0].responses.create_calls[0]["input"][0]["content"] == "hello"
assert instances[0].responses.create_calls[0]["reasoning"] == {"effort": "high"}
assert "max_output_tokens" not in instances[0].responses.create_calls[0]
@pytest.mark.asyncio
async def test_openai_provider_streaming_uses_responses_api(monkeypatch):
instances = []
class _FakeAsyncOpenAI:
def __init__(self, **kwargs):
self.responses = _FakeResponsesAPI()
self.chat = types.SimpleNamespace(completions=_FailingChatCompletions())
instances.append(self)
monkeypatch.setitem(sys.modules, "openai", types.SimpleNamespace(AsyncOpenAI=_FakeAsyncOpenAI))
provider = OpenAIProvider(
{
"api_key": "test-key",
"base_url": "https://api.openai.com/v1",
"model": "gpt-4.1",
"use_responses_api": True,
"enable_reasoning": True,
"reasoning_effort": "minimal",
}
)
chunks = []
async for chunk in provider.stream_chat_completion(
[AIMessage(role=MessageRole.USER, content="hello")],
):
chunks.append(chunk)
assert "".join(chunks) == "Hello from responses"
assert len(instances) == 1
assert instances[0].responses.stream_calls[0]["input"][0]["content"] == "hello"
assert instances[0].responses.stream_calls[0]["reasoning"] == {"effort": "minimal"}
@pytest.mark.asyncio
async def test_openai_provider_chat_completions_uses_reasoning_effort(monkeypatch):
instances = []
class _FakeAsyncOpenAI:
def __init__(self, **kwargs):
self.responses = _FakeResponsesAPI()
self.chat = types.SimpleNamespace(completions=_FakeChatCompletions())
instances.append(self)
monkeypatch.setitem(sys.modules, "openai", types.SimpleNamespace(AsyncOpenAI=_FakeAsyncOpenAI))
provider = OpenAIProvider(
{
"api_key": "test-key",
"base_url": "https://api.openai.com/v1",
"model": "gpt-4.1",
"max_tokens": 4096,
"enable_reasoning": True,
"reasoning_effort": "low",
}
)
response = await provider.chat_completion(
[AIMessage(role=MessageRole.USER, content="hello")],
)
assert response.content == "Hello from chat completions"
assert response.metadata["transport"] == "chat_completions"
assert len(instances) == 1
assert instances[0].chat.completions.create_calls[0]["reasoning_effort"] == "low"
assert "max_tokens" not in instances[0].chat.completions.create_calls[0]