mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-12 23:01:41 +00:00
test(oci): add tests for dynamic max_tokens and empty message filtering
12 mocked tests covering: - Dynamic maxTokens lookup from model cost map - Fallback to DEFAULT_MAX_TOKENS for unknown models - User-provided max_tokens override - Filtering of empty/None assistant, system messages from Cohere chat history - Preservation of non-empty messages Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bff16253eb
commit
4f7ac6e72b
1 changed files with 194 additions and 0 deletions
|
|
@ -0,0 +1,194 @@
|
|||
"""
|
||||
Tests for OCI Cohere chat fixes:
|
||||
1. Dynamic maxTokens default via model cost map lookup
|
||||
2. Filtering empty messages from Cohere chat history
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# Adds the parent directory to the system path
|
||||
sys.path.insert(0, os.path.abspath("../../../../.."))
|
||||
|
||||
import litellm
|
||||
from litellm.llms.oci.chat.transformation import OCIChatConfig
|
||||
from litellm.types.llms.oci import OCIVendors
|
||||
from litellm.constants import DEFAULT_MAX_TOKENS
|
||||
|
||||
|
||||
TEST_COMPARTMENT_ID = "ocid1.compartment.oc1..xxxxxx"
|
||||
BASE_OCI_PARAMS = {
|
||||
"oci_region": "us-ashburn-1",
|
||||
"oci_user": "ocid1.user.oc1..xxxxxxEXAMPLExxxxxx",
|
||||
"oci_fingerprint": "4f:29:77:cc:b1:3e:55:ab:61:2a:de:47:f1:38:4c:90",
|
||||
"oci_tenancy": "ocid1.tenancy.oc1..xxxxxxEXAMPLExxxxxx",
|
||||
"oci_compartment_id": TEST_COMPARTMENT_ID,
|
||||
"oci_key": "<private_key.pem as string>",
|
||||
}
|
||||
|
||||
|
||||
class TestOCICohereMaxTokens:
|
||||
"""Tests for dynamic maxTokens default lookup."""
|
||||
|
||||
def test_max_tokens_uses_model_cost_map(self):
|
||||
"""When a model is in the cost map, maxTokens should use its max_output_tokens."""
|
||||
config = OCIChatConfig()
|
||||
|
||||
# oci/cohere.command-a-03-2025 has max_output_tokens=4000 in the cost map
|
||||
params = config._get_optional_params(
|
||||
OCIVendors.COHERE, BASE_OCI_PARAMS, model="oci/cohere.command-a-03-2025"
|
||||
)
|
||||
|
||||
assert params["maxTokens"] == 4000
|
||||
|
||||
def test_max_tokens_falls_back_to_default(self):
|
||||
"""When a model is NOT in the cost map, maxTokens should fall back to DEFAULT_MAX_TOKENS."""
|
||||
config = OCIChatConfig()
|
||||
|
||||
params = config._get_optional_params(
|
||||
OCIVendors.COHERE, BASE_OCI_PARAMS, model="oci/cohere.nonexistent-model"
|
||||
)
|
||||
|
||||
assert params["maxTokens"] == DEFAULT_MAX_TOKENS
|
||||
|
||||
def test_max_tokens_falls_back_when_model_is_none(self):
|
||||
"""When model is None, maxTokens should fall back to DEFAULT_MAX_TOKENS."""
|
||||
config = OCIChatConfig()
|
||||
|
||||
params = config._get_optional_params(
|
||||
OCIVendors.COHERE, BASE_OCI_PARAMS, model=None
|
||||
)
|
||||
|
||||
assert params["maxTokens"] == DEFAULT_MAX_TOKENS
|
||||
|
||||
def test_user_provided_max_tokens_overrides_default(self):
|
||||
"""User-provided max_tokens should override the dynamic default."""
|
||||
config = OCIChatConfig()
|
||||
|
||||
params_with_override = {**BASE_OCI_PARAMS, "max_tokens": 1024}
|
||||
params = config._get_optional_params(
|
||||
OCIVendors.COHERE, params_with_override, model="oci/cohere.command-a-03-2025"
|
||||
)
|
||||
|
||||
assert params["maxTokens"] == 1024
|
||||
|
||||
def test_get_max_tokens_for_model_known_model(self):
|
||||
"""_get_max_tokens_for_model should return the correct value for a known model."""
|
||||
result = OCIChatConfig._get_max_tokens_for_model("oci/cohere.command-a-03-2025")
|
||||
assert result == 4000
|
||||
|
||||
def test_get_max_tokens_for_model_unknown_model(self):
|
||||
"""_get_max_tokens_for_model should return DEFAULT_MAX_TOKENS for an unknown model."""
|
||||
result = OCIChatConfig._get_max_tokens_for_model("oci/unknown-model-xyz")
|
||||
assert result == DEFAULT_MAX_TOKENS
|
||||
|
||||
def test_get_max_tokens_for_model_none(self):
|
||||
"""_get_max_tokens_for_model should return DEFAULT_MAX_TOKENS when model is None."""
|
||||
result = OCIChatConfig._get_max_tokens_for_model(None)
|
||||
assert result == DEFAULT_MAX_TOKENS
|
||||
|
||||
|
||||
class TestOCICohereEmptyMessages:
|
||||
"""Tests for filtering empty messages from Cohere chat history.
|
||||
|
||||
Note: adapt_messages_to_cohere_standard() processes messages[:-1]
|
||||
(all messages except the last one, which is the current user message).
|
||||
The returned CohereMessage objects are Pydantic models with .role and
|
||||
.message attributes.
|
||||
"""
|
||||
|
||||
def test_empty_assistant_message_is_filtered(self):
|
||||
"""An assistant message with empty content should be excluded from chat history."""
|
||||
config = OCIChatConfig()
|
||||
messages = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": ""},
|
||||
{"role": "user", "content": "How are you?"},
|
||||
]
|
||||
|
||||
# messages[:-1] = ["Hello" (user), "" (assistant)]
|
||||
# Empty assistant is filtered, so only "Hello" remains
|
||||
history = config.adapt_messages_to_cohere_standard(messages)
|
||||
|
||||
assert len(history) == 1
|
||||
assert history[0].role == "USER"
|
||||
assert history[0].message == "Hello"
|
||||
|
||||
def test_empty_system_message_is_filtered(self):
|
||||
"""A system message with empty content should be excluded from chat history."""
|
||||
config = OCIChatConfig()
|
||||
messages = [
|
||||
{"role": "system", "content": ""},
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "user", "content": "Last message"},
|
||||
]
|
||||
|
||||
# messages[:-1] = ["" (system), "Hello" (user)]
|
||||
# Empty system is filtered, so only "Hello" remains
|
||||
history = config.adapt_messages_to_cohere_standard(messages)
|
||||
|
||||
assert len(history) == 1
|
||||
assert history[0].role == "USER"
|
||||
assert history[0].message == "Hello"
|
||||
|
||||
def test_none_content_message_is_filtered(self):
|
||||
"""A message with None content should be excluded from chat history."""
|
||||
config = OCIChatConfig()
|
||||
messages = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": None},
|
||||
{"role": "user", "content": "Last message"},
|
||||
]
|
||||
|
||||
# messages[:-1] = ["Hello" (user), None (assistant)]
|
||||
# None assistant is filtered, so only "Hello" remains
|
||||
history = config.adapt_messages_to_cohere_standard(messages)
|
||||
|
||||
assert len(history) == 1
|
||||
assert history[0].role == "USER"
|
||||
assert history[0].message == "Hello"
|
||||
|
||||
def test_non_empty_messages_are_preserved(self):
|
||||
"""Non-empty messages should be included in chat history normally."""
|
||||
config = OCIChatConfig()
|
||||
messages = [
|
||||
{"role": "user", "content": "Hello"},
|
||||
{"role": "assistant", "content": "Hi there!"},
|
||||
{"role": "user", "content": "Last message"},
|
||||
]
|
||||
|
||||
# messages[:-1] = ["Hello" (user), "Hi there!" (assistant)]
|
||||
history = config.adapt_messages_to_cohere_standard(messages)
|
||||
|
||||
assert len(history) == 2
|
||||
assert history[0].role == "USER"
|
||||
assert history[0].message == "Hello"
|
||||
assert history[1].role == "CHATBOT"
|
||||
assert history[1].message == "Hi there!"
|
||||
|
||||
def test_mixed_empty_and_nonempty_messages(self):
|
||||
"""Only empty messages should be filtered; non-empty ones kept."""
|
||||
config = OCIChatConfig()
|
||||
messages = [
|
||||
{"role": "system", "content": ""},
|
||||
{"role": "user", "content": "First question"},
|
||||
{"role": "assistant", "content": ""},
|
||||
{"role": "user", "content": "Second question"},
|
||||
{"role": "assistant", "content": "A real answer"},
|
||||
{"role": "user", "content": "Last message"},
|
||||
]
|
||||
|
||||
# messages[:-1] excludes "Last message"
|
||||
# Empty system and empty assistant are filtered
|
||||
# Remaining: "First question" (user), "Second question" (user), "A real answer" (chatbot)
|
||||
history = config.adapt_messages_to_cohere_standard(messages)
|
||||
|
||||
assert len(history) == 3
|
||||
assert history[0].role == "USER"
|
||||
assert history[0].message == "First question"
|
||||
assert history[1].role == "USER"
|
||||
assert history[1].message == "Second question"
|
||||
assert history[2].role == "CHATBOT"
|
||||
assert history[2].message == "A real answer"
|
||||
Loading…
Add table
Reference in a new issue