From ebe9ad0bc77d996d7be8f5adf0fdc51be7434ff7 Mon Sep 17 00:00:00 2001 From: prajwal-3-14159 <83531837+prajwal-3-14159@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:06:49 +0900 Subject: [PATCH] fix(anthropic): correctly inject cache_control into tool_result content block --- .../anthropic_cache_control_hook.py | 7 ++++++- .../test_anthropic_cache_control_hook.py | 20 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/litellm/integrations/anthropic_cache_control_hook.py b/litellm/integrations/anthropic_cache_control_hook.py index 545b0f40018..12822b03443 100644 --- a/litellm/integrations/anthropic_cache_control_hook.py +++ b/litellm/integrations/anthropic_cache_control_hook.py @@ -374,7 +374,12 @@ class AnthropicCacheControlHook(CustomPromptManagement): # 1. if string, insert cache control in the message if isinstance(message_content, str): - message["cache_control"] = control + if message.get("role") == "tool": + message["content"] = [ # pyright: ignore[reportGeneralTypeIssues] # list conversion + {"type": "text", "text": message_content, "cache_control": control} + ] + else: + message["cache_control"] = control # pyright: ignore[reportGeneralTypeIssues] # cache_control field # 2. list of objects - only apply to last item per Anthropic spec elif isinstance(message_content, list): if len(message_content) > 0 and isinstance(message_content[-1], dict): diff --git a/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py b/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py index 3a736e2a889..a08c2a8f451 100644 --- a/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py +++ b/tests/test_litellm/integrations/test_anthropic_cache_control_hook.py @@ -2909,3 +2909,23 @@ class TestRecordGatewayInjection: custom_llm_provider="anthropic", ) assert self.KEY not in kwargs["litellm_metadata"] + def test_tool_result_string_content_wrapped_in_list(self): + from litellm.integrations.anthropic_cache_control_hook import AnthropicCacheControlHook + from litellm.types.llms.openai import ChatCompletionCachedContent + + message = { + "role": "tool", + "tool_call_id": "call_1", + "content": "Sunny" + } + + control = ChatCompletionCachedContent(type="ephemeral") + + modified_message = AnthropicCacheControlHook._safe_insert_cache_control_in_message(message, control, False) + + # Should be converted to a list + assert isinstance(modified_message["content"], list) + assert len(modified_message["content"]) == 1 + assert modified_message["content"][0]["type"] == "text" + assert modified_message["content"][0]["text"] == "Sunny" + assert modified_message["content"][0]["cache_control"] == control