Files
openai--openai-agents-python/tests/models/test_remove_openai_responses_api_incompatible_fields.py
2026-07-13 12:39:17 +08:00

163 lines
6.1 KiB
Python

from __future__ import annotations
from typing import Any
from unittest.mock import MagicMock
import pytest
from agents.models.fake_id import FAKE_RESPONSES_ID
from agents.models.openai_responses import OpenAIResponsesModel
@pytest.fixture
def model() -> OpenAIResponsesModel:
"""Create a model instance for testing."""
mock_client = MagicMock()
return OpenAIResponsesModel(model="gpt-5", openai_client=mock_client)
class TestRemoveOpenAIResponsesAPIIncompatibleFields:
"""Tests for _remove_openai_responses_api_incompatible_fields method."""
def test_returns_unchanged_when_no_provider_data(self, model: OpenAIResponsesModel):
"""When no items have provider_data, the input should be returned unchanged."""
list_input = [
{"type": "message", "content": "hello"},
{"type": "function_call", "call_id": "call_123", "name": "test"},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert result is list_input # Same object reference.
def test_removes_reasoning_items_with_provider_data(self, model: OpenAIResponsesModel):
"""Reasoning items with provider_data should be completely removed."""
list_input = [
{"type": "message", "content": "hello"},
{"type": "reasoning", "provider_data": {"model": "gemini/gemini-3"}},
{"type": "function_call", "call_id": "call_123"},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert len(result) == 2
assert result[0] == {"type": "message", "content": "hello"}
assert result[1] == {"type": "function_call", "call_id": "call_123"}
def test_keeps_reasoning_items_without_provider_data(self, model: OpenAIResponsesModel):
"""Reasoning items without provider_data should be kept."""
list_input = [
{"type": "reasoning", "summary": []},
{"type": "message", "content": "hello", "provider_data": {"foo": "bar"}},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert len(result) == 2
assert result[0] == {"type": "reasoning", "summary": []}
assert result[1] == {"type": "message", "content": "hello"}
def test_removes_provider_data_from_all_items(self, model: OpenAIResponsesModel):
"""provider_data field should be removed from all dict items."""
list_input = [
{"type": "message", "content": "hello", "provider_data": {"model": "gemini/gemini-3"}},
{
"type": "function_call",
"call_id": "call_123",
"provider_data": {"model": "gemini/gemini-3"},
},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert len(result) == 2
assert "provider_data" not in result[0]
assert "provider_data" not in result[1]
def test_removes_fake_responses_id(self, model: OpenAIResponsesModel):
"""Items with id equal to FAKE_RESPONSES_ID should have their id removed."""
list_input = [
{
"type": "message",
"id": FAKE_RESPONSES_ID,
"content": "hello",
"provider_data": {"model": "gemini/gemini-3"},
},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert len(result) == 1
assert "id" not in result[0]
assert result[0]["content"] == "hello"
def test_preserves_real_ids(self, model: OpenAIResponsesModel):
"""Real IDs (not FAKE_RESPONSES_ID) should be preserved."""
list_input = [
{
"type": "message",
"id": "msg_real123",
"content": "hello",
"provider_data": {},
},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert result[0]["id"] == "msg_real123"
def test_handles_empty_list(self, model: OpenAIResponsesModel):
"""Empty list should be returned unchanged."""
list_input: list[dict[str, Any]] = []
result = model._remove_openai_responses_api_incompatible_fields(list_input)
assert result == []
def test_combined_scenario(self, model: OpenAIResponsesModel):
"""Test a realistic scenario with multiple items needing different processing."""
list_input = [
{"type": "message", "content": "user input"},
{"type": "reasoning", "summary": [], "provider_data": {"model": "gemini/gemini-3"}},
{
"type": "function_call",
"call_id": "call_abc_123",
"name": "get_weather",
"provider_data": {"model": "gemini/gemini-3"},
},
{
"type": "function_call_output",
"call_id": "call_abc_123",
"output": '{"temp": 72}',
},
{
"type": "message",
"id": FAKE_RESPONSES_ID,
"content": "The weather is 72F",
"provider_data": {"model": "gemini/gemini-3"},
},
]
result = model._remove_openai_responses_api_incompatible_fields(list_input)
# Should have 4 items (reasoning with provider_data removed).
assert len(result) == 4
# First item unchanged (no provider_data).
assert result[0] == {"type": "message", "content": "user input"}
# Function call: __thought__ suffix removed, provider_data removed.
assert result[1]["type"] == "function_call"
assert result[1]["call_id"] == "call_abc_123"
assert "provider_data" not in result[1]
# Function call output: __thought__ suffix removed, provider_data removed.
assert result[2]["type"] == "function_call_output"
assert result[2]["call_id"] == "call_abc_123"
# Last message: fake id removed, provider_data removed.
assert result[3]["type"] == "message"
assert result[3]["content"] == "The weather is 72F"
assert "id" not in result[3]
assert "provider_data" not in result[3]