diff --git a/litellm/main.py b/litellm/main.py index 38591441e01..64fa5e115d1 100644 --- a/litellm/main.py +++ b/litellm/main.py @@ -2678,7 +2678,9 @@ def _complete_custom_openai( if extra_headers is not None and not use_base_llm_http_handler: optional_params["extra_headers"] = extra_headers - if litellm.enable_preview_features and metadata is not None: # [PREVIEW] allow metadata to be passed to OPENAI + # OpenAI accepts request metadata independently of preview features. Keep this + # limited to the OpenAI provider; compatible providers may reject the field. + if custom_llm_provider == "openai" and metadata is not None: openai_metadata: Final = get_requester_metadata(metadata) if openai_metadata is not None: optional_params["metadata"] = openai_metadata diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 7c292ea8f08..e919e0924dc 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -7633,34 +7633,30 @@ def test_completion_novita_ai_dynamic_params(api_key): "enable_preview_features", [True, False], ) -def test_completion_openai_metadata(monkeypatch, enable_preview_features): +def test_completion_openai_metadata( + monkeypatch, enable_preview_features, respx_mock: respx.MockRouter +): from openai import OpenAI client = OpenAI() - - litellm.set_verbose = True - monkeypatch.setattr(litellm, "enable_preview_features", enable_preview_features) - with patch.object( - client, "post", return_value=MagicMock() - ) as mock_completion: - try: - resp = litellm.completion( - model="openai/gpt-3.5-turbo", - messages=[{"role": "user", "content": "Hello world"}], - metadata={"my-test-key": "my-test-value"}, - client=client, - ) - except Exception as e: - print(f"Error: {e}") + respx_mock.post("https://api.openai.com/v1/chat/completions").mock( + return_value=_mocked_openai_chat_response("gpt-3.5-turbo") + ) - mock_completion.assert_called_once() - if enable_preview_features: - assert mock_completion.call_args.kwargs["body"]["metadata"] == { - "my-test-key": "my-test-value" - } - else: - assert "metadata" not in mock_completion.call_args.kwargs["body"] + litellm.completion( + model="openai/gpt-3.5-turbo", + messages=[{"role": "user", "content": "Hello world"}], + metadata={ + "session_id": "abc-123", + "hidden_params": {"api_key": "should-not-leak"}, + "non_string": 123, + }, + client=client, + ) + + request_body = json.loads(respx_mock.calls[0].request.content) + assert request_body["metadata"] == {"session_id": "abc-123"} AZURE_TTS_BASE: Final = "https://tts.example.azure.com"