LLM Session Chat
A local LLM that actually remembers — LLM Session Chat keeps history on disk
- media
- assistant_text
ComfyUI has plenty of "chat with a model" nodes, but most of them are one-shot: you type, it answers, the context evaporates. LLM Session Chat is the one that treats a conversation like a real session. It runs a local GGUF model through llama-cpp-python - entirely inside ComfyUI, no Ollama sidecar, no API key, nothing phoning home - and it writes your chat history to disk so the model still remembers last week's context when you run the workflow again.
The name is not a lie about scope: if you want a model that keeps state across executions, this is the workhorse of the pack. Same session_id on rerun, and it continues the conversation. Change the session_id and you've started a fresh one. That maps onto a JSON history file under output/llm_session_sessions/, which is both the feature and the gotcha - the history is invisible in the UI (only the assistant's reply comes out), so you're trusting a folder full of JSON to hold your context.
How it works
Each turn appends to the session's history file, and the node manages how much of that history actually goes into the model's context window. This is where the pack's engineering shows. max_turns keeps only the last N turns live in context, and when old turns overflow, summarize_old_history rolls them into a compact summary the model still sees - the classic rolling-summary pattern for long chats, so you don't hit n_ctx on day three of a conversation. dynamic_max_tokens shrinks generation budget when a prompt is about to blow past the context window, with safety_margin_tokens as a buffer so it doesn't fail at the last token.
It's also genuinely multimodal on the input side: the optional media input accepts IMAGE tensors or batches (sent as image message parts) and ComfyUI AUDIO - but audio only works on Gemma 4 models, and media is used for the current turn only, never saved to history. enable_thinking turns on reasoning output for models that support it, and rewrite_continue is a nice touch that rewrites inputs starting with "continue" into an explicit continuation instruction to stop repetition loops.
The inputs that matter
The model dropdown scans ComfyUI/models/LLM/ for GGUF files. mmproj is the vision projector - the tooltip says manual selection is recommended, because auto-detect quietly fails when you have a folder full of mmproj files. n_gpu_layers: 0 is CPU-only, -1 offloads everything; for a 7B Q4 that's the difference between usable and watching paint dry. temperature, top_p, and max_tokens are the usual sampling knobs, and n_ctx is your context window - keep it to what the model actually supports. When you want a clean start, reset_session overwrites the history file. The output is a single string, assistant_text, ready to feed a text display or save node.
Installing it
ComfyUI Manager (search ComfyUI-LLM-Session) or:
cd ComfyUI/custom_nodes
git clone https://github.com/kantan-kanto/ComfyUI-LLM-Session.git
pip install pillow numpy
pip install llama-cpp-python
Restart, then put GGUF files in ComfyUI/models/LLM/. Plain PyPI llama-cpp-python handles most text-only models; vision families like Qwen3-VL or Gemma 4 generally want a recent JamePeng build. The pack is GPL-3.0 because of the llama-cpp-python dependency, which is worth knowing if you build something commercial on top.
Where people get burned
The history file is the trap. First-time users rerun a workflow, see the model reference things it never said in this session, and assume a bug - it's your old session resuming, and reset_session is the escape hatch. And be honest about the size of the thing you load: a 32B model on CPU at n_gpu_layers=0 will make you think the node is broken while it grinds. Start with a small Q4 and check that history folder actually grows. And yes, one more caution, because it's the ComfyUI LLM space: install only from the real repo or Manager - the community got burned hard by a malicious "LLM vision" node once, and a local-runtime pack like this is exactly the kind of thing a sketchy clone could dress up as.
Inputs (30)
| Name | Type | Default | Description |
|---|---|---|---|
| user_text | STRING | User message for this turn | |
| session_id | STRING | default | Session ID (maps to a history file). Same ID continues the chat. |
| model | COMBO | (No GGUF models found in models/LLM/) | GGUF model file in models/LLM/ |
| mmproj | COMBO | (Auto-detect) | Manual selection is recommended. |
| system_prompt | STRING | You are a helpful assistant. | System prompt (conversation policy). Saved into the history file. |
| max_tokens | INT | 5121–32768 | Maximum tokens to generate for this turn |
| temperature | FLOAT | 0.700–2 | Sampling temperature |
| top_p | FLOAT | 0.900.05–1 | Nucleus sampling (top_p). Lower = safer/more conservative. |
| n_gpu_layers | INT | 0-1–200 | Number of layers to offload to GPU. 0=CPU. -1=all. |
| n_ctx | INT | 4096512–131072 | Context length (must be supported by the model) |
| mediaopt | * | Optional IMAGE tensor/batch or AUDIO input for this turn only (never saved to history) | |
| persistent_cacheopt | COMBO | off | Persistent cache backend. LlamaDiskCache stores cache data under a session-specific cache directory in output/llm_session_sessions/cache/. |
| runtime_cacheopt | COMBO | LlamaTrieCache | Runtime cache backend. KV_cache uses save_state/load_state, RAM/Trie use llama.cpp cache in memory. |
| log_levelopt | COMBO | timing | Console logging verbosity for LLM Session Chat. |
| suppress_backend_logsopt | BOOLEAN | true | Suppress backend stdout/stderr during generation. |
| repeat_penaltyopt | FLOAT | 1.121–2 | Repetition penalty to reduce looping outputs (especially on continue). |
| repeat_last_nopt | INT | 2560–4096 | Apply repeat_penalty over the last N tokens. 0 disables. |
| rewrite_continueopt | BOOLEAN | true | Rewrite inputs starting with 'continue' into an explicit continuation instruction to reduce repetition. |
| max_turnsopt | INT | 120–200 | Keep only the last N turns in live context. 0 means no prior turns. |
| summarize_old_historyopt | BOOLEAN | true | Summarize overflow turns into a rolling summary when turns exceed max_turns. |
| summary_chunk_turnsopt | INT | 31–50 | Summarize overflow in chunks of this many turns (reduces summary frequency). |
| max_tokens_summaryopt | INT | 12816–2048 | Max tokens for summary generation (kept small for speed). |
| summary_max_charsopt | INT | 1500200–20000 | If the rolling summary exceeds this size, it will be re-summarized to stay compact. |
| dynamic_max_tokensopt | BOOLEAN | true | Dynamically shrink max_tokens (and/or turns) when prompt would exceed n_ctx. |
| min_generation_tokensopt | INT | 961–4096 | Minimum tokens to allow for generation when dynamic_max_tokens is enabled. |
| safety_margin_tokensopt | INT | 640–2048 | Token margin reserved to reduce the chance of exceeding n_ctx. |
| history_diropt | STRING | Optional directory for history files and session-scoped disk caches. Empty uses output/llm_session_sessions/ | |
| reset_sessionopt | BOOLEAN | false | If true, overwrite existing session history file with a fresh session. Session disk cache is kept. |
| stream_to_consoleopt | BOOLEAN | false | Stream tokens to console while generating. |
| enable_thinkingopt | BOOLEAN | false | Enable model thinking/reasoning output for supported chat formats. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| assistant_text | STRING | — |