Nodes/Prompt PostProcessor/ACB Prompt Post Processor
ComfyUI Node

ACB Prompt Post Processor

The prompt node that hides a tiny programming language

By acorderob·Created 3 years ago·Updated 11 days ago· 54
ACB Prompt Post Processor
  • model
  • wc_options
  • stn_options
  • cup_options
  • en_options
  • rm_options
  • pos_prompt
  • neg_prompt
  • variables
pos_prompt
neg_prompt
modelname(none)
seed-1
debug_levelminimal
on_warningswarn
strict_operatorstrue
process_wildcardstrue
do_cleanuptrue
cleanup_variablestrue
results_file
run_modesingle

This is the node that makes you question whether you're writing a prompt or scripting. ACB Prompt Post Processor takes your positive and negative prompt as plain text and rewrites both before they ever reach the CLIP encoder: it expands wildcards, rolls choices, moves chunks of the positive into the negative, swaps LoRAs by model family, and can even run a whole batch of every combination. It's the ComfyUI face of Prompt PostProcessor (PPP), the pack by acorderob that started life in 2023 as sd-webui-sendtonegative and has been quietly maintained ever since. If you're still living in the A1111 wildcard world but working in ComfyUI, this is the bridge.

How it works

The node parses both prompt boxes with a real grammar (lark, if you care) and walks them left to right. Wildcards use the Dynamic Prompts formats - __hair_colors__ and {this|that} both work, with extras like weighted choices and filters. Its own commands look like <>-tags with a ppp: prefix: <ppp:if _is_sdxl>...<ppp:/if> for conditional content, <ppp:set var>...<ppp:/set> to stash a value, <ppp:stn>content<ppp:/stn> to send content to the negative, and <ppp:ext $lora name/> for model-aware LoRA loading. The output isn't one string - it's processed text plus a dictionary of every variable that got set, which is where a lot of the power lives.

To make the _is_* model variables work, it needs to know what's loaded. Pass a MODEL (or a model class name as text) into model, and set modelname to the checkpoint's relative path. If you give it only the filename it tries to detect the class from the file itself. Skip both and it warns you and runs without model awareness - fine for plain wildcard rolls, useless for conditional prompts.

The inputs that actually matter

  • pos_prompt / neg_prompt - the raw text. Paste your wildcards and commands here.
  • seed - drives the wildcard/choice picks; -1 randomizes. The value actually used lands in the _input_seed output variable.
  • model / modelname - the model-awareness pair above.
  • process_wildcards - on by default. Turn it off if another extension should do the rolling.
  • do_cleanup - strips the leftover cruft (double commas, dead parentheses) after processing. Leave it on.
  • do_combinatorial - the dangerous one. Enables combinatorial mode where the node returns every combination of your choices/wildcards. combinatorial_limit (default 100) caps it. The docs warn for good reason: a few constructs can explode into thousands of generations. combinatorial_shuffle randomizes the order if you want variety before the cap hits.

Outputs

Three outputs, all lists (ComfyUI runs each element sequentially): pos_prompt, neg_prompt, and variables - a PPP_DICT of everything your prompt set, which you can feed into the ACB PPP Select Variable node or chain into detailer prompts.

Installing it

Grab it via ComfyUI Manager (Custom Nodes Manager → search "Prompt PostProcessor") or:

cd ComfyUI/custom_nodes
git clone https://github.com/acorderob/sd-webui-prompt-postprocessor

Then restart ComfyUI. Dependencies are light - lark, numpy, ruamel.yaml, pydantic - and there are no model downloads. It's MIT-licensed and cross-platform (A1111, Forge, SD.Next, ComfyUI), though on A1111 the README warns it must load after other prompt extensions - rename the folder with a z prefix if yours gets overwritten.

Where people get burned

First, ComfyUI doesn't natively support A1111's BREAK, AND, alternation, or scheduling - PPP converts brackets to parentheses and turns AND/BREAK into commas by default, so those tricks silently degrade unless you add nodes like ComfyUI_smZNodes. Second, missing model info: the log nags you with "Model class was not provided nor detected" when you skip model/modelname, and every condition then evaluates against nothing. Third, combinatorial mode. Start with a limit of 1, check the "Estimated combinations" line in the log, then raise it. Fourth - the unglamorous one - remember that on distilled models at CFG 1 the negative prompt is math-multiplied by zero, so all the stn cleverness does nothing there. On SDXL-lineage it's very much alive.

If the node refuses to fire every time (it forces re-execution because wildcard files can change between runs - that's by design), that's IS_CHANGED returning NaN, not a bug.

CategoryACB

Inputs (18)

NameTypeDefaultDescription
pos_promptSTRINGPositive prompt to process
neg_promptSTRINGNegative prompt to process
modeloptMODEL,STRINGModel or model class name. Optional if you set modelname.
modelnameoptCOMBO(none)Relative path of the model. Needed to detect variants.
seedoptINT-1Seed value for the prompt processing (use -1 for random)
debug_leveloptCOMBOminimalDebug level
on_warningsoptCOMBOwarnHow to handle invalid content warnings
strict_operatorsoptBOOLEANtrueUse strict operators
process_wildcardsoptBOOLEANtrueProcess wildcards in the prompt
do_cleanupoptBOOLEANtrueDo a cleanup of the prompt
cleanup_variablesoptBOOLEANtrueDo a cleanup of the output variables
results_fileoptSTRINGFilename to save processing results. Supports %datetime%, %date%, %time%, %host% tokens. Empty = disabled.
run_modeoptCOMBOsingleRun mode
wc_optionsoptPPP_OPTIONS_WCWildcard processing options
stn_optionsoptPPP_OPTIONS_STNSend-To-Negative options
cup_optionsoptPPP_OPTIONS_CUPCleanup options
en_optionsoptPPP_OPTIONS_ENExtraNetworks mapping options
rm_optionsoptPPP_OPTIONS_RMRun mode options

Outputs (3)

NameTypeDescription
pos_promptSTRINGProcessed positive prompt (list of prompts if combinatorial/multiple mode is enabled)
neg_promptSTRINGProcessed negative prompt (list of prompts if combinatorial/multiple mode is enabled)
variablesPPP_DICTOutput variables (list of dictionaries if combinatorial/multiple mode is enabled)