Nodes/comfyui_vod_image_gen/Image Gen (OpenAI → VOD fallback)
ComfyUI Node

Image Gen (OpenAI → VOD fallback)

OpenAI first, Tencent VOD when you get throttled

By kq0715·Created 4 months ago·Updated 4 months ago· 0
Image Gen (OpenAI → VOD fallback)
    • image
    • upstream_url
    • used_protocol
    prompt
    aspect_ratio16:9
    resolution
    model_nameGEM
    model_version3.0
    sub_app_id0
    poll_interval_sec1.5
    poll_timeout_sec120
    openai_base_url
    openai_model
    openai_api_key
    openai_timeout_sec180
    secret_id
    secret_key
    region
    ref_image_url_1
    ref_image_url_2
    ref_image_url_3

    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_url and openai_model both 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_KEY env 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.

    Categoryimage/generation

    Inputs (18)

    NameTypeDefaultDescription
    promptSTRING
    aspect_ratioCOMBO16:98 options: , 16:9, 9:16, 1:1, 4:3, 3:4, +2
    resolutionCOMBO4 options: , 1K, 2K, 4K
    model_nameSTRINGGEM
    model_versionSTRING3.0
    sub_app_idINT00–2147483647
    poll_interval_secFLOAT1.50.2–30
    poll_timeout_secINT1205–1800
    openai_base_urloptSTRING
    openai_modeloptSTRING
    openai_api_keyoptSTRING
    openai_timeout_secoptINT1805–1800
    secret_idoptSTRING
    secret_keyoptSTRING
    regionoptSTRING
    ref_image_url_1optSTRING
    ref_image_url_2optSTRING
    ref_image_url_3optSTRING

    Outputs (3)

    NameTypeDescription
    imageIMAGE
    upstream_urlSTRING
    used_protocolSTRING