mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-10 03:28:53 +00:00
[Bug fix] Fixes SambaNova API rejecting requests when message content is passed as a list format (#16612)
* add runwayml_models * test_call_with_end_user_over_budget * TestSambanovaContentListHandling * add _transform_messages for sambanova
This commit is contained in:
parent
3feae855bd
commit
4a486dc669
2 changed files with 159 additions and 1 deletions
|
|
@ -4,9 +4,13 @@ Sambanova Chat Completions API
|
|||
this is OpenAI compatible - no translation needed / occurs
|
||||
"""
|
||||
|
||||
from typing import Optional, Union
|
||||
from typing import Any, Coroutine, List, Literal, Optional, Union, overload
|
||||
|
||||
from litellm.litellm_core_utils.prompt_templates.common_utils import (
|
||||
handle_messages_with_content_list_to_str_conversion,
|
||||
)
|
||||
from litellm.llms.openai.chat.gpt_transformation import OpenAIGPTConfig
|
||||
from litellm.types.llms.openai import AllMessageValues
|
||||
|
||||
|
||||
class SambanovaConfig(OpenAIGPTConfig):
|
||||
|
|
@ -92,3 +96,30 @@ class SambanovaConfig(OpenAIGPTConfig):
|
|||
elif param in supported_openai_params:
|
||||
optional_params[param] = value
|
||||
return optional_params
|
||||
|
||||
@overload
|
||||
def _transform_messages(
|
||||
self, messages: List[AllMessageValues], model: str, is_async: Literal[True]
|
||||
) -> Coroutine[Any, Any, List[AllMessageValues]]:
|
||||
...
|
||||
|
||||
@overload
|
||||
def _transform_messages(
|
||||
self,
|
||||
messages: List[AllMessageValues],
|
||||
model: str,
|
||||
is_async: Literal[False] = False,
|
||||
) -> List[AllMessageValues]:
|
||||
...
|
||||
|
||||
def _transform_messages(
|
||||
self, messages: List[AllMessageValues], model: str, is_async: bool = False
|
||||
) -> Union[List[AllMessageValues], Coroutine[Any, Any, List[AllMessageValues]]]:
|
||||
"""
|
||||
Transform messages to handle content list conversion.
|
||||
|
||||
SambaNova API doesn't support content as a list - only string content.
|
||||
This converts content lists like [{"type": "text", "text": "..."}] to strings.
|
||||
"""
|
||||
messages = handle_messages_with_content_list_to_str_conversion(messages)
|
||||
return messages
|
||||
|
|
|
|||
127
tests/llm_translation/test_sambanova_chat_transformation.py
Normal file
127
tests/llm_translation/test_sambanova_chat_transformation.py
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
"""
|
||||
Unit tests for SambaNova chat message transformation
|
||||
"""
|
||||
import pytest
|
||||
from litellm.llms.sambanova.chat import SambanovaConfig
|
||||
|
||||
|
||||
class TestSambanovaContentListHandling:
|
||||
"""
|
||||
Test that SambaNova properly transforms content lists to strings
|
||||
"""
|
||||
|
||||
def test_content_list_to_string_transformation(self):
|
||||
"""
|
||||
Test content list with text objects is converted to string.
|
||||
|
||||
SambaNova API doesn't support content as a list - only string content.
|
||||
"""
|
||||
config = SambanovaConfig()
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Hello, how are you?"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
transformed_messages = config._transform_messages(
|
||||
messages=messages,
|
||||
model="sambanova/gpt-oss-120b",
|
||||
is_async=False
|
||||
)
|
||||
|
||||
assert len(transformed_messages) == 1
|
||||
assert transformed_messages[0]["role"] == "user"
|
||||
assert isinstance(transformed_messages[0]["content"], str)
|
||||
assert transformed_messages[0]["content"] == "Hello, how are you?"
|
||||
|
||||
def test_content_list_multiple_text_blocks(self):
|
||||
"""
|
||||
Test content list with multiple text blocks is converted to concatenated string.
|
||||
"""
|
||||
config = SambanovaConfig()
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Hello, "},
|
||||
{"type": "text", "text": "how are you?"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
transformed_messages = config._transform_messages(
|
||||
messages=messages,
|
||||
model="sambanova/gpt-oss-120b",
|
||||
is_async=False
|
||||
)
|
||||
|
||||
assert transformed_messages[0]["content"] == "Hello, how are you?"
|
||||
|
||||
def test_string_content_unchanged(self):
|
||||
"""
|
||||
Test that string content is passed through unchanged.
|
||||
"""
|
||||
config = SambanovaConfig()
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Hello, how are you?"
|
||||
}
|
||||
]
|
||||
|
||||
transformed_messages = config._transform_messages(
|
||||
messages=messages,
|
||||
model="sambanova/gpt-oss-120b",
|
||||
is_async=False
|
||||
)
|
||||
|
||||
assert transformed_messages[0]["content"] == "Hello, how are you?"
|
||||
|
||||
def test_multiple_messages_transformation(self):
|
||||
"""
|
||||
Test transformation of multiple messages with mixed content types.
|
||||
"""
|
||||
config = SambanovaConfig()
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "system",
|
||||
"content": "You are a helpful assistant."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "What is the weather?"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "I need your location."
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "I'm in "},
|
||||
{"type": "text", "text": "San Francisco"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
transformed_messages = config._transform_messages(
|
||||
messages=messages,
|
||||
model="sambanova/gpt-oss-120b",
|
||||
is_async=False
|
||||
)
|
||||
|
||||
assert len(transformed_messages) == 4
|
||||
assert transformed_messages[0]["content"] == "You are a helpful assistant."
|
||||
assert transformed_messages[1]["content"] == "What is the weather?"
|
||||
assert transformed_messages[2]["content"] == "I need your location."
|
||||
assert transformed_messages[3]["content"] == "I'm in San Francisco"
|
||||
|
||||
Loading…
Add table
Reference in a new issue