fix(vertex): keep scalar constraints on type-array anyOf branches

This commit is contained in:
bunnysayzz 2026-09-27 04:08:45 +05:30
parent 3afcd176b3
commit 836e6cbafe
2 changed files with 62 additions and 2 deletions

View file

@ -1015,6 +1015,19 @@ def _convert_schema_types(schema, depth=0):
"minProperties",
"maxProperties",
}
# Constraint keywords that apply to primitive types and should move
# into the anyOf branch with the type. Without this they are left on
# the parent next to anyOf and dropped by _filter_anyof_fields.
scalar_constraint_fields: Final = {
"enum",
"pattern",
"minLength",
"maxLength",
"minimum",
"maximum",
"multipleOf",
"format",
}
any_of: Final[list[dict[str, object]]] = []
for t in type_val:
@ -1034,14 +1047,22 @@ def _convert_schema_types(schema, depth=0):
item_schema[field] = deepcopy(schema[field])
any_of.append(item_schema)
else:
# For primitive types, only include the type
any_of.append({"type": t})
# For primitive types, carry the scalar constraint keywords
# into the branch so they survive _filter_anyof_fields
item_schema: dict[str, object] = {"type": t}
for field in scalar_constraint_fields:
if field in schema:
item_schema[field] = deepcopy(schema[field])
any_of.append(item_schema)
# Remove type-specific fields from parent if we moved them into anyOf
has_object_or_array: Final = any(t in ("object", "array") for t in type_val if isinstance(t, str))
if has_object_or_array:
for field in type_specific_fields:
schema.pop(field, None)
else:
for field in scalar_constraint_fields:
schema.pop(field, None)
schema["anyOf"] = any_of
schema.pop("type")

View file

@ -1755,3 +1755,42 @@ def test_get_vertex_ai_lyria_model_info_is_none_for_non_lyria_speech_models(mode
assert get_vertex_ai_lyria_model_info(model=model) is None
def test_type_array_keeps_scalar_constraints_on_anyof_branches():
"""A nullable type array must not lose enum/min-max/pattern/format (issue #43325)."""
from litellm.llms.vertex_ai.common_utils import _build_vertex_schema
schema = {
"type": "object",
"properties": {
"status": {"type": ["string", "null"], "enum": ["open", "closed"], "maxLength": 6},
"priority": {"type": ["integer", "null"], "minimum": 1, "maximum": 5},
"code": {"type": ["string", "null"], "pattern": "^[A-Z]+$", "format": "date-time"},
},
"required": ["status"],
}
assert _build_vertex_schema(schema) == {
"type": "object",
"properties": {
"status": {
"anyOf": [
{"type": "string", "enum": ["open", "closed"], "maxLength": 6},
{"type": "null"},
]
},
"priority": {
"anyOf": [
{"type": "integer", "minimum": 1, "maximum": 5},
{"type": "null"},
]
},
"code": {
"anyOf": [
{"type": "string", "pattern": "^[A-Z]+$", "format": "date-time"},
{"type": "null"},
]
},
},
"required": ["status"],
}