This commit is contained in:
Bharadwaj Pendyala 2026-08-26 21:06:13 -04:00 committed by GitHub
commit 9a9a65411f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 28 additions and 9 deletions

View file

@ -1215,12 +1215,12 @@ def _transform_request_body(
generation_config["mediaResolution"] = media_resolution_value["level"]
data: Final = RequestBody(contents=content)
# Vertex rejects system_instruction/tools/toolConfig alongside cachedContent.
# Vertex rejects systemInstruction/tools/toolConfig alongside cachedContent.
# Treat dropping these fields as a request mutation guarded by modify_params.
can_send_cache_incompatible_fields: Final = cached_content is None or litellm.modify_params is False
if can_send_cache_incompatible_fields:
if system_instructions is not None:
data["system_instruction"] = system_instructions
data["systemInstruction"] = system_instructions
if tools is not None:
data["tools"] = tools
if tool_choice is not None:

View file

@ -338,7 +338,7 @@ class CachedContent(TypedDict, total=False):
class RequestBody(TypedDict, total=False):
contents: Required[list[ContentType]]
system_instruction: SystemInstructions
systemInstruction: SystemInstructions
tools: Tools
toolConfig: ToolConfig
safetySettings: list[SafetSettingsConfig]

View file

@ -2906,7 +2906,7 @@ def test_gemini_function_call_parameter_in_messages():
],
},
],
"system_instruction": {
"systemInstruction": {
"parts": [{"text": "Use search for most queries."}]
},
"tools": [

View file

@ -123,7 +123,7 @@ def test_cached_content_respects_modify_params_for_cache_incompatible_fields():
cached_content=cache_name,
)
assert result.get("cachedContent") == cache_name
assert "system_instruction" in result
assert "systemInstruction" in result
assert "tools" in result
assert "toolConfig" in result
assert "contents" in result
@ -139,7 +139,7 @@ def test_cached_content_respects_modify_params_for_cache_incompatible_fields():
cached_content=cache_name,
)
assert result_modify_true.get("cachedContent") == cache_name
assert "system_instruction" not in result_modify_true
assert "systemInstruction" not in result_modify_true
assert "tools" not in result_modify_true
assert "toolConfig" not in result_modify_true
assert "contents" in result_modify_true
@ -153,13 +153,32 @@ def test_cached_content_respects_modify_params_for_cache_incompatible_fields():
litellm_params={},
cached_content=None,
)
assert "system_instruction" in result_no_cache
assert "systemInstruction" in result_no_cache
assert "tools" in result_no_cache
assert "toolConfig" in result_no_cache
finally:
litellm.modify_params = original_modify_params
@pytest.mark.parametrize("custom_llm_provider", ["gemini", "vertex_ai"])
def test_system_instruction_uses_canonical_rest_key(custom_llm_provider):
"""Regression for #37028: strict generateContent endpoints reject the snake_case alias."""
result = _transform_request_body(
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Reply with exactly: ok"},
],
model="gemini-2.5-pro",
optional_params={},
custom_llm_provider=custom_llm_provider,
litellm_params={},
cached_content=None,
)
assert "system_instruction" not in result
assert result["systemInstruction"]["parts"][0]["text"] == "You are a concise assistant."
# Tests for issue #14556: Labels field provider-aware filtering
def test_google_genai_excludes_labels():
"""Test that Google GenAI/AI Studio endpoints exclude labels when custom_llm_provider='gemini'"""

View file

@ -1579,5 +1579,5 @@ def test_system_prompt_only_adds_blank_user_message():
#########################################################
# system message was passed in
#########################################################
assert len(data["system_instruction"]) == 1
assert data["system_instruction"]["parts"][0]["text"] == SYSTEM_INSTRUCTION
assert len(data["systemInstruction"]) == 1
assert data["systemInstruction"]["parts"][0]["text"] == SYSTEM_INSTRUCTION