Pi LLM Text
The cloud LLM that borrows a CLI instead of holding your key
- image
- text
It's a cloud LLM that keeps its key out of ComfyUI
Most LLM-in-the-graph nodes either run a local GGUF model on your card or take an API key straight into a node field. Pi LLM Text does neither. It shells out to Pi - the terminal coding agent from pi.dev (@earendil-works/pi-coding-agent) - in print mode, and returns whatever Pi's underlying model wrote as a plain ComfyUI STRING. Your API key or provider login lives in Pi's own config, not in the workflow. That's a genuinely nice property in a category where nodes love to swallow credentials: this one never sees yours.
The name is doing honest work, too: it does call Pi, just not through an API of its own. Pi is a separate program that already talks to a model provider, and this node drives it from the graph.
Why reach for it? A language model bolted into the graph is the standard way to turn a rough idea into a structured, model-appropriate prompt without fighting a blank text box. The usual tradeoff is local GGUF - free, uncensored, but eats VRAM - versus an API node - no VRAM, but costs per call and holds your key. Pi LLM Text sits awkwardly but usefully between: zero VRAM, no key in ComfyUI, but you pay per call through Pi's providers and everything leaves the machine. Fine for structured prompt writing and caption-ish text; don't route sensitive reference images through it.
How it works
The node builds a Pi command and runs it as a subprocess:
pi -p --no-tools --no-context-files --no-session \
--system-prompt "..." --model "minimax/MiniMax-M3" "...prompt..."
-p is print mode - stdout only, no chat UI. --no-tools --no-context-files --no-session deliberately cripple Pi so it behaves like a plain text/image LLM call and can't touch your files or open a session. That's a safety call, and a good one: this is a prompt-writing node, not an agent.
Connect an IMAGE and the node converts each frame to a temporary PNG, passing it as @/tmp/.../image-0.png before the prompt - use a vision-capable model from the dropdown for that. The prompt text itself is prompt plus optional connected_text, joined with a blank line.
There's also a deterministic local cache: the response lands in cache/<sha256>.txt inside the pack folder, keyed by system instruction, model, prompt, image digests, and seed. Same inputs, same seed → same text, no second API call.
The inputs that matter
You mostly set three things: system_instruction (how the model should behave - the default already says "return only the requested text"), prompt (what you want it to produce, or a wired-in STRING), and model_name (a 61-entry static dropdown, default minimax/MiniMax-M3, plus OpenRouter Grok/Kimi/GLM/Gemini options). That list was generated from the author's own machine, so if your Pi can't reach a model in the dropdown you'll be editing models.py.
The rest is cache control, and it matters more than it looks:
response_mode-use_saved_text_if_present(default) usessaved_responsewhen you've pasted text into it;use_saved_textalways uses it;call_pialways calls.cache_mode-use_cache_or_generate(default) serves the cache when present,refresh_cacheforces a new call and overwrites,cache_onlyerrors if missing,disable_cachenever reads or writes.seed- part of the cache key, so bumping it forces a new response for the same prompt. Note it's not passed to Pi as a sampling seed.run_every_queue- disables ComfyUI's node cache so it fires every run.
The single output is text (STRING). Wire it into a CLIP Text Encode, or through the pack's extractor node first to strip any wrapper fluff the model adds.
Install
Pi is the real dependency. The pack itself is pure Python with no requirements file - it leans on the numpy/Pillow that ship inside ComfyUI. Install Pi first:
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
pi /login # or set provider API keys in Pi's config
Verify it works outside ComfyUI:
pi -p --no-tools --no-context-files --no-session "Say hello in five words."
Then, from your ComfyUI directory:
cd custom_nodes
git clone https://github.com/felixowens/ComfyUI-Pi-LLM.git
Restart ComfyUI and the nodes appear under the Pi category. ComfyUI Manager works too - search "ComfyUI-Pi-LLM".
Where people get burned
The classic failure is pi not being on the PATH the ComfyUI process sees - you'll get the node's "Could not find the pi executable" error. Windows users running ComfyUI from a desktop shortcut or service hit this most; the fix is a symlink into a common path (sudo ln -s $(which pi) /usr/local/bin/pi on Linux/macOS). After that: timeouts (default timeout_seconds is 120, and a long prompt or slow model will hit it), authentication errors raised from Pi itself, and the quiet surprise that reruns return the cached answer until you change the seed or cache_mode.
And the general caution applies - this is a network-calling node in a category that has shipped malware before. It's open source and tiny, so read it once before trusting it. Pi itself isn't a name the wider ComfyUI community talks about yet, and this pack is new; expect rough edges rather than a polished ecosystem.
Inputs (11)
| Name | Type | Default | Description |
|---|---|---|---|
| system_instruction | STRING | You are a helpful assistant. Return only the requested text. | — |
| model_name | COMBO | minimax/MiniMax-M3 | 61 options: minimax/MiniMax-M3, minimax/MiniMax-M2.7, minimax/MiniMax-M2.7-highspeed, anthropic/claude-3-5-sonnet-20240620, anthropic/claude-3-5-sonnet-20241022, anthropic/claude-3-7-sonnet-20250219, +55 |
| prompt | STRING | — | |
| response_mode | COMBO | use_saved_text_if_present | 3 options: use_saved_text_if_present, call_pi, use_saved_text |
| cache_mode | COMBO | use_cache_or_generate | 4 options: use_cache_or_generate, refresh_cache, cache_only, disable_cache |
| saved_response | STRING | — | |
| seed | INT | 00–18446744073709550000 | — |
| timeout_seconds | INT | 1201–3600 | — |
| run_every_queue | BOOLEAN | false | — |
| connected_textopt | STRING | — | |
| imageopt | IMAGE | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |