iz chat
A chat window living inside a ComfyUI node
- cfg
- image
- full_chat
- last_response
Most ways of putting an LLM in a ComfyUI graph mean standing up a second process - an Ollama server, or a separate GGUF loader node holding its own weights. iz chat takes a lazier route: it borrows ComfyUI's own text-encoder plumbing. You load a chat-capable model in CLIPLoader, hand it to iz chat cfg, and the iz chat node grows a chat box. You type, you get a reply, you edit it, you send another - all without pressing Run, because generation travels over the pack's own HTTP routes on your ComfyUI server instead of the prompt queue.
That puts it at the chat-shaped end of the "LLM as a tool in the graph" niche, and the uses are the boring ones that matter: talking a rough idea into a prompt, asking questions about a reference image (it takes IMAGE, batches included), and having a local vision model a click away.
One honest note first. This is a brand-new, single-author pack - the README says the nodes were written with an LLM's help, and a search of the Reddit corpus for the slug comes back empty. Not a reason to skip it; a reason to read the code first, especially in a category where an "LLM vision" node once shipped malware. Good news: nodes.py is small, and api.py only registers routes on your own ComfyUI server. No outbound calls, no key, no cloud.
How it works
iz chat cfg caches the actual CLIP object in a module-level global, along with your sampling settings. Running the workflow is only for loading the model - it does not generate anything. When you hit send, the pack's frontend JS posts your transcript and any images to /iz_chat/generate, and the server runs clip.tokenize(prompt, min_length=1, skip_template=False) - passing an image tensor too when there is one - then clip.generate(do_sample=True, temperature, top_k, top_p, repetition_penalty, seed), then clip.decode().
The prompt is built by flattening the conversation into plain System: … / User: … / Assistant: lines, with Assistant: appended as the continuation cue - and no hard stop tokens or regex cleaner like the purpose-built enhancer packs ship, so a chatty model will occasionally keep going in role labels.
Two more mechanics worth knowing. The node returns float("NaN") from IS_CHANGED, deliberately defeating ComfyUI's cache so it re-executes every run. And if you queue the workflow while a chat generation is in flight, it waits up to 300 seconds rather than fighting it.
Inputs and outputs that matter
- cfg - from
iz chat cfg. Nothing happens without it. - system_prompt - defaults to "You are a helpful assistant." A text node wired into this socket outranks the Set node and outranks what you typed; the frontend walks upstream to find it.
- chat_history - the JSON transcript, managed by the chat UI. Don't hand-edit it.
- image (optional) - one image or a batch for a vision model, downscaled to
max_image_mp.
It returns two strings. full_chat is the whole conversation with 👤 User / 🤖 Assistant prefixes; last_response is the newest assistant reply - the one you wire into Preview Text / Show Text, or straight into a CLIP Text Encode for prompt enhancement. First-run trap: before any assistant turn exists, last_response is empty and full_chat is the literal placeholder "Chat is empty. Enter a message in the node interface." And outputs only refresh when you re-run the workflow - the chat is instant, the graph is not.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/IZmake/iz_chat.git
requirements.txt is empty and pyproject.toml declares no dependencies, so there is nothing to pip install. Restart ComfyUI. The repo ships registry metadata (PublisherId izmake), so ComfyUI Manager may find it too.
You still need a model: a text-generation-capable encoder such as Qwen3-VL, dropped into ComfyUI/models/text_encoders and loaded with CLIPLoader. The pack's own workflow loads a 4B abliterated Qwen3-VL int8 file with CLIPLoader set to type krea2 - copy that pairing. The 4B fits consumer cards; the 8B is the usual ceiling at ~8GB.
When it goes wrong
Run the workflow once after every ComfyUI restart, or the send button returns "CLIP model not loaded. Connect clip to iz_chat_cfg and run workflow." - the model lives in process memory, not in the saved graph.
The chat refuses to send while a workflow is running - it checks the server's queue status first - so a stuck queue makes the node look frozen.
The token bar is decoration: its denominator is token_limit, whose own tooltip says "statistical only, does not block anything." The setting that actually caps a reply is max_length on the cfg node. History is also resent in full every turn with no truncation, so long chats get slower and eventually run past the model's context - the ⚓ button on any message starts a fresh chat from there.
Finally, there is no unload/reload logic: the node holds onto the encoder you gave it, so on a tight card the chat model and your diffusion model compete for VRAM. If replies crawl, drop to a 4B or a quantized build rather than blaming the node.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| cfg | IZ_CHAT_CFG | Generation settings from iz_chat_cfg | |
| system_prompt | STRING | You are a helpful assistant. | System prompt |
| chat_history | STRING | [] | Chat history (managed via UI) |
| imageopt | IMAGE | Optional images (1 or batch) for Vision-Language model |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| full_chat | STRING | — |
| last_response | STRING | — |