mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-09 03:18:44 +00:00
test_azure_responses_api_status_error
This commit is contained in:
parent
86881a8fc1
commit
ce6102d54f
2 changed files with 122 additions and 14 deletions
|
|
@ -41,12 +41,10 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig):
|
|||
|
||||
def _handle_reasoning_item(self, item: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""
|
||||
Handle reasoning items specifically to filter out status=None using OpenAI's model.
|
||||
Handle reasoning items to filter out the status field.
|
||||
Issue: https://github.com/BerriAI/litellm/issues/13484
|
||||
OpenAI API does not accept ReasoningItem(status=None), so we need to:
|
||||
1. Check if the item is a reasoning type
|
||||
2. Create a ResponseReasoningItem object with the item data
|
||||
3. Convert it back to dict with exclude_none=True to filter None values
|
||||
|
||||
Azure OpenAI API does not accept 'status' field in reasoning input items.
|
||||
"""
|
||||
if item.get("type") == "reasoning":
|
||||
try:
|
||||
|
|
@ -82,6 +80,30 @@ class AzureOpenAIResponsesAPIConfig(OpenAIResponsesAPIConfig):
|
|||
}
|
||||
return filtered_item
|
||||
return item
|
||||
|
||||
def _validate_input_param(
|
||||
self, input: Union[str, ResponseInputParam]
|
||||
) -> Union[str, ResponseInputParam]:
|
||||
"""
|
||||
Override parent method to also filter out 'status' field from message items.
|
||||
Azure OpenAI API does not accept 'status' field in input messages.
|
||||
"""
|
||||
# First call parent's validation
|
||||
validated_input = super()._validate_input_param(input)
|
||||
|
||||
# Then filter out status from message items
|
||||
if isinstance(validated_input, list):
|
||||
filtered_input = []
|
||||
for item in validated_input:
|
||||
if isinstance(item, dict) and item.get("type") == "message":
|
||||
# Filter out status field from message items
|
||||
filtered_item = {k: v for k, v in item.items() if k != "status"}
|
||||
filtered_input.append(filtered_item)
|
||||
else:
|
||||
filtered_input.append(item)
|
||||
return filtered_input # type: ignore
|
||||
|
||||
return validated_input
|
||||
|
||||
def transform_responses_api_request(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -50,9 +50,11 @@ async def test_azure_responses_api_preview_api_version():
|
|||
@pytest.mark.asyncio
|
||||
async def test_azure_responses_api_status_error():
|
||||
"""
|
||||
Ensure new azure preview api version is working
|
||||
Test that 'status' field is not sent in the final request body to Azure API.
|
||||
The status field should be filtered out from input messages before making the API call.
|
||||
"""
|
||||
litellm._turn_on_debug()
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
import json
|
||||
|
||||
request_data = {
|
||||
"model": "computer-use-preview",
|
||||
|
|
@ -88,11 +90,95 @@ async def test_azure_responses_api_status_error():
|
|||
"stream": False,
|
||||
"tools": [],
|
||||
}
|
||||
response = await litellm.aresponses(
|
||||
model="azure/computer-use-preview",
|
||||
truncation="auto",
|
||||
api_version="preview",
|
||||
api_base=os.getenv("AZURE_RESPONSES_OPENAI_ENDPOINT"),
|
||||
api_key=os.getenv("AZURE_RESPONSES_OPENAI_API_KEY"),
|
||||
input=request_data["input"],
|
||||
|
||||
# Mock response
|
||||
mock_response_data = {
|
||||
"id": "resp_123",
|
||||
"object": "response",
|
||||
"created_at": 1234567890,
|
||||
"model": "computer-use-preview",
|
||||
"status": "completed",
|
||||
"output": [
|
||||
{
|
||||
"id": "msg_123",
|
||||
"role": "assistant",
|
||||
"type": "message",
|
||||
"status": "completed",
|
||||
"content": [{"type": "output_text", "text": "Here's an interesting fact."}],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
captured_request_body = {}
|
||||
|
||||
async def mock_post(*args, **kwargs):
|
||||
# Capture the request body
|
||||
nonlocal captured_request_body
|
||||
if "json" in kwargs:
|
||||
captured_request_body = kwargs["json"]
|
||||
elif "data" in kwargs:
|
||||
captured_request_body = json.loads(kwargs["data"])
|
||||
|
||||
import httpx
|
||||
|
||||
# Create a proper httpx Response object
|
||||
response_content = json.dumps(mock_response_data).encode("utf-8")
|
||||
response = httpx.Response(
|
||||
status_code=200,
|
||||
headers={"content-type": "application/json"},
|
||||
content=response_content,
|
||||
request=httpx.Request(method="POST", url="https://test.openai.azure.com"),
|
||||
)
|
||||
return response
|
||||
|
||||
from litellm.llms.custom_httpx.http_handler import AsyncHTTPHandler
|
||||
from unittest.mock import patch
|
||||
|
||||
with patch.object(AsyncHTTPHandler, "post", new=mock_post):
|
||||
response = await litellm.aresponses(
|
||||
model="azure/computer-use-preview",
|
||||
truncation="auto",
|
||||
api_version="preview",
|
||||
api_base="https://test.openai.azure.com",
|
||||
api_key="test-key",
|
||||
input=request_data["input"],
|
||||
)
|
||||
|
||||
# Verify that 'status' field is not present in any of the input messages
|
||||
print("Final request body:", json.dumps(captured_request_body, indent=4, default=str))
|
||||
assert "input" in captured_request_body, "Request body should contain 'input' field"
|
||||
|
||||
expected_input = [
|
||||
{
|
||||
"content": "tell me an interesting fact",
|
||||
"role": "user"
|
||||
},
|
||||
{
|
||||
"id": "rs_0ab687487834d9df0068e462a1b2d88197aabbc832c9ba5316",
|
||||
"summary": [],
|
||||
"type": "reasoning"
|
||||
},
|
||||
{
|
||||
"id": "msg_0ab687487834d9df0068e462a1df188197b74b1eef05102c18",
|
||||
"content": [
|
||||
{
|
||||
"annotations": [],
|
||||
"text": "very good morning",
|
||||
"type": "output_text",
|
||||
"logprobs": []
|
||||
}
|
||||
],
|
||||
"role": "assistant",
|
||||
"type": "message"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "tell me another"
|
||||
}
|
||||
]
|
||||
|
||||
assert captured_request_body["input"] == expected_input, (
|
||||
f"Request body input should match expected format without 'status' field.\n"
|
||||
f"Expected: {json.dumps(expected_input, indent=2)}\n"
|
||||
f"Got: {json.dumps(captured_request_body['input'], indent=2)}"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue