fix(vertex_ai): send systemInstruction on the cachedContents create body

The cachedContents create call was the last place in the provider still
sending the snake_case alias. CachedContent, the read type for the same
resource, already declares systemInstruction, so the request and response
types disagreed on one field.
This commit is contained in:
Bharadwaj Pendyala 2026-09-06 22:31:47 -05:00
parent 6835f48056
commit f2bba9c1ba
4 changed files with 27 additions and 4 deletions

View file

@ -158,7 +158,7 @@ def cached_messages_end_on_supported_turn(cached_messages: Sequence[AllMessageVa
The cachedContents API rejects contents ending on a model turn, which is how it
classifies both assistant messages and tool results, with HTTP 400
"Requests ending with a model turn are not supported". System messages are
extracted into system_instruction before contents are built, so the terminal
extracted into systemInstruction before contents are built, so the terminal
turn is the last non-system message.
"""
non_system_messages: Final = tuple(message for message in cached_messages if message.get("role") != "system")
@ -206,6 +206,6 @@ def transform_openai_messages_to_gemini_context_caching(
data["ttl"] = ttl
if transformed_system_messages is not None:
data["system_instruction"] = transformed_system_messages
data["systemInstruction"] = transformed_system_messages
return data

View file

@ -350,7 +350,7 @@ class RequestBody(TypedDict, total=False):
class CachedContentRequestBody(TypedDict, total=False):
contents: Required[list[ContentType]]
system_instruction: SystemInstructions
systemInstruction: SystemInstructions
tools: Tools
toolConfig: ToolConfig
model: Required[str] # Format: models/{model}

View file

@ -334,7 +334,7 @@ class TestTransformationWithTTL:
assert "ttl" in result
assert result["ttl"] == "7200s"
assert "system_instruction" in result
assert "systemInstruction" in result
if custom_llm_provider == "gemini":
assert result["model"] == "models/gemini-2.5-pro"

View file

@ -1599,6 +1599,29 @@ def test_cached_messages_end_on_supported_turn():
assert cached_messages_end_on_supported_turn([]) is False
@pytest.mark.parametrize("custom_llm_provider", ["gemini", "vertex_ai", "vertex_ai_beta"])
def test_cached_content_system_instruction_uses_canonical_rest_key(custom_llm_provider):
"""cachedContents.create takes systemInstruction; this was the last snake_case sender in the provider."""
from litellm.llms.vertex_ai.context_caching.transformation import (
transform_openai_messages_to_gemini_context_caching,
)
result = transform_openai_messages_to_gemini_context_caching(
model="gemini-2.5-pro",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Reply with exactly: ok"},
],
custom_llm_provider=custom_llm_provider,
cache_key="test-cache-key",
vertex_project="test_project",
vertex_location="test_location",
)
assert "system_instruction" not in result
assert result["systemInstruction"]["parts"][0]["text"] == "You are a concise assistant."
class TestCheckCachePagination:
"""Test pagination logic in check_cache and async_check_cache methods."""