fix(vertex_ai): let an override pick only channels the model has

An override asking for responseJsonSchema on a model that is not known to accept it
now logs a warning and keeps the natively converted responseSchema, so no setting can
send a field the provider will reject.
This commit is contained in:
ArthurAAM 2026-08-25 18:15:05 -03:00
parent 729cb0f244
commit 7c0219a1c2
2 changed files with 7 additions and 13 deletions

View file

@ -271,16 +271,10 @@ def supports_response_json_schema(model: str) -> bool:
return bool(gemini_2_plus_pattern.search(model_lower))
GEMINI_1_MODEL_PATTERN: Final = re.compile(r"gemini-1(?:\.|-)")
VERTEX_AI_USE_RESPONSE_JSON_SCHEMA_PARAM: Final = "vertex_ai_use_response_json_schema"
VERTEX_AI_VERBATIM_RESPONSE_SCHEMA_PARAM: Final = "litellm_param_vertex_ai_verbatim_response_schema"
def _rejects_response_json_schema(model: str) -> bool:
"""Gemini 1.x generateContent has no responseJsonSchema field, so no override can reach it"""
return bool(GEMINI_1_MODEL_PATTERN.search(model.lower()))
def should_use_response_json_schema(model: str, request_override: bool | None = None) -> bool:
"""
Resolve which structured output channel a json_schema response_format goes to.
@ -289,16 +283,16 @@ def should_use_response_json_schema(model: str, request_override: bool | None =
natively converted ``responseSchema`` (nullable unions flattened, constraints
hoisted, ``propertyOrdering`` added). Precedence: per request
``vertex_ai_use_response_json_schema``, then
``litellm.vertex_ai_use_response_json_schema``, then the model heuristic. Neither
override can select a channel the model has no field for
``litellm.vertex_ai_use_response_json_schema``, then the model heuristic. An
override picks between the channels the model has, it never adds one
"""
override: Final = request_override if request_override is not None else litellm.vertex_ai_use_response_json_schema
if override is None:
return supports_response_json_schema(model)
if override and _rejects_response_json_schema(model):
if override and not supports_response_json_schema(model):
verbose_logger.warning(
"vertex_ai_use_response_json_schema=True ignored for model=%s: it has no responseJsonSchema field, "
"so the schema stays on responseSchema",
"vertex_ai_use_response_json_schema=True ignored for model=%s: it is not known to accept "
"responseJsonSchema, so the schema stays on responseSchema",
model,
)
return False

View file

@ -200,7 +200,7 @@ CLIENT_SCHEMA = {
(None, None, "gemini-2.5-flash", True),
(None, None, "gemini-1.5-pro", False),
(False, None, "gemini-2.5-flash", False),
(True, None, "gemini-flash-latest", True),
(True, None, "gemini-flash-latest", False),
(True, None, "gemini-1.5-pro", False),
(None, True, "gemini-1.5-pro", False),
(False, True, "gemini-2.5-flash", True),
@ -212,7 +212,7 @@ def test_should_use_response_json_schema_precedence(
):
"""
Per request override beats litellm.vertex_ai_use_response_json_schema, which beats the model
heuristic, and neither can put a schema on a channel Gemini 1.x has no field for
heuristic, and neither can select responseJsonSchema for a model not known to accept it
"""
monkeypatch.setattr(litellm, "vertex_ai_use_response_json_schema", global_setting)