From b9a794291a93cd6f4c14a05776e13aaeae7c2c3e Mon Sep 17 00:00:00 2001 From: kerry Date: Tue, 6 Oct 2026 00:24:48 +0000 Subject: [PATCH] refactor(caching): rename get_str_from_messages_with_tools to get_semantic_cache_prompt_from_messages Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm-rust/crates/cache/src/semantic.rs | 4 +-- litellm/caching/qdrant_semantic_cache.py | 10 +++---- litellm/caching/redis_semantic_cache.py | 4 +-- .../prompt_templates/common_utils.py | 2 +- ...ore_utils_prompt_templates_common_utils.py | 26 ++++++++++--------- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/litellm-rust/crates/cache/src/semantic.rs b/litellm-rust/crates/cache/src/semantic.rs index 253efb47759..5af6a54d894 100644 --- a/litellm-rust/crates/cache/src/semantic.rs +++ b/litellm-rust/crates/cache/src/semantic.rs @@ -1,6 +1,6 @@ //! The embedding and prompt contract every semantic backend shares. //! -//! Python's semantic caches all read their prompt through `get_str_from_messages_with_tools`, and +//! Python's semantic caches all read their prompt through `get_semantic_cache_prompt_from_messages`, and //! `RedisSemanticCache._get_prompt_from_kwargs` (inherited by Valkey) adds Responses API //! `input`. Qdrant reads messages only. Each backend picks one of the two extractors here. @@ -83,7 +83,7 @@ impl Embedder for PreparedEmbedding { } } -/// `get_str_from_messages_with_tools`: every message's content text, tool calls and tool results, +/// `get_semantic_cache_prompt_from_messages`: every message's content text, tool calls and tool results, /// then its OpenAI `tool_calls`, then its search results. Each tool result is encoded with the /// position of the call it answers. pub fn str_from_messages(messages: &[Value]) -> String { diff --git a/litellm/caching/qdrant_semantic_cache.py b/litellm/caching/qdrant_semantic_cache.py index 8fe03131760..1258c9f4917 100644 --- a/litellm/caching/qdrant_semantic_cache.py +++ b/litellm/caching/qdrant_semantic_cache.py @@ -24,7 +24,7 @@ from litellm.constants import ( ) from litellm.litellm_core_utils.asyncify import asyncify from litellm.litellm_core_utils.prompt_templates.common_utils import ( - get_str_from_messages_with_tools, + get_semantic_cache_prompt_from_messages, ) from litellm.types.utils import EmbeddingResponse @@ -286,7 +286,7 @@ class QdrantSemanticCache(BaseCache): # get the prompt messages: Final = kwargs["messages"] - prompt: Final = get_str_from_messages_with_tools(messages) + prompt: Final = get_semantic_cache_prompt_from_messages(messages) # create an embedding for prompt embedding_response: Final = cast( @@ -325,7 +325,7 @@ class QdrantSemanticCache(BaseCache): # get the messages messages: Final = kwargs["messages"] - prompt: Final = get_str_from_messages_with_tools(messages) + prompt: Final = get_semantic_cache_prompt_from_messages(messages) # convert to embedding embedding_response: Final = cast( @@ -400,7 +400,7 @@ class QdrantSemanticCache(BaseCache): # get the prompt messages: Final = kwargs["messages"] - prompt: Final = get_str_from_messages_with_tools(messages) + prompt: Final = get_semantic_cache_prompt_from_messages(messages) embedding_response: Final = await self._get_async_embedding(prompt, metadata=kwargs.get("metadata")) # get the embedding @@ -435,7 +435,7 @@ class QdrantSemanticCache(BaseCache): # get the messages messages: Final = kwargs["messages"] - prompt: Final = get_str_from_messages_with_tools(messages) + prompt: Final = get_semantic_cache_prompt_from_messages(messages) embedding_response: Final = await self._get_async_embedding(prompt, metadata=kwargs.get("metadata")) diff --git a/litellm/caching/redis_semantic_cache.py b/litellm/caching/redis_semantic_cache.py index 827fa91398f..dfbdcce8ae8 100644 --- a/litellm/caching/redis_semantic_cache.py +++ b/litellm/caching/redis_semantic_cache.py @@ -21,7 +21,7 @@ from litellm._logging import print_verbose, verbose_logger from litellm.constants import SEMANTIC_CACHE_EMBEDDING_TIMEOUT_SECONDS from litellm.litellm_core_utils.asyncify import asyncify from litellm.litellm_core_utils.prompt_templates.common_utils import ( - get_str_from_messages_with_tools, + get_semantic_cache_prompt_from_messages, tool_call_ordinals, tool_call_str, tool_result_str, @@ -266,7 +266,7 @@ class RedisSemanticCache(BaseCache): """ messages: Final = kwargs.get("messages") if messages: - return get_str_from_messages_with_tools(messages) + return get_semantic_cache_prompt_from_messages(messages) if "input" not in kwargs: return None diff --git a/litellm/litellm_core_utils/prompt_templates/common_utils.py b/litellm/litellm_core_utils/prompt_templates/common_utils.py index a7769e6b1ac..f191286144f 100644 --- a/litellm/litellm_core_utils/prompt_templates/common_utils.py +++ b/litellm/litellm_core_utils/prompt_templates/common_utils.py @@ -195,7 +195,7 @@ def get_str_from_messages(messages: list[AllMessageValues]) -> str: return text -def get_str_from_messages_with_tools(messages: object) -> str: +def get_semantic_cache_prompt_from_messages(messages: object) -> str: """ ``get_str_from_messages`` that also keeps each conversation's tool calls and tool results, so agent turns that differ only in their tool exchange (Anthropic ``tool_use`` / ``tool_result``, OpenAI ``tool_calls``) diff --git a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py index 826bd83bc54..61d7cdbd96c 100644 --- a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py +++ b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py @@ -16,8 +16,8 @@ from litellm.litellm_core_utils.prompt_templates.common_utils import ( encrypted_reasoning_signature, get_file_ids_from_messages, get_format_from_file_id, + get_semantic_cache_prompt_from_messages, get_str_from_messages, - get_str_from_messages_with_tools, handle_any_messages_to_chat_completion_str_messages_conversion, hoist_images_from_tool_messages, is_encrypted_reasoning_block, @@ -2308,8 +2308,8 @@ _TASK: Final = {"role": "user", "content": "fix the failing test"} ), ], ) -def test_get_str_from_messages_with_tools_keeps_tool_exchange(messages: list[object], expected: str) -> None: - assert get_str_from_messages_with_tools(messages) == expected +def test_get_semantic_cache_prompt_from_messages_keeps_tool_exchange(messages: list[object], expected: str) -> None: + assert get_semantic_cache_prompt_from_messages(messages) == expected @pytest.mark.parametrize( @@ -2332,8 +2332,10 @@ def test_get_str_from_messages_with_tools_keeps_tool_exchange(messages: list[obj pytest.param([{"role": "assistant", "content": None}, {"role": "user"}], id="missing-content"), ], ) -def test_get_str_from_messages_with_tools_matches_get_str_from_messages_without_tools(messages: list[object]) -> None: - assert get_str_from_messages_with_tools(messages) == get_str_from_messages(messages) # pyright: ignore[reportArgumentType] # untyped fixtures +def test_get_semantic_cache_prompt_from_messages_matches_get_str_from_messages_without_tools( + messages: list[object], +) -> None: + assert get_semantic_cache_prompt_from_messages(messages) == get_str_from_messages(messages) # pyright: ignore[reportArgumentType] # untyped fixtures def _parallel_reads(result_for_a: str, result_for_b: str, *, call_id_prefix: str = "c") -> list[object]: @@ -2356,13 +2358,13 @@ def _results_in_swapped_order(result_for_a: str, result_for_b: str) -> list[obje return [call, answer_b, answer_a] -def test_get_str_from_messages_with_tools_tells_apart_parallel_results_answering_different_calls() -> None: - assert get_str_from_messages_with_tools(_parallel_reads("empty", "secret")) != get_str_from_messages_with_tools( - _results_in_swapped_order("secret", "empty") - ) +def test_get_semantic_cache_prompt_from_messages_tells_apart_parallel_results_answering_different_calls() -> None: + assert get_semantic_cache_prompt_from_messages( + _parallel_reads("empty", "secret") + ) != get_semantic_cache_prompt_from_messages(_results_in_swapped_order("secret", "empty")) -def test_get_str_from_messages_with_tools_ignores_call_ids_that_differ_between_sessions() -> None: - assert get_str_from_messages_with_tools( +def test_get_semantic_cache_prompt_from_messages_ignores_call_ids_that_differ_between_sessions() -> None: + assert get_semantic_cache_prompt_from_messages( _parallel_reads("A", "B", call_id_prefix="toolu_") - ) == get_str_from_messages_with_tools(_parallel_reads("A", "B")) + ) == get_semantic_cache_prompt_from_messages(_parallel_reads("A", "B"))