diff --git a/litellm/llms/hosted_vllm/embedding/transformation.py b/litellm/llms/hosted_vllm/embedding/transformation.py index 9c3e8c6c7cc..4407e3b1b68 100644 --- a/litellm/llms/hosted_vllm/embedding/transformation.py +++ b/litellm/llms/hosted_vllm/embedding/transformation.py @@ -110,10 +110,13 @@ class HostedVLLMEmbeddingConfig(BaseEmbeddingConfig): if model.startswith("hosted_vllm/"): model = model.replace("hosted_vllm/", "", 1) + # Filter out None values to avoid sending invalid params (e.g. encoding_format=None) + # which vLLM rejects with: "unknown variant ``, expected float or base64" + filtered_params = {k: v for k, v in optional_params.items() if v is not None} return { "model": model, "input": input, - **optional_params, + **filtered_params, } def transform_embedding_response( diff --git a/tests/mcp_tests/test_mcp_server.py b/tests/mcp_tests/test_mcp_server.py index d3ec7863504..c5ad25d3014 100644 --- a/tests/mcp_tests/test_mcp_server.py +++ b/tests/mcp_tests/test_mcp_server.py @@ -395,6 +395,7 @@ async def test_mcp_http_transport_tool_not_found(): @pytest.mark.asyncio async def test_streamable_http_mcp_handler_mock(): """Test the streamable HTTP MCP handler functionality""" + from litellm.proxy._types import UserAPIKeyAuth # Mock the session manager and its methods mock_session_manager = AsyncMock() @@ -413,12 +414,29 @@ async def test_streamable_http_mcp_handler_mock(): mock_receive = AsyncMock() mock_send = AsyncMock() + mock_auth_result = ( + UserAPIKeyAuth(), + None, + None, + {}, + {}, + [], + ) + with patch( "litellm.proxy._experimental.mcp_server.server._SESSION_MANAGERS_INITIALIZED", True, ), patch( "litellm.proxy._experimental.mcp_server.server.session_manager", mock_session_manager, + ), patch( + "litellm.proxy._experimental.mcp_server.server.extract_mcp_auth_context", + new=AsyncMock(return_value=mock_auth_result), + ), patch( + "litellm.proxy._experimental.mcp_server.server.set_auth_context", + ), patch( + "litellm.proxy._experimental.mcp_server.server._handle_stale_mcp_session", + new=AsyncMock(return_value=False), ): from litellm.proxy._experimental.mcp_server.server import ( handle_streamable_http_mcp, diff --git a/tests/test_litellm/llms/openrouter/responses/test_openrouter_responses_transformation.py b/tests/test_litellm/llms/openrouter/responses/test_openrouter_responses_transformation.py index 544ec1ec719..0d12fdfba45 100644 --- a/tests/test_litellm/llms/openrouter/responses/test_openrouter_responses_transformation.py +++ b/tests/test_litellm/llms/openrouter/responses/test_openrouter_responses_transformation.py @@ -9,6 +9,8 @@ reasoning.encrypted_content for multi-turn stateless workflows. Related issue: https://github.com/BerriAI/litellm/issues/22189 """ +from unittest.mock import patch + import litellm from litellm.llms.openrouter.responses.transformation import ( OpenRouterResponsesAPIConfig, @@ -65,15 +67,21 @@ class TestOpenRouterResponsesAPIConfig: config = OpenRouterResponsesAPIConfig() from litellm.types.router import GenericLiteLLMParams - try: - config.validate_environment( - headers={}, - model="openai/o4-mini", - litellm_params=GenericLiteLLMParams(), - ) - assert False, "Should have raised ValueError" - except ValueError as e: - assert "OpenRouter API key is required" in str(e) + # Mock get_secret_str and litellm.api_key to ensure no API key is found, + # even in CI environments where OPENROUTER_API_KEY may be set. + with patch( + "litellm.llms.openrouter.responses.transformation.get_secret_str", + return_value=None, + ), patch.object(litellm, "api_key", None): + try: + config.validate_environment( + headers={}, + model="openai/o4-mini", + litellm_params=GenericLiteLLMParams(), + ) + assert False, "Should have raised ValueError" + except ValueError as e: + assert "OpenRouter API key is required" in str(e) class TestOpenRouterResponsesAPIRegistration: