Custom node pack for ComfyUI.
- PhoenixRandomCSVTextReplace — replaces consecutive placeholders ($1, $2, ...) in a text with a randomly chosen term from a CSV candidate list (one line per placeholder). Ported from comfyui-text-placeholder-randomizer, whose
RandomCSVTextReplacenode continues to exist independently.- By default, lines are independent — the same term can be drawn more than once.
unique(bool): when enabled, prevents a term from being drawn for more than one placeholder in a given run (across lines).- Fine-grained control per line: add the field
_UNIQUE_to a CSV line to make only that line (or lines) mutually unique — independent of theuniquebool. The keyword is removed from the candidate list before selection, so it can never be picked as a value itself. It only has an effect between multiple lines marked this way (with only one marked line, there is nothing for it to be distinct from). If all candidates for a unique line are already taken, it still draws from the full list (repetition instead of an unresolved placeholder). - If a line contains only the field
_NONE_(e.g. line 5 =_NONE_), the corresponding placeholder ($5) is removed from the output entirely instead of being replaced by a term. - A candidate can carry a weight by including a number between two underscores, e.g.
red, _2_ green, _0.1_ blue—greenis picked twice as often asred,blueonly a tenth as often asred(default weight is 1). The_NUMBER_token is stripped from the term before use.
- PhoenixSaveText — saves standalone text using the same
filename_prefixscheme (including%date%placeholders, subfolders) and auto-counter logic asSave Image. The counter is based only on its own.txthistory — for text that must guaranteedly get the same number as an associated image, use PhoenixSaveImageAndText instead (see below). - PhoenixSaveImageAndText — saves images together with up to two optional accompanying texts (e.g. captions) using the same scheme as
Save Image. All files share a single counter computed within this one function call, e.g.AAA/myImage_00023_.png+AAA/myImage_00023_.txt— guaranteeing they stay in sync regardless of how the rest of the graph is wired. (Two separate Save Image / Save Text nodes both fed directly from the same image source have no enforced execution order relative to each other — depending on which runs first, the number can shift by one. Hence this combined node when image and text belong together.)textis optional — left unconnected, only the image is saved, no.txt.text2(optional) — a second, independent text (e.g. an alternate caption variant); left unconnected, it isn't saved. The filename usestext2_postfix(default"2") as a suffix before the extension, e.g.AAA/myImage_00023_2.txt.path(optional) completely overridesfilename_prefix/counter: a full path without extension, e.g. from another instance of this node. The image is saved as<path>.png,text(if given) as<path>.txt,text2(if given) as<path><text2_postfix>.txt. This makes it usable outside the ComfyUI output folder too (e.g. writing directly into a training dataset).- The
pathoutput produces exactly the format expected by another instance of this node'spathinput — for chaining multiple Save nodes onto the same path.
- PhoenixAppendText — appends a fixed text field to an incoming string and outputs the result.
- PhoenixLoadText — loads a
.txtfile via a path with wildcards (*,?,[seq],**for recursive), e.g.input/random/random*.txt. Relative paths are resolved against the ComfyUI root; matches are sorted alphabetically.index:-1= pick a random match (viaseed),0= take the first match,>0= the match at this position (1= second match, ...).seed+control_after_generate: same as KSampler — only used whenindex = -1.alternative_text(optional, default empty) — output used fortextwhen no file could be loaded, instead of an empty string.loaded(bool output) —trueif the text came from a file,falseifalternative_textwas used instead.preview: read-only widget showing the loaded text, or "No Text found" plus a reason when there's no match (no path, no match, index out of range, file not readable), noting that the alternative text was used.
- Create a new file (e.g.
my_node.py) with the node class — at minimumINPUT_TYPES,RETURN_TYPES,FUNCTION,CATEGORY— plus its ownNODE_CLASS_MAPPINGS/NODE_DISPLAY_NAME_MAPPINGSat the end of the file. - Import the file in
__init__.pyand merge its mappings intoNODE_CLASS_MAPPINGS/NODE_DISPLAY_NAME_MAPPINGS({**a.NODE_CLASS_MAPPINGS, **b.NODE_CLASS_MAPPINGS}). - Restart ComfyUI.
WEB_DIRECTORY = "js" is active; .js files in the js/ folder are loaded automatically (see random_csv_text_replace_preview.js for the preview widget of PhoenixRandomCSVTextReplace).
Only add to requirements.txt when truly necessary — all node packs share Stability Matrix's ComfyUI venv, see requirements.txt for details on today's NumPy/numba update conflict.
pyproject.toml is prepared for the Comfy Registry (comfy node publish via comfy-cli). Adjust PublisherId and the repository URL before publishing.