mirror of
https://github.com/tiennm99/litellm.git
synced 2026-08-14 10:25:37 +00:00
fix: correct CompletionRequest messages type to match OpenAI API spec (#12980)
* fix: correct CompletionRequest messages type to match OpenAI API spec - Changed messages field type from List[str] to List[ChatCompletionMessageParam] - This ensures proper OpenAI API compatibility where messages should be objects with role and content fields - Fixes type inconsistency in completion request handling * feat(tests): Add comprehensive tests for CompletionRequest model - Add test_completion.py for litellm.types.completion module - Test ChatCompletionMessageParam type validation - Test tool message format compatibility - Test function message format (deprecated) - Test multimodal content (text + image) - Test default empty messages list - Test all optional parameters - Validate OpenAI ChatCompletion API message format compatibility
This commit is contained in:
@@ -164,7 +164,7 @@ ChatCompletionMessageParam = Union[
|
||||
|
||||
class CompletionRequest(BaseModel):
|
||||
model: str
|
||||
messages: List[str] = []
|
||||
messages: List[ChatCompletionMessageParam] = []
|
||||
timeout: Optional[Union[float, int]] = None
|
||||
temperature: Optional[float] = None
|
||||
top_p: Optional[float] = None
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
"""
|
||||
Tests for litellm.types.completion module
|
||||
|
||||
This test suite validates the CompletionRequest model and its compatibility with
|
||||
OpenAI ChatCompletion API message formats.
|
||||
|
||||
Usage:
|
||||
pytest tests/test_litellm/types/test_completion.py -v
|
||||
"""
|
||||
from typing import List
|
||||
|
||||
from litellm.types.completion import (
|
||||
CompletionRequest,
|
||||
ChatCompletionMessageParam
|
||||
)
|
||||
|
||||
|
||||
def test_completion_request_messages_type_validation():
|
||||
"""
|
||||
Test that CompletionRequest.messages field accepts proper ChatCompletionMessageParam types.
|
||||
"""
|
||||
# Valid message formats according to OpenAI API
|
||||
valid_messages: List[ChatCompletionMessageParam] = [
|
||||
{"role": "system", "content": "You are a helpful assistant"},
|
||||
{"role": "user", "content": "Hello, how are you?"},
|
||||
{"role": "assistant", "content": "I'm doing well, thank you!"},
|
||||
]
|
||||
|
||||
request = CompletionRequest(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=valid_messages
|
||||
)
|
||||
|
||||
assert request.model == "gpt-3.5-turbo"
|
||||
assert len(request.messages) == 3
|
||||
|
||||
|
||||
def test_completion_request_tool_message():
|
||||
"""
|
||||
Test CompletionRequest with tool message format.
|
||||
"""
|
||||
messages: List[ChatCompletionMessageParam] = [
|
||||
{"role": "user", "content": "Calculate 2+2"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_123",
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "calculate",
|
||||
"arguments": '{"expression": "2+2"}'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "tool",
|
||||
"content": "4",
|
||||
"tool_call_id": "call_123"
|
||||
}
|
||||
]
|
||||
|
||||
request = CompletionRequest(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=messages
|
||||
)
|
||||
|
||||
assert len(request.messages) == 3
|
||||
assert request.messages[1]["role"] == "assistant"
|
||||
assert request.messages[2]["role"] == "tool"
|
||||
|
||||
|
||||
def test_completion_request_function_message():
|
||||
"""
|
||||
Test CompletionRequest with deprecated function message format.
|
||||
"""
|
||||
messages: List[ChatCompletionMessageParam] = [
|
||||
{"role": "user", "content": "What's the weather?"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": None,
|
||||
"function_call": {
|
||||
"name": "get_weather",
|
||||
"arguments": '{"location": "NYC"}'
|
||||
}
|
||||
},
|
||||
{
|
||||
"role": "function",
|
||||
"name": "get_weather",
|
||||
"content": "Sunny, 75°F"
|
||||
}
|
||||
]
|
||||
|
||||
request = CompletionRequest(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=messages
|
||||
)
|
||||
|
||||
assert len(request.messages) == 3
|
||||
assert request.messages[2]["role"] == "function"
|
||||
assert request.messages[2]["name"] == "get_weather"
|
||||
|
||||
|
||||
def test_completion_request_multimodal_content():
|
||||
"""
|
||||
Test CompletionRequest with multimodal content (text + image).
|
||||
"""
|
||||
messages: List[ChatCompletionMessageParam] = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "What's in this image?"
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
request = CompletionRequest(
|
||||
model="gpt-4-vision-preview",
|
||||
messages=messages
|
||||
)
|
||||
|
||||
assert len(request.messages) == 1
|
||||
assert request.messages[0]["role"] == "user"
|
||||
|
||||
|
||||
def test_completion_request_empty_messages_default():
|
||||
"""
|
||||
Test that CompletionRequest defaults to empty messages list.
|
||||
"""
|
||||
request = CompletionRequest(model="gpt-3.5-turbo")
|
||||
|
||||
assert request.messages == []
|
||||
assert isinstance(request.messages, list)
|
||||
|
||||
|
||||
def test_completion_request_with_all_params():
|
||||
"""
|
||||
Test CompletionRequest with various optional parameters.
|
||||
"""
|
||||
messages: List[ChatCompletionMessageParam] = [
|
||||
{"role": "user", "content": "Hello"}
|
||||
]
|
||||
|
||||
request = CompletionRequest(
|
||||
model="gpt-3.5-turbo",
|
||||
messages=messages,
|
||||
temperature=0.7,
|
||||
max_tokens=100,
|
||||
top_p=0.9,
|
||||
frequency_penalty=0.0,
|
||||
presence_penalty=0.0,
|
||||
stop={"sequences": ["END"]},
|
||||
stream=False,
|
||||
n=1
|
||||
)
|
||||
|
||||
assert request.model == "gpt-3.5-turbo"
|
||||
assert request.temperature == 0.7
|
||||
assert request.max_tokens == 100
|
||||
assert request.top_p == 0.9
|
||||
assert request.frequency_penalty == 0.0
|
||||
assert request.presence_penalty == 0.0
|
||||
assert request.stream is False
|
||||
assert request.n == 1
|
||||
Reference in New Issue
Block a user