Divergent Gemini Node
Gemini for captions and prompt surgery
- image_optional
- text
You know that moment where you stare at a generated image and think "okay, but what would an LLM call this?" The Divergent Gemini Node is the answer to that thought. It drops a real Gemini model into your graph: feed it a prompt, optionally an image, and it returns text. No local LLM weights, no GPU vram - it calls Google's API, so it needs a key and internet, but it gives you a model that genuinely reads images and writes sentences about them.
The obvious move is automatic captioning: generate → image_optional → Gemini → feed the returned text into a save node's caption field and you've got a dataset pipeline. But it's also great for prompt rewriting mid-workflow, or as a debugging assistant that looks at your output and tells you what changed. It's one of those nodes that feels gimmicky until you wire it into a real loop.
How it works
Under the hood it uses Google's google-genai library. On execution it resolves an API key - per-node override first, then a config.json in the pack folder, then an environment variable - builds your prompt into content parts, converts any input image to JPEG bytes and attaches it, applies the four safety thresholds you picked, and makes the call with retry logic built in (up to max_retries, with retry_delay_seconds between attempts). Extended thinking is on by default for models that support it, with a token budget you can set.
The inputs that actually matter
Most of these you'll leave alone, but a few are worth knowing:
- model - defaults to
gemini-1.5-flash, and the list spans 1.5-pro, the 2.0-flash family, and 2.5-pro/flash. These are the text-generation models, not the image generators - for image understanding, any of them work fine. - prompt - the actual instruction. "Describe the image." is the default and it's a fine captioning prompt.
- temperature - 0–2, default 0.9. For deterministic captioning you'll want it lower.
- image_optional - the IMAGE input that makes it multimodal. Skip it for pure text work.
- max_output_tokens - default 2048, capped at 8192. Generous for captions, tight for long analysis.
- The four safety_* combos all default to "Block Medium & Above". If Gemini keeps refusing your content, this is where to look.
- extended_thinking and thinking_token_budget - thinking is on by default;
-1budget means auto. Setoutput_thoughtsif you want the reasoning chain in the output.
Output
- text (STRING) - the model's reply. Wire it anywhere a string belongs: a text preview, the caption input of
SaveImageEnhancedNode, a prompt field.
API key setup
The pack reads a config.json in its own directory:
{
"GOOGLE_API_KEY": "YOUR_API_KEY_HERE"
}
Get the key from Google AI Studio. A .env file or a GOOGLE_API_KEY environment variable also works, and api_key_override on the node beats all three if you want one key per workflow. The files are git-ignored, so your secret stays local.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/thedivergentai/divergent_nodes.git divergent_nodes
cd divergent_nodes
pip install -r requirements.txt
Or search "Divergent Nodes" in ComfyUI Manager. This pack is built against the newer v3 node schema, so a current ComfyUI matters.
Where people get burned
The classic failure is "API key not found" - the node looks for the key and the message tells you exactly which of the three sources to fix. After that, the usual complaint is a blocked generation, and nine times out of ten the safety combo you didn't touch is the blocker. Budget-wise, remember this is a paid API: a captioning loop over a big batch is cheap but not free, and rate limits can bite - which is what the batch node next door exists for.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| model | COMBO | gemini-1.5-flash | Select the Gemini model to use |
| prompt | STRING | Describe the image. | The text prompt for generation |
| temperature | FLOAT | 0.900–2 | Controls randomness. Higher = more creative |
| top_p | FLOAT | 1.000–1 | Nucleus sampling probability threshold |
| top_k | INT | 11–100 | Top-K sampling threshold |
| max_output_tokens | INT | 20481–8192 | Maximum tokens to generate |
| safety_harassment | COMBO | Block Medium & Above | Safety threshold for harassment |
| safety_hate_speech | COMBO | Block Medium & Above | Safety threshold for hate speech |
| safety_sexually_explicit | COMBO | Block Medium & Above | Safety threshold for sexual content |
| safety_dangerous_content | COMBO | Block Medium & Above | Safety threshold for dangerous content |
| image_optionalopt | IMAGE | Optional image for multimodal models | |
| api_key_overrideopt | STRING | Override API key for this node | |
| max_retriesopt | INT | 30–10 | Maximum retry attempts |
| retry_delay_secondsopt | INT | 51–60 | Delay between retries |
| extended_thinkingopt | BOOLEAN | true | Enable extended thinking if supported |
| thinking_token_budgetopt | INT | -1-1–8192 | Token budget for thinking (-1=auto) |
| output_thoughtsopt | BOOLEAN | false | Include thought process in output |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |