Gemini Multi-Turn Chat
Actual multi-turn conversation inside a ComfyUI graph
- response
- conversation_history
Here's the thing most "LLM in ComfyUI" nodes quietly skip: they're one-shot. You type a prompt, you get an answer, and the model has already forgotten you by the time the next queue hits. If you're building something that's actually a conversation - a dialogue-driven workflow, an iterative character brainstorm that needs the model to remember what you liked two turns ago - you need the chat history carried forward. That's what this node is: Gemini multi-turn chat, with the conversation history passed as a string so it survives between runs of the graph.
It's the least glamorous node in the Gemini text set and one of the most genuinely useful. Wire the conversation_history output back into the conversation_history input and every queue continues the thread instead of restarting it. In a wider ComfyUI workflow, that's how you build a "design a character, refine it, iterate on the costume" loop where each step actually builds on the last.
How it works
The node keeps the whole conversation as a JSON string. You feed it the history from the previous turn (or nothing, to start fresh), plus your new message. It parses the JSON back into Content objects with proper user/model roles, appends your new message, and sends the full thread to generate_content. The model's reply comes back, gets appended to the history as the model's turn, and both the reply and the updated history are returned.
So the state isn't held in the node's memory - it lives in the graph, as data. That's what makes it composable: you can log it, transform it, branch on it, or feed it to a text node.
Inputs and outputs that matter
message- your new user message. The only thing you type each turn.conversation_history- the JSON history. Leave empty for a brand-new conversation; wire the output back in to continue. If it contains garbage JSON, the node logs a warning and silently starts fresh rather than crashing - a forgiving touch.model- defaults togemini-2.5-flash, a good chat model; 35 options in the dropdown.system_instruction- optional, but this is where you set the persona or rules for the whole thread.temperature- 0 to 2, default 0.7. Lower for a steadier conversation, higher for creativity.
Two outputs: response (the model's reply, STRING) and conversation_history (the updated thread, STRING). Feed the second back into the first's input. That's the loop.
How to install it
It's a member of ComfyUI-API-Toolkit, so the install is pack-level:
cd ComfyUI/custom_nodes
git clone https://github.com/IxMxAMAR/ComfyUI-API-Toolkit
cd ComfyUI-API-Toolkit
pip install -r requirements.txt
Or search "API Toolkit" in ComfyUI Manager and restart. The Gemini service needs google-genai>=0.8.0 and an API key (node field or GEMINI_API_KEY env var). No downloads, no VRAM.
Common issues
The one real failure mode people hit: expecting it to be stateful when it isn't. If you don't wire the conversation_history output back around, every turn is amnesia - a fresh chat each time. That's not a bug, that's the design, and it's also why the node re-runs every queue (the pack's API nodes all force re-execution via IS_CHANGED): each queue is a new turn, paid for separately.
Also remember the API-path caveat that applies to all of Gemini: this is a filtered, closed model. The kind of conversation you'd have locally with an uncensored model isn't on the menu here. For SFW dialogue and prompt-driven chat it's great; for anything the filter refuses, you're better served by a local LLM node.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| api_key | STRING | Gemini API key. Leave blank to use GEMINI_API_KEY env var. | |
| model | COMBO | gemini-2.5-flash | Gemini model for chat. |
| custom_model | STRING | Override with a custom model ID. | |
| message | STRING | The new user message to send. | |
| conversation_historyopt | STRING | JSON conversation history from previous turn. Leave empty to start fresh. | |
| system_instructionopt | STRING | System instruction for the chat. | |
| temperatureopt | FLOAT | 0.700–2 | Controls randomness. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| response | STRING | — |
| conversation_history | STRING | — |