diff --git a/litellm/llms/base_llm/chat/transformation.py b/litellm/llms/base_llm/chat/transformation.py index 1867abde310..b592c23846d 100644 --- a/litellm/llms/base_llm/chat/transformation.py +++ b/litellm/llms/base_llm/chat/transformation.py @@ -101,6 +101,7 @@ class BaseConfig(ABC): ), ) and v is not None + and not callable(v) # Filter out any callable objects including mocks } def get_json_schema_from_pydantic_object( diff --git a/litellm/utils.py b/litellm/utils.py index df0b2317123..65d793fa12f 100644 --- a/litellm/utils.py +++ b/litellm/utils.py @@ -2990,6 +2990,8 @@ def get_optional_params_embeddings( # noqa: PLR0915 drop_params = passed_params.pop("drop_params", None) additional_drop_params = passed_params.pop("additional_drop_params", None) + # Remove function objects from passed_params to avoid JSON serialization errors + passed_params.pop("get_supported_openai_params", None) def _check_valid_arg(supported_params: Optional[list]): if supported_params is None: @@ -6913,6 +6915,8 @@ def get_valid_models( ################################ # init litellm_params ################################# + from litellm.types.router import LiteLLM_Params + if litellm_params is None: litellm_params = LiteLLM_Params(model="") if api_key is not None: diff --git a/tests/test_litellm/interactions/base_interactions_test.py b/tests/test_litellm/interactions/base_interactions_test.py index b7748a45f32..fee5758ab5e 100644 --- a/tests/test_litellm/interactions/base_interactions_test.py +++ b/tests/test_litellm/interactions/base_interactions_test.py @@ -52,7 +52,13 @@ class BaseInteractionsTest(ABC): if response.usage: # Usage is a dict in InteractionsAPIResponse if isinstance(response.usage, dict): - assert response.usage.get("input_tokens") is not None or response.usage.get("output_tokens") is not None + # Check for both possible key formats: input_tokens/output_tokens or total_input_tokens/total_output_tokens + assert ( + response.usage.get("input_tokens") is not None + or response.usage.get("output_tokens") is not None + or response.usage.get("total_input_tokens") is not None + or response.usage.get("total_output_tokens") is not None + ) else: # If it's an object, check attributes assert hasattr(response.usage, "input_tokens") or hasattr(response.usage, "output_tokens") diff --git a/tests/test_litellm/llms/ollama/test_ollama_chat_transformation.py b/tests/test_litellm/llms/ollama/test_ollama_chat_transformation.py index 24defc6a0ab..fc4a3e43573 100644 --- a/tests/test_litellm/llms/ollama/test_ollama_chat_transformation.py +++ b/tests/test_litellm/llms/ollama/test_ollama_chat_transformation.py @@ -216,10 +216,8 @@ class TestOllamaChatConfigResponseFormat: # Verify image was extracted to images list assert "images" in result["messages"][0] assert len(result["messages"][0]["images"]) == 1 - assert ( - result["messages"][0]["images"][0] - == "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQ..." - ) + # Ollama expects pure base64 data without the data URL prefix + assert result["messages"][0]["images"][0] == "/9j/4AAQSkZJRgABAQAAAQ..." def test_transform_request_multiple_images_extraction(self): """Test extraction of multiple images from a single message""" @@ -263,12 +261,9 @@ class TestOllamaChatConfigResponseFormat: # Verify both images were extracted assert "images" in result["messages"][0] assert len(result["messages"][0]["images"]) == 2 - assert ( - result["messages"][0]["images"][0] == "data:image/jpeg;base64,image1data..." - ) - assert ( - result["messages"][0]["images"][1] == "data:image/png;base64,image2data..." - ) + # Ollama expects pure base64 data without the data URL prefix + assert result["messages"][0]["images"][0] == "image1data..." + assert result["messages"][0]["images"][1] == "image2data..." def test_transform_request_image_url_as_string(self): """Test handling of image_url as direct string (edge case)"""