Image Gen (OpenAI → VOD fallback)
OpenAI first, Tencent VOD when you get throttled
- image
- upstream_url
- used_protocol
This node doesn't run a model on your GPU - it's an API-wrapper node. You type a prompt, it POSTs to a cloud image endpoint, and a finished IMAGE tensor drops back into your graph like a local sampler made it. The twist is in the name: it has two backends and switches between them automatically. Fill in an OpenAI-compatible base URL (OpenRouter and friends) and it calls POST {base_url}/chat/completions. If that returns HTTP 429 or rate-limit text, it transparently falls back to Tencent Cloud VOD's AIGC image API instead of failing your whole workflow.
Why does that exist? The repo is one commit by one author, and the source comments reference a Tencent video-editing backend where OpenRouter throttling was stalling a production pipeline. This node is that problem, packaged for ComfyUI. Reach for it if you already have a Tencent Cloud VOD account with AIGC image generation enabled and want cloud generation in-graph without loading a local checkpoint. No Tencent account? It still works - leave the VOD fields alone and you've got a plain OpenAI-image node.
How the routing works
This is the load-bearing design, straight from the code:
openai_base_urlandopenai_modelboth set → try OpenAI first.- OpenAI returns 429, or the response body matches a rate-limit phrase (
rate limit,too many requests,resource_exhausted,quota exceeded…) → fall back to VOD. - Either field blank → skip OpenAI, go straight to VOD.
- Any other OpenAI error (5xx, timeout, decode failure) → raise immediately, no fallback.
That last rule is the opinion worth stealing: the fallback exists to ride out throttling, not to mask a broken upstream. If the OpenAI endpoint is actually dead, the node would rather fail loudly than burn quota on two providers for an image nobody gets.
The VOD path is async: it creates a task (CreateAigcImageTask), then polls DescribeTaskDetail starting at poll_interval_sec (default 1.5s) with 1.5x backoff capped at 5s, until the task finishes or poll_timeout_sec (default 120s) runs out. The generated image is downloaded straight into a tensor. Tencent's StorageMode is forced to Temporary, so the node never depends on long-lived hosted URLs.
The inputs that matter
Most of the 15 inputs you can safely ignore. The ones you'll actually set:
- prompt - the only required field, multiline, can't be empty.
- aspect_ratio (16:9 default) and resolution (1K / 2K / 4K) - both enums, passed to whichever backend answers.
- openai_base_url / openai_model / openai_api_key - the OpenAI-compatible endpoint. Blank both URL and model and you're on VOD-only.
- secret_id / secret_key - Tencent credentials. Leave blank and they fall back to
TENCENTCLOUD_SECRET_ID/TENCENTCLOUD_SECRET_KEYenv vars, which is the right move for shared setups. - sub_app_id - your Tencent VOD sub-account. Must be non-zero or the VOD path errors out.
- ref_image_url_1/2/3 - up to three public URLs for img2img, on either protocol.
Three outputs come back: image (the tensor), upstream_url (a trace URL for debugging - inline data: URLs are redacted to data:<inline base64 omitted> so your logs don't explode), and used_protocol, which is openai, vod, or vod_fallback. Wire used_protocol into a text display and you can see at a glance which backend actually served you.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/kq0715/comfyui_vod_image_gen
cd comfyui_vod_image_gen && pip install -r requirements.txt
Then restart ComfyUI - fully, not just the browser tab. The OpenAI-only path needs nothing beyond what ComfyUI already ships (requests, Pillow, numpy). The single real dependency is tencentcloud-sdk-python-common, and the code lazy-imports it so you only hit it when the VOD path actually runs.
Troubleshooting
Node missing from the UI. Make sure it's cloned exactly one level deep at ComfyUI/custom_nodes/comfyui_vod_image_gen/ with __init__.py directly inside, then look for [comfyui_vod_image_gen] loaded: in the server console on startup. The lazy-import fix exists precisely because an earlier version crashed at import and made the node silently disappear.
ModuleNotFoundError: No module named 'tencentcloud' when you run the node. Expected on the VOD path - pip install tencentcloud-sdk-python-common. The OpenAI path won't touch it.
Two gotchas worth remembering. First, reference images must be publicly fetchable URLs - you can't feed a ComfyUI IMAGE tensor straight into either upstream, so upload it to a public URL with another node first and paste that in. Second, the usual API-node caveat: this thing holds your keys and phones home by design, exactly the shape of node that's been weaponized in this ecosystem once. It's tiny and one file - read it once before you feed it a real secret, and prefer env vars over pasting keys into the graph.
Reach for it if Tencent VOD is already in your stack; otherwise a plain OpenAI/OpenRouter wrapper does the same job with one less moving part.
Inputs (18)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| aspect_ratio | COMBO | 16:9 | 8 options: , 16:9, 9:16, 1:1, 4:3, 3:4, +2 |
| resolution | COMBO | 4 options: , 1K, 2K, 4K | |
| model_name | STRING | GEM | — |
| model_version | STRING | 3.0 | — |
| sub_app_id | INT | 00–2147483647 | — |
| poll_interval_sec | FLOAT | 1.50.2–30 | — |
| poll_timeout_sec | INT | 1205–1800 | — |
| openai_base_urlopt | STRING | — | |
| openai_modelopt | STRING | — | |
| openai_api_keyopt | STRING | — | |
| openai_timeout_secopt | INT | 1805–1800 | — |
| secret_idopt | STRING | — | |
| secret_keyopt | STRING | — | |
| regionopt | STRING | — | |
| ref_image_url_1opt | STRING | — | |
| ref_image_url_2opt | STRING | — | |
| ref_image_url_3opt | STRING | — |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| upstream_url | STRING | — |
| used_protocol | STRING | — |