fix(vertex_ai): regex in supports_response_json_schema misses gemini-3-flash

The regex `r"gemini-([2-9]|[1-9]\d+)\."` requires a literal dot after
the major version number. This correctly matches models like
`gemini-2.0-flash`, `gemini-2.5-pro`, and `gemini-3.1-flash-lite`, but
fails to match `gemini-3-flash-preview` because Google named it with a
hyphen (`gemini-3-`) instead of a dot (`gemini-3.`).

When the regex fails, `supports_response_json_schema()` returns False
and the request falls through to `_build_vertex_schema()` which strips
`additionalProperties`. This causes `dict[str, float]` fields in
structured output schemas to return empty objects `{}` instead of
actual key-value pairs.

Fix: Change `\.` to `[.-]` to accept both dot and hyphen after the
major version number.

Fixes #14251
This commit is contained in:
Ray Walker 2026-04-08 07:27:49 +10:00
parent bf8b615b64
commit eb92eb10ba
2 changed files with 35 additions and 1 deletions

View file

@ -176,7 +176,7 @@ def supports_response_json_schema(model: str) -> bool:
# Gemini 2.0+ and 2.5+ models support responseJsonSchema
# Pattern matches: gemini-2.0-*, gemini-2.5-*, gemini-3-*, etc.
gemini_2_plus_pattern = re.compile(r"gemini-([2-9]|[1-9]\d+)\.")
gemini_2_plus_pattern = re.compile(r"gemini-([2-9]|[1-9]\d+)[.-]")
return bool(gemini_2_plus_pattern.search(model_lower))

View file

@ -16,6 +16,7 @@ from litellm.llms.vertex_ai.common_utils import (
get_vertex_location_from_url,
get_vertex_project_id_from_url,
set_schema_property_ordering,
supports_response_json_schema,
)
@ -1382,3 +1383,36 @@ def test_add_object_type_does_not_add_type_when_anyof_present():
# Verify type was not added (anyOf handles the type)
assert "type" not in input_schema, "type should not be added when anyOf is present"
class TestSupportsResponseJsonSchema:
"""Test supports_response_json_schema correctly identifies Gemini 2.0+ models."""
@pytest.mark.parametrize(
"model",
[
"gemini-2.0-flash",
"gemini-2.5-flash",
"gemini-2.5-pro",
"gemini-3.1-flash-lite-preview",
"vertex_ai/gemini-3.1-flash-lite-preview",
"gemini-3-flash-preview", # no dot after major version
"vertex_ai/gemini-3-flash-preview",
"gemini-4-ultra", # future model
],
)
def test_gemini_2_plus_returns_true(self, model):
assert supports_response_json_schema(model) is True
@pytest.mark.parametrize(
"model",
[
"gemini-1.5-flash",
"gemini-1.5-pro",
"vertex_ai/gemini-1.5-flash-001",
"chat-bison",
"text-bison",
],
)
def test_older_models_return_false(self, model):
assert supports_response_json_schema(model) is False