Ollama Prompt Planner
Let a local LLM pick your model, LoRAs, and sampler
- checkpoint
- loras
- lora_strengths
- model_type
- steps
- cfg
- sampler_name
- scheduler
- width
- height
- seed
- positive_prompt
- negative_prompt
- plan_json
- vae_name
- clip_name
- task
- denoise
- use_refiner
- refiner_checkpoint
- controlnet_name
- controlnet_strength
- controlnet_start
- controlnet_end
The Ollama Prompt Planner is the brain of the ComfyUI-cluster pack: you type a prompt, and a local LLM decides which checkpoint to use, which LoRAs to stack, and what steps/CFG/sampler/resolution to run - then hands the whole plan to the loader nodes. It's an LLM-as-router, and the part people don't believe at first is that it's fully local. No API key, no cloud call, no "sign in to continue." The name says Ollama, and it means the Ollama you run on your own machine.
Worth being clear about the pitch before you get invested: this node doesn't make images. It makes decisions about images. The planners in this pack sit at the front of the graph, and everything downstream - DynamicCheckpointLoader, DynamicLoraStack, the KSampler - just executes whatever plan comes out. That's a genuinely different workflow shape than hand-picking a checkpoint dropdown.
How it works
The node reads model_registry.json (the pack's catalog of ~100 checkpoints, ~95 LoRAs, and a couple of ControlNets), filters it down to models whose min_vram fits your max_vram budget, compacts it to a lightweight payload, and sends it to Ollama along with your prompt. The system prompt demands one thing: a valid JSON plan with checkpoint, LoRAs, strengths, model type, sampler, scheduler, resolution, seed, and more. The call uses Ollama's /api/chat with format: json and a low temperature so it doesn't get creative with your settings.
Here's the smart part. If Ollama is down, or returns garbage, or takes too long, the node doesn't fail - it falls back to _heuristic_plan, which scores your prompt's keywords against registry tags and picks the best-matching checkpoint, LoRAs, and even a ControlNet if you mention pose or canny. Your workflow survives an Ollama outage, just with a dumber plan. Either way, it then normalizes resolution from aspect_ratio and base_size per model type, merges your user_negative into the negative prompt, and - a nice detail grounded in how Flux actually behaves - blanks the negative prompt entirely and disables the refiner when the chosen model type is Flux.
The inputs that matter
Most of the twelve inputs are set-and-forget, but four are yours:
- prompt - the actual generation prompt. Everything routes off this.
- ollama_model - which local model plans for you. Default
qwen2.5:7b; any capable text model works. - max_vram - your GPU budget (24/16/12/8/6 GB). Checkpoints over the budget are excluded from what the LLM can pick.
- task_hint -
autois fine, but if you know it's img2img or Flux, telling it avoids a wrong guess.
ollama_host/ollama_port matter if your Ollama isn't on localhost:11434.
The outputs that matter
It has 24 outputs. The ones you'll actually wire: checkpoint, loras, lora_strengths, model_type, vae_name/clip_name, positive_prompt, negative_prompt, steps, cfg, sampler_name, scheduler, width, height, seed, and denoise. Plus plan_json - the raw plan as a string, great for debugging or feeding a LiveStatus node. The pack's workflows wire the checkpoint/LoRA outputs straight into the dynamic loaders and everything else into a KSampler.
How to install it
Two parts. Install the pack via ComfyUI Manager (search "ComfyUI-cluster") or:
cd ComfyUI/custom_nodes
git clone https://github.com/GeekatplayStudio/ComfyUI-cluster
Restart ComfyUI. Then install Ollama and pull a model the planner can use:
ollama pull qwen2.5:7b
The nodes themselves have no Python dependencies - Ollama is the entire external requirement, and the model files are downloaded by install.bat if you want the pack's curated set.
Troubleshooting
Most issues trace to one of three things. Ollama not running, or the model not pulled - ollama pull qwen2.5:7b and check the server is up, or you'll silently get heuristic plans instead of LLM plans. An empty registry - the planner has nothing to pick from if model_registry.json is missing or every model is disabled, so run manage_models.bat to sync it with disk. And too-tight a max_vram - set 24 GB but only have 8, and the planner's options shrink to almost nothing. Also keep task_hint honest; telling it "flux" when you're on SDXL produces plans that fight your loader.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | — | |
| ollama_model | STRING | qwen2.5:7b | — |
| registry_path | STRING | model_registry.json | — |
| task_hint | COMBO | 7 options: auto, text2img, img2img, inpaint, sdxl, sd15, +1 | |
| user_negative | STRING | — | |
| aspect_ratio | COMBO | 15 options: 1:1, 3:2, 2:3, 4:3, 3:4, 16:9, +9 | |
| base_size | INT | 1024256–2048 | — |
| ollama_host | STRING | localhost | — |
| ollama_port | INT | 114341–65535 | — |
| max_vram | COMBO | 24 | 5 options: 24, 16, 12, 8, 6 |
Outputs (24)
| Name | Type | Description |
|---|---|---|
| checkpoint | STRING | — |
| loras | STRING | — |
| lora_strengths | STRING | — |
| model_type | STRING | — |
| steps | INT | — |
| cfg | FLOAT | — |
| sampler_name | euler,euler_cfg_pp,euler_ancestral,euler_ancestral_cfg_pp,heun,heunpp2,exp_heun_2_x0,exp_heun_2_x0_sde,dpm_2,dpm_2_ancestral,lms,dpm_fast,dpm_adaptive,dpmpp_2s_ancestral,dpmpp_2s_ancestral_cfg_pp,dpmpp_sde,dpmpp_sde_gpu,dpmpp_2m,dpmpp_2m_cfg_pp,dpmpp_2m_sde,dpmpp_2m_sde_gpu,dpmpp_2m_sde_heun,dpmpp_2m_sde_heun_gpu,dpmpp_3m_sde,dpmpp_3m_sde_gpu,ddpm,lcm,ipndm,ipndm_v,deis,res_multistep,res_multistep_cfg_pp,res_multistep_ancestral,res_multistep_ancestral_cfg_pp,gradient_estimation,gradient_estimation_cfg_pp,er_sde,seeds_2,seeds_3,sa_solver,sa_solver_pece,ddim,uni_pc,uni_pc_bh2 | — |
| scheduler | simple,sgm_uniform,karras,exponential,ddim_uniform,beta,normal,linear_quadratic,kl_optimal | — |
| width | INT | — |
| height | INT | — |
| seed | INT | — |
| positive_prompt | STRING | — |
| negative_prompt | STRING | — |
| plan_json | STRING | — |
| vae_name | STRING | — |
| clip_name | STRING | — |
| task | STRING | — |
| denoise | FLOAT | — |
| use_refiner | BOOLEAN | — |
| refiner_checkpoint | STRING | — |
| controlnet_name | STRING | — |
| controlnet_strength | FLOAT | — |
| controlnet_start | FLOAT | — |
| controlnet_end | FLOAT | — |