From 76efb0153ae4ed9cdc4ed4c506a9186a8b04d953 Mon Sep 17 00:00:00 2001 From: brandtcormorant Date: Fri, 13 Mar 2026 17:48:27 -0700 Subject: [PATCH] fix(cache_control) treat empty text like None to avoid anthropic api cache_control error --- agent/prompt_caching.py | 6 ++++-- tests/agent/test_prompt_caching.py | 8 ++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/agent/prompt_caching.py b/agent/prompt_caching.py index aa80b2ddf..661a28b6a 100644 --- a/agent/prompt_caching.py +++ b/agent/prompt_caching.py @@ -21,12 +21,14 @@ def _apply_cache_marker(msg: dict, cache_marker: dict) -> None: msg["cache_control"] = cache_marker return - if content is None: + if content is None or content == "": msg["cache_control"] = cache_marker return if isinstance(content, str): - msg["content"] = [{"type": "text", "text": content, "cache_control": cache_marker}] + msg["content"] = [ + {"type": "text", "text": content, "cache_control": cache_marker} + ] return if isinstance(content, list) and content: diff --git a/tests/agent/test_prompt_caching.py b/tests/agent/test_prompt_caching.py index 7f7f562e4..fd87a80e3 100644 --- a/tests/agent/test_prompt_caching.py +++ b/tests/agent/test_prompt_caching.py @@ -23,6 +23,14 @@ class TestApplyCacheMarker: _apply_cache_marker(msg, MARKER) assert msg["cache_control"] == MARKER + def test_empty_string_content_gets_top_level_marker(self): + """Empty text blocks cannot have cache_control (Anthropic rejects them).""" + msg = {"role": "assistant", "content": ""} + _apply_cache_marker(msg, MARKER) + assert msg["cache_control"] == MARKER + # Must NOT wrap into [{"type": "text", "text": "", "cache_control": ...}] + assert msg["content"] == "" + def test_string_content_wrapped_in_list(self): msg = {"role": "user", "content": "Hello"} _apply_cache_marker(msg, MARKER)