diff --git a/litellm/llms/azure/chat/gpt_transformation.py b/litellm/llms/azure/chat/gpt_transformation.py index 0ae6fad730..18dad503a5 100644 --- a/litellm/llms/azure/chat/gpt_transformation.py +++ b/litellm/llms/azure/chat/gpt_transformation.py @@ -105,6 +105,7 @@ class AzureOpenAIConfig(BaseConfig): "modalities", "audio", "web_search_options", + "prompt_cache_key", ] def _is_response_format_supported_model(self, model: str) -> bool: diff --git a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py index 0523000984..dfab81123f 100644 --- a/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/chat/invoke_transformations/anthropic_claude3_transformation.py @@ -2,7 +2,6 @@ from typing import TYPE_CHECKING, Any, List, Optional import httpx -from litellm.anthropic_beta_headers_manager import filter_and_transform_beta_headers from litellm.llms.anthropic.chat.transformation import AnthropicConfig from litellm.llms.bedrock.chat.invoke_transformations.base_invoke_transformation import ( AmazonInvokeConfig, diff --git a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py index b105e5f079..2c041adba7 100644 --- a/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py +++ b/litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py @@ -12,9 +12,6 @@ from typing import ( import httpx -from litellm.anthropic_beta_headers_manager import ( - filter_and_transform_beta_headers, -) from litellm.llms.anthropic.common_utils import AnthropicModelInfo from litellm.llms.anthropic.experimental_pass_through.messages.transformation import ( AnthropicMessagesConfig, diff --git a/litellm/llms/openai/chat/gpt_transformation.py b/litellm/llms/openai/chat/gpt_transformation.py index 6cc09dafc2..1636890707 100644 --- a/litellm/llms/openai/chat/gpt_transformation.py +++ b/litellm/llms/openai/chat/gpt_transformation.py @@ -20,12 +20,12 @@ from typing import ( import httpx import litellm +from litellm.litellm_core_utils.core_helpers import map_finish_reason from litellm.litellm_core_utils.llm_response_utils.convert_dict_to_response import ( _extract_reasoning_content, _handle_invalid_parallel_tool_calls, _should_convert_tool_call_to_json_mode, ) -from litellm.litellm_core_utils.core_helpers import map_finish_reason from litellm.litellm_core_utils.prompt_templates.common_utils import get_tool_call_names from litellm.litellm_core_utils.prompt_templates.image_handling import ( async_convert_url_to_base64, @@ -161,6 +161,7 @@ class OpenAIGPTConfig(BaseLLMModelInfo, BaseConfig): "web_search_options", "service_tier", "safety_identifier", + "prompt_cache_key", ] # works across all models model_specific_params = [] diff --git a/tests/llm_translation/test_azure_openai.py b/tests/llm_translation/test_azure_openai.py index 3fd908f86d..1da380b57a 100644 --- a/tests/llm_translation/test_azure_openai.py +++ b/tests/llm_translation/test_azure_openai.py @@ -728,3 +728,18 @@ def test_azure_with_content_safety_error(): assert e.provider_specific_fields["innererror"]["code"] == "ResponsibleAIPolicyViolation" assert e.provider_specific_fields["innererror"]["content_filter_result"]["violence"]["filtered"] is True assert e.provider_specific_fields["innererror"]["content_filter_result"]["violence"]["severity"] == "high" + + +def test_azure_openai_with_prompt_cache_key(): + """ + E2E test for Azure OpenAI with prompt cache key param on /chat/completions API. + """ + litellm._turn_on_debug() + response = litellm.completion( + model="azure/gpt-4.1-mini", + api_key=os.getenv("AZURE_API_KEY"), + api_base=os.getenv("AZURE_API_BASE"), + api_version="2024-12-01-preview", + messages=[{"role": "user", "content": "What is the weather in San Francisco?"}], + prompt_cache_key="test_streaming_azure_openai", + ) \ No newline at end of file diff --git a/tests/test_litellm/llms/azure/chat/test_azure_chat_gpt_transformation.py b/tests/test_litellm/llms/azure/chat/test_azure_chat_gpt_transformation.py index 8df35a3751..7be4d6dfcf 100644 --- a/tests/test_litellm/llms/azure/chat/test_azure_chat_gpt_transformation.py +++ b/tests/test_litellm/llms/azure/chat/test_azure_chat_gpt_transformation.py @@ -30,6 +30,19 @@ class TestAzureOpenAIConfig: assert not config._is_response_format_supported_model("gpt-35-turbo") + def test_prompt_cache_key_supported(self): + """Test that 'prompt_cache_key' is in supported params for Azure OpenAI chat completion models. + + OpenAI's Chat Completions API supports prompt_cache_key for cache routing optimization. + """ + config = AzureOpenAIConfig() + supported_params = config.get_supported_openai_params("gpt-4.1-nano") + assert "prompt_cache_key" in supported_params + + supported_params = config.get_supported_openai_params("gpt-4.1") + assert "prompt_cache_key" in supported_params + + def test_map_openai_params_with_preview_api_version(): config = AzureOpenAIConfig() non_default_params = { diff --git a/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py b/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py index 5f08736379..c0695bf358 100644 --- a/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py +++ b/tests/test_litellm/llms/openai/chat/test_openai_gpt_transformation.py @@ -2,9 +2,10 @@ Tests for OpenAI GPT transformation (litellm/llms/openai/chat/gpt_transformation.py) """ -import pytest -import sys import os +import sys + +import pytest sys.path.insert(0, os.path.abspath("../../../../..")) @@ -73,6 +74,17 @@ class TestOpenAIGPTConfig: for param in base_expected_params: assert param in supported_params, f"Expected '{param}' in supported params" + def test_prompt_cache_key_supported(self): + """Test that 'prompt_cache_key' is in supported params for OpenAI chat completion models. + + OpenAI's Chat Completions API supports prompt_cache_key for cache routing optimization. + """ + supported_params = self.config.get_supported_openai_params("gpt-4.1-nano") + assert "prompt_cache_key" in supported_params + + supported_params = self.config.get_supported_openai_params("gpt-4.1") + assert "prompt_cache_key" in supported_params + class TestGetOptionalParamsIntegration: """Integration tests using litellm.get_optional_params()""" @@ -123,3 +135,14 @@ class TestGetOptionalParamsIntegration: # Both should include user assert regular_params.get("user") == "my-end-user" assert responses_params.get("user") == "my-end-user" + + def test_prompt_cache_key_in_optional_params(self): + """Test that 'prompt_cache_key' flows through get_optional_params for OpenAI models.""" + from litellm.utils import get_optional_params + + optional_params = get_optional_params( + model="gpt-4.1-nano", + custom_llm_provider="openai", + prompt_cache_key="test-cache-key-123", + ) + assert optional_params.get("prompt_cache_key") == "test-cache-key-123"