Nodes/ComfyUI_RS_NAI_API_Request/NAI Multi-Character Detailer
ComfyUI Node

NAI Multi-Character Detailer

NAICombinedFaceDetailerTest Is a Ghost Node — Your Old Workflow Just Hasn't Noticed

By raspie10032·Created about a year ago·Updated 2 days ago· 8
NAI Multi-Character Detailer
  • image
  • detectors
  • characterPrompts
  • tagger
  • vibes
  • references
  • nai_context
  • image
  • mask_visualization
  • matching_report
◄promptsmiling face, highly detailed►
◄negative_promptlowres, bad anatomy►
◄modelNAI Diffusion V5 Full►
◄strength0.55►
◄seed-1►
◄show_advancedfalse►
◄limit_opus_freetrue►
◄detail_modeall►
◄matching_modeshared►
◄match_min_score0.25►
◄match_min_margin0.08►
◄match_crop_factor2.0►
◄max_regions5►
◄normalize_vibe_strengthstrue►
◄save_formatPNG►
◄webp_quality90►
◄samplerk_euler►
◄steps28►
◄cfg_scale6.0►
◄schedulerkarras►
◄threshold0.30►
◄crop_factor3.0►
◄bbox_threshold0.30►
◄closingtrue►
◄fill_holestrue►
◄dilation8►
◄mask_feather8►
◄request_delay_seconds0.0►
◄use_context_settingstrue►
◄cfg_rescale0.00►
◄prefer_brownianfalse►
◄variety_boosttrue►
◄context_modeinherit_all►
◄override_promptfalse►
◄override_negative_promptfalse►
◄override_modelfalse►
◄override_samplerfalse►
◄override_stepsfalse►
◄override_cfg_scalefalse►
◄override_schedulerfalse►
◄override_cfg_rescalefalse►
◄override_prefer_brownianfalse►
◄override_variety_boostfalse►
◄override_characterPromptsfalse►

Here's the short version: NAICombinedFaceDetailerTest is not a node you go looking for. It's a compatibility shim - a subclass of the real thing, kept around so workflows and saved API graphs written against an earlier prototype still load and still run. The node menu calls it "NAI Multi-Character Detailer", exactly like the current node, so you can't tell them apart by looking at the canvas.

In the pack's __init__.py it's four lines of class definition with DEPRECATED = True and nothing else:

class NAICombinedFaceDetailerTest(NAIMultiCharacterDetailer):
    DEPRECATED = True

Because it's a plain subclass with no overrides, it inherits the entire current implementation. Same inputs, same outputs, same behaviour. There is no "test" logic left in it, and nothing you can do here that you can't do on NAIMultiCharacterDetailer.

Why it exists, and the trap it sets

The prototype workflows that shipped in version 2.8.0 and earlier used this class name. Rather than break every saved graph, the author kept the ID alive and wired it to the finished node. When you load one of those old workflows, the node IDs migrate to the stable names on load, custom titles survive, and links into the removed preview_only input are dropped along with the widget.

That removal is the actual trap. preview_only used to mean "detect and match, but don't call NovelAI" - a free way to check which face got assigned which character. It's gone, and the pack states flatly that running a migrated workflow now performs correction. The old flag no longer suppresses the request. If you queued a workflow you last used in June to check it still loads, you may also have just spent Anlas on it.

What it takes and what it gives you

The full schema is the current node's: image and a detectors bundle from the NAI Detection Combine Loader are required, along with prompt, negative_prompt, model, strength and seed. Optional inputs cover character matching (characterPrompts, tagger, matching_mode, match_min_score, match_min_margin), mask behavior (closing, fill_holes, dilation, mask_feather), context inheritance (nai_context, use_context_settings, context_mode, the override_* switches) and reference inputs. It returns image, mask_visualization and matching_report, in that order.

limit_opus_free still defaults to True, so a migrated workflow will usually stop at the guard rather than quietly billing you - but "usually" is doing real work in that sentence, and the check is a preflight, not a billing guarantee.

What to do about it

If you're building something new, don't add this node. Use NAI Multi-Character Detailer (NAIMultiCharacterDetailer). If you're opening an old workflow and want to modernize it, delete the old node and drop the current one in - the sockets are in the same order, so your existing image, detectors and tagger wires reconnect cleanly, and you'll gain the visible input set instead of a migrated legacy node nobody can see the origin of.

If you're driving the pack over the API, note the aliases are still registered in NODE_CLASS_MAPPINGS, so a POST that names NAICombinedFaceDetailerTest as the class will resolve and run. That's intentional backward compatibility, not a second feature.

Install

Shared with the pack, and required either way - this node can't run standalone:

cd ComfyUI/custom_nodes
git clone https://github.com/raspie10032/ComfyUI_RS_NAI_API_Request.git
python -m pip install -r ComfyUI_RS_NAI_API_Request/requirements.txt

You need ComfyUI-Impact-Pack and ComfyUI-Impact-Subpack for the detectors, a .env with NAI_ACCESS_TOKEN in the pack folder, and the optional tagger dependencies if you want automatic per-character matching. Restart ComfyUI after any update, then refresh the browser page - the localized labels and the execution notices are served to the frontend and won't appear until you do.

