Custom Selector
' token in your prompt picks the whole closeup/medium/wide preset
- matched_weight
- matched_start
- matched_end
- matched_denoise
- cleaned_string
- matched_keyword
- image_url
If you've ever loaded a portrait workflow where the prompt contains something like crop:closeup and every downstream number magically matches the shot type, this node is doing that work. Its display name is the generic "Custom Selector," but the name undersells it in the most useful way possible: it's not a wildcard picker, it's a lookup table with string parsing glued on. It calls no API, needs no key, and loads no model - the entire pack is one ~100-line Python file that scans your text for a crop: token and spits back four floats, a cleaned string, and a reference-image URL.
Why you'd reach for it
This is plumbing, pure and simple - it never touches pixels. But it's plumbing with a very specific shape. In the crop-zoom/inpaint family of workflows (see the crop-edit-stitch pattern in the inpainting knowledge doc), the difference between "wide shot," "medium," and "closeup" usually means three different sets of numbers: how hard the prompt should weigh in, when in the schedule the pass starts and ends, and how much denoise that pass gets. Most people hardcode those in the graph or fiddle with three KSamplers by hand. This node collapses the whole decision into a token you type into your prompt. Hand your text box crop:wide, <character>, golden hour and the node answers "wide" with the weight/start/end/denoise recipe you configured for it.
How it works
The mechanism is dead simple. It lowercases input_string, then looks for the literal tokens crop:medium, crop:wide, and crop:closeup. First match wins - and here's the gotcha: match priority is hardcoded to medium → wide → closeup, not "first token in the string." If your text contains crop:wide crop:closeup, medium still isn't matched (neither token is medium), but if crop:medium appears anywhere, it wins even if crop:closeup came earlier in the sentence. The matched token is stripped from the text so your actual prompt doesn't carry it, giving you cleaned_string.
Then it checks the comma-separated triggerwords list against the text with word boundaries. The defaults - michipeklo,chrishnsk,renehundertpfund,mikegasparik - are the author's own Civitai model trigger words - almost certainly his, given one of them is literally his name. On a hit it sets matched_keyword and builds image_url pointing at a hardcoded Supabase storage bucket.
The inputs that matter
You mostly set three things:
input_string- the text to scan. Wire it from your prompt or a text node.triggerwords- your own comma-separated keyword list. Replace the defaults unless you actually use those creators' models.- The three
weight_*/start_at_*/end_at_*/denoise_*groups - one recipe per crop level. Defaults are weight 0.5, start 0, end 1, denoise 0.2; tune the denoise per shot.
clear_string is a boolean that, when on, empties cleaned_string entirely - handy if you want the token and the original text dropped.
What comes out and where it wires
Seven outputs, all scalar: matched_weight, matched_start, matched_end, matched_denoise, cleaned_string, matched_keyword, and image_url. Wire matched_denoise into a KSampler (convert the denoise widget to input first), feed matched_start/matched_end to whatever schedule or attention node your zoom pipeline uses, and matched_weight into your conditioning weight. image_url goes to whatever URL-loader node you use for reference images.
Installing it
ComfyUI Manager → search comfy-customselector → install → restart. Or the manual route:
cd ComfyUI/custom_nodes
git clone https://github.com/gasparuff/comfy-customselector
Restart ComfyUI. That's genuinely it - there's no requirements.txt, no models to download, and the only Python import is the standard library's re.
Gotchas
The big one: image_url is hardcoded to the author's Supabase bucket, with a file path derived from your matched keyword. Use it with your own trigger words and you'll get a 404 unless you happen to host a face image at that exact URL yourself. And remember the medium-over-wide-over-closeup priority - write only one crop: token per prompt, or you'll be debugging why "closeup" lost to an earlier crop:medium.
Honest verdict: this is a personal tool tuned for one workflow, and it shows - no README, no tooltips, zero community footprint. But if you're building a crop/zoom face pipeline, the pattern is worth stealing: a token in the prompt that fans out into a full numeric recipe. Adapt the trigger words, fork the URL logic, and it's a neat little switchboard.
Inputs (15)
| Name | Type | Default | Description |
|---|---|---|---|
| input_string | STRING | — | |
| triggerwords | STRING | michipeklo,chrishnsk,renehundertpfund,mikegasparik | — |
| weight_closeup | FLOAT | 0.50 | — |
| weight_medium | FLOAT | 0.50 | — |
| weight_wide | FLOAT | 0.50 | — |
| start_at_closeup | FLOAT | 0.00 | — |
| start_at_medium | FLOAT | 0.00 | — |
| start_at_wide | FLOAT | 0.00 | — |
| end_at_closeup | FLOAT | 1.00 | — |
| end_at_medium | FLOAT | 1.00 | — |
| end_at_wide | FLOAT | 1.00 | — |
| denoise_closeup | FLOAT | 0.20 | — |
| denoise_medium | FLOAT | 0.20 | — |
| denoise_wide | FLOAT | 0.20 | — |
| clear_string | BOOLEAN | false | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| matched_weight | FLOAT | — |
| matched_start | FLOAT | — |
| matched_end | FLOAT | — |
| matched_denoise | FLOAT | — |
| cleaned_string | STRING | — |
| matched_keyword | STRING | — |
| image_url | STRING | — |