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>
This commit is contained in:
kerry 2026-10-06 00:24:48 +00:00
parent 9de92d79af
commit b9a794291a
5 changed files with 24 additions and 22 deletions

View file

@ -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 {

View file

@ -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"))

View file

@ -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

View file

@ -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``)

View file

@ -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"))