mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-04 07:27:51 +00:00
* refactor(litellm): migrate private usage in llms Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(litellm): preserve Bedrock batch signature marker Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(litellm): migrate llms private usage symbols Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(litellm): preserve UUID Watsonx project IDs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(litellm): retarget llms mocks to public names Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(litellm): limit llms changes to renames and forwarders Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(litellm): keep GCS mock client patching private Vertex auth methods Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(litellm): assert forwarder arguments and type forwarder signatures Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: mateo <mateo@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
176 lines
5.6 KiB
Python
176 lines
5.6 KiB
Python
"""
|
|
Unit tests for SambaNova chat message transformation
|
|
"""
|
|
|
|
import asyncio
|
|
import importlib
|
|
|
|
import pytest
|
|
|
|
import litellm
|
|
from litellm.llms.sambanova.chat import SambanovaConfig
|
|
from tests._vcr_conftest_common import install_live_call_probe, record_vcr_outcome
|
|
|
|
|
|
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"
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def _vcr_outcome_gate(request, vcr):
|
|
install_live_call_probe(request, vcr)
|
|
yield
|
|
record_vcr_outcome(request, vcr)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def event_loop():
|
|
try:
|
|
loop = asyncio.get_running_loop()
|
|
except RuntimeError:
|
|
loop = asyncio.new_event_loop()
|
|
yield loop
|
|
loop.close()
|
|
|
|
|
|
@pytest.fixture(scope="function", autouse=True)
|
|
def setup_and_teardown(event_loop):
|
|
import litellm
|
|
|
|
original_state = {}
|
|
for attr in (
|
|
"callbacks",
|
|
"success_callback",
|
|
"failure_callback",
|
|
"_async_success_callback",
|
|
"_async_failure_callback",
|
|
):
|
|
if hasattr(litellm, attr):
|
|
val = getattr(litellm, attr)
|
|
original_state[attr] = val.copy() if val else []
|
|
for attr in _SCALAR_DEFAULTS:
|
|
if hasattr(litellm, attr):
|
|
original_state[attr] = getattr(litellm, attr)
|
|
from litellm.litellm_core_utils.logging_worker import GLOBAL_LOGGING_WORKER
|
|
|
|
asyncio.run(GLOBAL_LOGGING_WORKER.clear_queue())
|
|
importlib.reload(litellm)
|
|
asyncio.set_event_loop(event_loop)
|
|
yield
|
|
for attr, original_value in original_state.items():
|
|
if hasattr(litellm, attr):
|
|
setattr(litellm, attr, original_value)
|
|
pending = asyncio.all_tasks(event_loop)
|
|
for task in pending:
|
|
task.cancel()
|
|
if pending:
|
|
event_loop.run_until_complete(asyncio.gather(*pending, return_exceptions=True))
|
|
|
|
|
|
_SCALAR_DEFAULTS = {
|
|
"num_retries": getattr(litellm, "num_retries", None),
|
|
"set_verbose": getattr(litellm, "set_verbose", False),
|
|
"cache": getattr(litellm, "cache", None),
|
|
"allowed_fails": getattr(litellm, "allowed_fails", 3),
|
|
"disable_aiohttp_transport": getattr(litellm, "disable_aiohttp_transport", False),
|
|
"force_ipv4": getattr(litellm, "force_ipv4", False),
|
|
"drop_params": getattr(litellm, "drop_params", None),
|
|
"modify_params": getattr(litellm, "modify_params", False),
|
|
"api_base": getattr(litellm, "api_base", None),
|
|
"api_key": getattr(litellm, "api_key", None),
|
|
"cohere_key": getattr(litellm, "cohere_key", None),
|
|
}
|