feat(plugins): add Google Vertex AI image and video generation providers - #61579
feat(plugins): add Google Vertex AI image and video generation providers#61579conernar wants to merge 1 commit into
Conversation
Adds native support for Vertex AI's Veo and Gemini image/video models(omni included) via GCP credentials. █ Shared vertex_adapter is used for auth resolution.
Related: the native Vertex/Gemini provider cluster (#55742 Claude-on-Vertex, #29611 Gemini Express Mode, #59938 Gemini built-in tools) — those cover the chat surface; this PR adds the distinct media-generation (image/video) surface via the same |
|
Thanks for the substantial implementation and for keeping the media integration on the existing backend-provider interfaces. The media-generation scope is distinct from the existing Vertex chat-provider work noted in the triage discussion, but this cannot land as a bundled plugin.
Please publish this as a standalone plugin repository or pip entry point, where users can install it into Closed as not-planned per standing maintainer policy ( |
Adds native support for Vertex AI's Veo and Gemini image/video models (Omni included) via GCP credentials.
Shared vertex_adapter is used for auth resolution.
What does this PR do?
Hermes has pluggable
image_gen/video_genbackends, but none for Google Vertex AI — users who already run their chat model through thevertexprovider (service-account auth) had no way to use Google's media models (Gemini image, Imagen, Veo, Gemini Omni) from theimage_generate/video_generatetools.This PR adds two bundled
kind: backendplugins. Per the footprint ladder, no core files are touched — the plugins register through the existing provider registries and reuseagent/vertex_adapter.pyfor credential resolution, so a user with a workingvertexchat setup needs zero new secrets: justimage_gen.provider: vertex/video_gen.provider: vertexin config.yaml.Routing covers all four Vertex media API surfaces, dispatched by model-id prefix:
generateContent(image out)gemini-*image models:predictimagen-*:predictLongRunning+ pollveo-*gemini-*video (Omni)Design choice (deliberate): model IDs pass through unvalidated, with
google/publisher-prefix normalization (the vertex chat endpoint convention). Google's media catalog moves fast — Veo previews were removed 2026-04, Imagen 2–4 and Veo ≤3.0 retired 2026-06-30, andgemini-omni-flash-previewshipped 2026-06-30. Validating against a hardcoded catalog would break users on every Google release cycle; with passthrough, any current or future model on these four surfaces works via config alone. The built-in catalog (list_models) is advisory.Feature coverage: text-to-image, image editing (Gemini multimodal contents), text-to-video and image-to-video (Veo and Omni), audio generation, resolution/aspect-ratio/duration handling with provider-limit clamping, negative prompt / seed / person-generation passthrough, GCS output download, and RAI safety-filter reasons surfaced as structured errors instead of silent empty results.
Related Issue
N/A — no existing issue. Gap:
image_gen/video_genhad no Vertex backend despite chat-side Vertex support.Type of Change
Changes Made
plugins/image_gen/vertex/__init__.py+plugin.yaml—VertexImageGenProvider: prefix routing (gemini-*→generateContent,imagen-*→predict) withimage_gen.vertex.apiescape hatch for future prefixes; edit requests on predict-only models auto-reroute to agenerateContentmodelplugins/video_gen/vertex/__init__.py+plugin.yaml—VertexVideoGenProvider:veo-*→predictLongRunning/fetchPredictOperationpolling;gemini-*→ synchronous Interactions API (/v1beta1/.../locations/global/interactions); handles bothresponse.videos[]andgeneratedSamples[]operation shapes; downloadsgcsUrioutputs with the same bearer tokentests/plugins/image_gen/test_vertex_provider.py— 17 teststests/plugins/video_gen/test_vertex_plugin.py— 22 testscli-config.yaml.example— new commented "Image / Video Generation" section documentingimage_gen.provider/model,video_gen.provider/model, and the optionalimage_gen.vertex.*/video_gen.vertex.*keysgeneration_config.video_config.task(text/image/reference_to_video) explicitly; uri-delivered video outputs are parsed defensively (download with bearer token, URI fallback) — Vertex currently inlines all outputs and rejectsresponse_format.delivery, so no request-side delivery field is sentHow to Test
scripts/run_tests.sh tests/plugins/image_gen/test_vertex_provider.py tests/plugins/video_gen/test_vertex_plugin.py— 39 tests, no network or credentials neededVERTEX_CREDENTIALS_PATH(service-account JSON) in.env,vertex.project_idin config.yaml, then:hermes -q "generate an image of a lighthouse"andhermes -q "generate a short video of ocean waves"— verify media lands in the media cache and the tool result includes model/location metadataVerified end-to-end on a production GCP project (Debian 12 vps, Telegram gateway): Gemini image gen + edit, Veo 3.1 t2v/i2v, and Omni t2v/i2v via the Interactions API.Request fields were validated against the live Vertex endpoint, not just docs —
video_config.taskis confirmed accepted,response_format.deliveryis confirmed rejected (the Gemini API and Vertex schemas have diverged; the plugin only sends fields verified on Vertex).Checklist
Code
feat(plugins): ...)Documentation & Housekeeping
cli-config.yaml.examplefor the new optionalimage_gen.vertex.*/video_gen.vertex.*keysrequests+ stdlib, explicitencoding=on file IO, no POSIX-only callsScreenshots / Logs