fix(caching): read list-form function_call_output text in semantic cache prompts
Some checks failed
LiteLLM Rust / rust-lint (push) Has been cancelled
LiteLLM Rust / rust-test (push) Has been cancelled
LiteLLM Rust / rust-wheel (push) Has been cancelled

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
kerry 2026-10-07 00:44:45 +00:00
parent 0dc9c914bc
commit f6e9be9e81
4 changed files with 32 additions and 0 deletions

View file

@ -184,6 +184,10 @@ fn collect_input_text(value: &Value, parts: &mut Vec<String>) {
collect_input_text(content, parts);
return;
}
if let Some(output) = map.get("output").filter(|output| output.is_array()) {
collect_input_text(output, parts);
return;
}
for key in ["text", "output", "input_text", "output_text"] {
if let Some(Value::String(text)) = map.get(key)
&& push_trimmed(text, parts)

View file

@ -191,6 +191,15 @@ fn prompt_from_messages_reads_messages_only(
])),
Some("model dump prompt\ndict prompt\ninline prompt"),
)]
#[case::function_call_output_blocks(
None,
Some(json!([
{"role": "user", "content": "update the config"},
{"type": "function_call", "call_id": "c1", "name": "write_file", "arguments": "{\"path\": \"a\"}"},
{"type": "function_call_output", "call_id": "c1", "output": [{"type": "input_text", "text": "wrote a"}]},
])),
Some("update the config\nwrote a"),
)]
#[case::object_content(
None,
Some(json!({"content": [{"text": "object content prompt"}]})),

View file

@ -296,6 +296,11 @@ class RedisSemanticCache(BaseCache):
cls._collect_responses_input_text(content, prompt_parts)
return
output = value.get("output")
if isinstance(output, list):
cls._collect_responses_input_text(output, prompt_parts)
return
for text_key in ("text", "output", "input_text", "output_text"):
text_value = value.get(text_key)
if isinstance(text_value, str):

View file

@ -568,6 +568,20 @@ def test_redis_semantic_cache_set_cache_flattens_structured_responses_input():
)
def test_redis_semantic_cache_prompt_extraction_reads_function_call_output_blocks():
from litellm.caching.redis_semantic_cache import RedisSemanticCache
prompt = RedisSemanticCache._get_prompt_from_kwargs(
input=[
{"role": "user", "content": "update the config"},
{"type": "function_call", "call_id": "c1", "name": "write_file", "arguments": '{"path": "a"}'},
{"type": "function_call_output", "call_id": "c1", "output": [{"type": "input_text", "text": "wrote a"}]},
]
)
assert prompt == "update the config\nwrote a"
def test_redis_semantic_cache_prompt_extraction_prefers_messages():
from litellm.caching.redis_semantic_cache import RedisSemanticCache