Pi Text Extractor
The polite scrubber for chat-LLM output
- text
- found
The node that un-wraps your LLM's present
Chat models almost never emit what you asked for and nothing else. Ask one to "return only the prompt" and you get "Here is your enhanced prompt:" followed by a ```text code fence, or the prompt wrapped in <prompt>...</prompt> XML tags, or some other wrapper the model invented for politeness. Feed that straight into a CLIP Text Encode and the scaffolding becomes literal prompt tokens - the exact dirty-output failure mode that sinks naive LLM prompt-enhancer workflows. Pi Text Extractor is the regex cleaner that strips it.
It's the companion to Pi LLM Text, but it doesn't care where the text came from. Any STRING in, cleaned STRING out. It ships in the same pack, and - useful detail - it's pure Python, so you don't even need the Pi CLI installed to use just this node.
How it works
Give it the LLM's raw output in text and pick an extraction_mode:
auto(default) tries an XML tag first, then a code fence, then custom delimiters - first match winsxml_tagpulls from<prompt>...</prompt>(the tag name lives in thexml_tagfield, defaultprompt)code_fencepulls from triple-backtick blocks; leavefence_languageempty to match any language, or set e.g.textto only match ```text fencesbetween_delimitersuses your ownstart_delimiter/end_delimitermarkers
Under the hood it's a small set of regexes with occurrence picking the first or last match, and strip_whitespace (default on) trimming the result. The smart default is fail_if_missing = false: if nothing matches, you get the original text back rather than a broken graph - a stale prompt format won't kill your queue, it just quietly passes through. Flip it on if you'd rather get a loud error than silently bad text.
Two outputs come out: text (the cleaned string) and found (a BOOLEAN saying whether a wrapper was actually found). Wire found into a node that can branch on it if you want to catch the silent pass-through.
The pair that works
With Pi LLM Text, tell the model which wrapper to use:
Return only the final prompt inside <prompt>...</prompt> tags.
or:
Return only the final prompt in a ```text code fence.
Set xml_tag to prompt (already the default), connect the LLM node's text output here, and pipe this node's text into your CLIP Text Encode. If the LLM ever forgets the wrapper, fail_if_missing off means you still get something rather than a crash mid-batch.
Install
Same pack as the others - ComfyUI Manager (search "ComfyUI-Pi-LLM") or:
cd ComfyUI/custom_nodes
git clone https://github.com/felixowens/ComfyUI-Pi-LLM.git
Restart ComfyUI and it shows up under the Pi category. No model downloads, no Pi install, nothing heavier than ComfyUI's bundled Python. About the only thing that'll trip you up: if your custom delimiters look like regex metacharacters (say [[PROMPT]]), don't worry - the node escapes them for you. And if you ever get back your raw, unfiltered text when you expected a clean extract, check the found output first. That's the tell that the wrapper didn't match, not a bug.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | — | |
| extraction_mode | COMBO | auto | 4 options: auto, xml_tag, code_fence, between_delimiters |
| xml_tag | STRING | prompt | — |
| fence_language | STRING | — | |
| start_delimiter | STRING | — | |
| end_delimiter | STRING | — | |
| occurrence | COMBO | first | 2 options: first, last |
| strip_whitespace | BOOLEAN | true | — |
| fail_if_missing | BOOLEAN | false | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| text | STRING | — |
| found | BOOLEAN | — |