fix(vertex-ai): gate veo resolution inference

This commit is contained in:
Emerson Gomes 2026-07-15 21:04:48 -05:00
parent 1e4b30e4ed
commit 9012842c2f
No known key found for this signature in database
GPG key ID: D3DF28AB5D1B5E17
3 changed files with 34 additions and 21 deletions

View file

@ -97,6 +97,12 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
"720x1280": "9:16",
"1080x1920": "9:16",
}
_OPENAI_VIDEO_SIZE_TO_RESOLUTION: dict[str, str] = {
"1280x720": "720p",
"1920x1080": "1080p",
"720x1280": "720p",
"1080x1920": "1080p",
}
def __init__(self):
BaseVideoConfig.__init__(self)
@ -140,8 +146,9 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
- prompt prompt (in instances)
- input_reference image (in instances)
- size aspectRatio (e.g., "1280x720" "16:9")
- size resolution when inferable ("1280x720"/"720x1280" "720p",
"1920x1080"/"1080x1920" "1080p"); skipped if ``resolution`` is already set
- size resolution for Veo 3 models when inferable
("1280x720"/"720x1280" "720p", "1920x1080"/"1080x1920" "1080p");
skipped if ``resolution`` is already set
- seconds durationSeconds (defaults to 4 seconds if not provided)
"""
mapped_params: Final[dict[str, Any]] = {}
@ -168,10 +175,10 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
mapped_params["aspectRatio"] = aspect_ratio
nested_params: Final = video_create_optional_params.get("parameters")
has_resolution = "resolution" in mapped_params or (
isinstance(nested_params, dict)
and nested_params.get("resolution") is not None
isinstance(nested_params, dict) and nested_params.get("resolution") is not None
)
if not has_resolution:
supports_resolution = model.removeprefix("vertex_ai/").startswith("veo-3.")
if supports_resolution and not has_resolution:
inferred_resolution = self._convert_size_to_resolution(size)
if inferred_resolution is not None:
mapped_params["resolution"] = inferred_resolution
@ -201,18 +208,7 @@ class VertexAIVideoConfig(BaseVideoConfig, VertexBase):
return self._OPENAI_VIDEO_SIZE_TO_ASPECT_RATIO.get(size, "16:9")
def _convert_size_to_resolution(self, size: str) -> str | None:
if not size or size not in self._OPENAI_VIDEO_SIZE_TO_ASPECT_RATIO:
return None
try:
width, height = size.split("x", 1)
smaller_edge = min(int(width), int(height))
except (ValueError, TypeError):
return None
if smaller_edge == 720:
return "720p"
if smaller_edge == 1080:
return "1080p"
return None
return self._OPENAI_VIDEO_SIZE_TO_RESOLUTION.get(size)
def validate_environment(
self,

View file

@ -76,6 +76,7 @@ class VideoCreateOptionalRequestParams(TypedDict, total=False):
image: Any | None # Image for image-to-video; dict with gcsUri/bytesBase64Encoded, or file-like object
parameters: dict[str, Any] | None # Provider-specific parameters block passed directly to the API
model: str | None
resolution: str | None
seconds: str | None
size: str | None
characters: list[dict[str, str]] | None

View file

@ -285,17 +285,33 @@ class TestVertexAIVideoConfig:
assert mapped["durationSeconds"] == 8
assert mapped["aspectRatio"] == "16:9"
assert mapped["resolution"] == "720p"
assert "resolution" not in mapped
def test_map_openai_size_to_1080p_resolution(self):
@pytest.mark.parametrize(
("size", "expected_resolution"),
(("1280x720", "720p"), ("1920x1080", "1080p")),
)
def test_map_openai_size_to_resolution_for_veo_3(
self, size: str, expected_resolution: str
):
mapped = self.config.map_openai_params(
video_create_optional_params={"size": "1920x1080"},
video_create_optional_params={"size": size},
model=VEO_31_LITE_VERTEX_MODEL,
drop_params=False,
)
assert mapped["aspectRatio"] == "16:9"
assert mapped["resolution"] == "1080p"
assert mapped["resolution"] == expected_resolution
def test_map_openai_size_does_not_infer_resolution_for_veo_2(self):
mapped = self.config.map_openai_params(
video_create_optional_params={"size": "1920x1080"},
model="vertex_ai/veo-2.0-generate-001",
drop_params=False,
)
assert mapped["aspectRatio"] == "16:9"
assert "resolution" not in mapped
def test_map_openai_size_does_not_override_provider_resolution(self):
mapped = self.config.map_openai_params(