diff --git a/litellm/llms/dashscope/chat/transformation.py b/litellm/llms/dashscope/chat/transformation.py index cc5cf99182..d022f9da21 100644 --- a/litellm/llms/dashscope/chat/transformation.py +++ b/litellm/llms/dashscope/chat/transformation.py @@ -4,6 +4,8 @@ Translates from OpenAI's `/v1/chat/completions` to DashScope's `/v1/chat/complet from typing import Any, Coroutine, List, Literal, Optional, Tuple, Union, overload +from litellm.types.llms.openai import ChatCompletionToolParam + from litellm.secret_managers.main import get_secret_str from litellm.types.llms.openai import AllMessageValues @@ -11,6 +13,18 @@ from ...openai.chat.gpt_transformation import OpenAIGPTConfig class DashScopeChatConfig(OpenAIGPTConfig): + def remove_cache_control_flag_from_messages_and_tools( + self, + model: str, + messages: List[AllMessageValues], + tools: Optional[List[ChatCompletionToolParam]] = None, + ) -> Tuple[List[AllMessageValues], Optional[List[ChatCompletionToolParam]]]: + """ + Override to preserve cache_control for DashScope. + DashScope supports cache_control - don't strip it. + """ + return messages, tools + @overload def _transform_messages( self, messages: List[AllMessageValues], model: str, is_async: Literal[True] diff --git a/tests/test_litellm/llms/dashscope/test_dashscope_chat_transformation.py b/tests/test_litellm/llms/dashscope/test_dashscope_chat_transformation.py index b5f656c71f..e99c3c3b31 100644 --- a/tests/test_litellm/llms/dashscope/test_dashscope_chat_transformation.py +++ b/tests/test_litellm/llms/dashscope/test_dashscope_chat_transformation.py @@ -144,3 +144,47 @@ class TestDashScopeConfig: assert transformed_messages[0]["content"][0]["text"] == "Hello" assert transformed_messages[0]["content"][1]["type"] == "text" assert transformed_messages[0]["content"][1]["text"] == "World" + + def test_dashscope_preserves_cache_control_in_messages(self): + """DashScope should NOT strip cache_control from messages.""" + config = DashScopeChatConfig() + + messages = [ + { + "role": "system", + "content": "You are a helpful assistant.", + "cache_control": {"type": "ephemeral"}, + }, + { + "role": "user", + "content": "Hello, world!", + }, + ] + + transformed_messages, _ = config.remove_cache_control_flag_from_messages_and_tools( + model="dashscope/qwen-turbo", messages=messages + ) + + assert transformed_messages[0].get("cache_control") == {"type": "ephemeral"} + + def test_dashscope_preserves_cache_control_in_tools(self): + """DashScope should NOT strip cache_control from tools.""" + config = DashScopeChatConfig() + + tools = [ + { + "type": "function", + "function": { + "name": "get_weather", + "description": "Get weather information", + "parameters": {"type": "object", "properties": {}}, + }, + "cache_control": {"type": "ephemeral"}, + } + ] + + _, transformed_tools = config.remove_cache_control_flag_from_messages_and_tools( + model="dashscope/qwen-turbo", messages=[], tools=tools + ) + + assert transformed_tools[0].get("cache_control") == {"type": "ephemeral"}