CategoryRS_NovelAI_API

Inputs (51)

NameTypeDefaultDescription
imageIMAGE—
detectorsNAI_DETECTION_BUNDLE—
promptSTRINGsmiling face, highly detailed—
negative_promptSTRINGlowres, bad anatomy—
modelCOMBONAI Diffusion V5 FullV5 Full Medium Effort always uses 14 steps, Euler Ancestral, zero CFG Rescale, and fixed Heavy Undesired Content. Custom base/character negative prompts are ignored. Prompt Guidance remains adjustable. Image-to-image and inpainting require limit_opus_free=False and can spend Anlas.
strengthFLOAT0.550–1—
seedINT-1-1–4294967295—
show_advancedoptBOOLEANfalse—
limit_opus_freeoptBOOLEANtrue—
detail_modeoptCOMBOall2 options: all, first
matching_modeoptCOMBOshared2 options: shared, wd14
characterPromptsoptLIST—
taggeroptRS_WD_TAGGER—
match_min_scoreoptFLOAT0.250.01–1—
match_min_marginoptFLOAT0.080.01–1—
match_crop_factoroptFLOAT2.01–5—
max_regionsoptINT51–64Maximum number of regions to process. Quality cannot be guaranteed as the number of processed regions increases.
vibesoptRS_NAI_VIBES—
referencesoptRS_NAI_REFERENCES—
normalize_vibe_strengthsoptBOOLEANtrueV4/V4.5 Vibe: scale strengths down if their absolute sum exceeds 1.0.
save_formatoptCOMBOPNGAutosave format. Preserves NovelAI generation information. No ComfyUI workflow is embedded.
webp_qualityoptINT901–100Used only for lossy WebP. Lossless WebP preserves pixels.
sampleroptCOMBOk_euler7 options: k_dpmpp_2m, k_dpmpp_sde, k_dpmpp_2m_sde, k_dpmpp_2s_ancestral, k_euler_ancestral, k_euler, +1
stepsoptINT281–50—
cfg_scaleoptFLOAT6.00–30—
scheduleroptCOMBOkarras4 options: native, karras, exponential, polyexponential
thresholdoptFLOAT0.300–1—
crop_factoroptFLOAT3.01–10—
bbox_thresholdoptFLOAT0.300–1—
closingoptBOOLEANtrueFill small notches before dilation.
fill_holesoptBOOLEANtrueFill enclosed holes within the repair limits, before dilation.
dilationoptINT80–128Extra editing room in original-image pixels, after hole/notch filling.
mask_featheroptINT80–64Blend inside the expanded mask. Separate from crop context and dilation.
nai_contextoptNAI_CONTEXTConnect the previous NAI generation context. Carries prompts, characters and generation settings; seed, size, strength, references and Anlas protection stay local.
request_delay_secondsoptFLOAT0.00–3600Wait before each NovelAI request, including each detail region and uncached Vibe encoding. 0 adds no delay. The built-in 2-second gap overlaps this timer; a longer server retry wait still applies. Preview-only runs do not wait. Stop cancels the countdown.
use_context_settingsoptBOOLEANtrueOn: inherit prompts, characters, model and sampling settings from connected NAI context. Off: use this node's manual values. Both modes perform NovelAI correction; the seed stays local.
cfg_rescaleoptFLOAT0.000–1—
prefer_brownianoptBOOLEANfalse—
variety_boostoptBOOLEANtrue—
context_modeoptCOMBOinherit_allWith context enabled, inherit everything or replace only checked fields with this node's values. Unchecked fields still come from context.
override_promptoptBOOLEANfalseUse this node's prompt in override_selected mode. An empty string, zero or False is an intentional replacement.
override_negative_promptoptBOOLEANfalseUse this node's negative_prompt in override_selected mode. An empty string, zero or False is an intentional replacement.
override_modeloptBOOLEANfalseUse this node's model in override_selected mode. An empty string, zero or False is an intentional replacement.
override_sampleroptBOOLEANfalseUse this node's sampler in override_selected mode. An empty string, zero or False is an intentional replacement.
override_stepsoptBOOLEANfalseUse this node's steps in override_selected mode. An empty string, zero or False is an intentional replacement.
override_cfg_scaleoptBOOLEANfalseUse this node's cfg_scale in override_selected mode. An empty string, zero or False is an intentional replacement.
override_scheduleroptBOOLEANfalseUse this node's scheduler in override_selected mode. An empty string, zero or False is an intentional replacement.
override_cfg_rescaleoptBOOLEANfalseUse this node's cfg_rescale in override_selected mode. An empty string, zero or False is an intentional replacement.
override_prefer_brownianoptBOOLEANfalseUse this node's prefer_brownian in override_selected mode. An empty string, zero or False is an intentional replacement.
override_variety_boostoptBOOLEANfalseUse this node's variety_boost in override_selected mode. An empty string, zero or False is an intentional replacement.
override_characterPromptsoptBOOLEANfalseReplace the complete character list with characterPrompts, including negatives and positions. No connection clears the list.

Outputs (3)

NameTypeDescription
imageIMAGE—
mask_visualizationIMAGE—
matching_reportSTRING—