Files
ComfyAssets-ComfyUI_PromptM…/web/js/inspection-semantics.json
T
Vito a0fc5171e3 fix(inspector): pass text through unknown nodes instead of refusing them (#381) (#383)
* fix(inspector): pass text through unknown nodes instead of refusing them (#381)

The inspector refused any node class missing from the semantics table, so a
PromptManagerPair behind an rgthree Any Switch showed "Prompt uses a node the
inspector does not support". The inspection resolver (Python and browser) now
reads through unknown nodes: a text input is the text, positive/negative route
by output slot, a conditioning input is followed alone, otherwise every linked
input except core type inputs (pass_through.skip_inputs). PromptManager nodes
are authoritative; several different texts become one candidate each
("Several prompts reach the sampler"). A seeded text node with no conditioning
input is generated at run time, and a recorded PromptManager execution is not
checked against text that passed through an unknown node.

INSPECTION_RESOLVER_VERSION goes to 2; ingestion keeps the default profile.
A legacy parity gate records every committed graph whose inspection positive
matches the legacy parser's; no graph may leave it.

* fix(inspector): keep recorded pair text, string-only seed rule, role inputs and unique candidates (#381)

Review of the pass-through: a walk through an unknown node never overrides a
PromptManagerPair's execution record (any outcome but work-limit is
unverifiable while the record is checked); the run-time seed rule reads only
string outputs; a node with positive/negative inputs follows only the role of
the requested slot, nothing when it is unlinked; one text offered twice is one
candidate.

* fix(inspector): anchor on the saver that wrote the file and resolve stages on shared links (#381)

An inspected file's name now anchors the inspection on the one saver whose
filename_prefix (literal or traced) makes the file's stem <prefix>_<digits>[_];
the samplers in that saver's image ancestry are the candidates. No match,
several matches or an unreadable walk anchor nothing, so the file stays
"several possible prompts". In a latent walk, an earlier sampler reading the
same conditioning links as the later one is the same prompt, not an
unattributed stage. Python and the browser resolver behave the same; the
legacy parity gate states each graph that differs from legacy on purpose.

* fix(inspector): skip only plain first stages on shared links; an unfinished prefix scan anchors nothing (#381)

Review of the saver anchor: a same-links earlier stage is skipped only when it
is not a detailer, sets no prompt override and continues no other sampler, so
an earlier prompt or override behind it is never hidden. A work limit while
tracing a saver prefix ends the match scan without an anchor instead of
counting that saver as no match.

* test(inspector): cover every plain-first-stage outcome on both resolvers (#381)

The frontend coverage gate found local-resolver-stages.mjs branches at 92.44%
(< 93). Each way an earlier stage stops being a plain first stage (no latent,
literal, missing or cyclic latent, a sampler-shaped node, a detailer) is now a
resolver test and an anchor-first-stage-* parity vector.
2026-10-27 16:56:37 +00:00

308 lines
12 KiB
JSON

{
"schema": 1,
"samplers": {
"KSampler": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent_image",
"facts": "ksampler"
},
"KSamplerAdvanced": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent_image",
"facts": "ksampler"
},
"SamplerCustom": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent_image",
"facts": "custom"
},
"SamplerCustomAdvanced": {
"strategy": "custom-advanced",
"conditioning": { "guider": "guider" },
"latent": "latent_image",
"facts": "custom-advanced"
},
"FaceDetailer": {
"strategy": "detailer-stage",
"conditioning": { "positive": "positive", "negative": "negative" },
"image_stage": "image",
"facts": "ksampler",
"prompt_overrides": ["wildcard"]
},
"DetailerForEach": {
"strategy": "detailer-stage",
"conditioning": { "positive": "positive", "negative": "negative" },
"image_stage": "image",
"facts": "ksampler",
"prompt_overrides": ["wildcard"]
},
"UltimateSDUpscale": {
"strategy": "detailer-stage",
"conditioning": { "positive": "positive", "negative": "negative" },
"image_stage": "image",
"facts": "ksampler"
},
"UltimateSDUpscaleNoUpscale": {
"strategy": "detailer-stage",
"conditioning": { "positive": "positive", "negative": "negative" },
"image_stage": "upscaled_image",
"facts": "ksampler"
},
"ClownsharKSampler_Beta": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent_image",
"facts": "ksampler",
"prompt_overrides": ["options"],
"fact_overrides": ["options", "sigmas"]
},
"KSampler (Efficient)": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent_image",
"facts": "ksampler",
"prompt_overrides": ["script"],
"fact_overrides": ["script"]
},
"ttN KSampler_v2": {
"strategy": "ksampler",
"conditioning": { "positive": "positive", "negative": "negative" },
"latent": "latent",
"facts": "ksampler",
"prompt_overrides": ["adv_xyPlot"],
"fact_overrides": ["adv_xyPlot"]
}
},
"guiders": {
"CFGGuider": { "strategy": "cfg", "positive": "positive", "negative": "negative" },
"BasicGuider": {
"strategy": "basic",
"positive": "conditioning",
"absent_reason": "Guider has no negative input"
}
},
"conditioning": [
{ "class": "FluxGuidance", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ReferenceLatent", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ConditioningSetArea", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ConditioningSetAreaPercentage", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ConditioningSetAreaStrength", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ConditioningSetMask", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ConditioningSetTimestepRange", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ControlNetApply", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ControlNetApplyAdvanced", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "ControlNetApplyAdvanced", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "ControlNetApplySD3", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "ControlNetApplySD3", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "InpaintModelConditioning", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "InpaintModelConditioning", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "WanImageToVideo", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "WanImageToVideo", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "ControlNetInpaintingAliMamaApply", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "ControlNetInpaintingAliMamaApply", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "LTXVConditioning", "slot": 0, "strategy": "passthrough", "input": "positive" },
{ "class": "LTXVConditioning", "slot": 1, "strategy": "passthrough", "input": "negative" },
{ "class": "FluxKontextMultiReferenceLatentMethod", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "SeedVarianceEnhancer", "slot": 0, "strategy": "passthrough", "input": "conditioning" },
{ "class": "ApplyInstantIDAdvanced", "slot": 1, "strategy": "passthrough", "input": "positive" },
{ "class": "ApplyInstantIDAdvanced", "slot": 2, "strategy": "passthrough", "input": "negative" },
{ "class": "ConditioningZeroOut", "slot": 0, "strategy": "zeroed", "input": "conditioning" }
],
"selectors": {
"easy ifElse": {
"strategy": "boolean-select",
"condition": "boolean",
"branches": { "true": "on_true", "false": "on_false" }
},
"Switch conditioning [Crystools]": {
"strategy": "boolean-select",
"condition": "boolean",
"branches": { "true": "on_true", "false": "on_false" }
}
},
"composites": {
"ConditioningCombine": { "strategy": "combine", "inputs": ["conditioning_1", "conditioning_2"], "additive": true },
"ConditioningConcat": { "strategy": "combine", "inputs": ["conditioning_to", "conditioning_from"], "additive": true },
"ConditioningAverage": { "strategy": "combine", "inputs": ["conditioning_to", "conditioning_from"] }
},
"encoders": [
{ "class": "CLIPTextEncode", "slot": 0, "strategy": "single", "inputs": ["text"] },
{ "class": "CLIPTextEncodeSDXL", "slot": 0, "strategy": "parts-equal", "inputs": ["text_g", "text_l"] },
{ "class": "CLIPTextEncodeFlux", "slot": 0, "strategy": "parts-equal", "inputs": ["clip_l", "t5xxl"] },
{ "class": "CLIPTextEncodeSD3", "slot": 0, "strategy": "parts-equal", "inputs": ["clip_l", "clip_g", "t5xxl"] },
{ "class": "TextEncodeQwenImageEdit", "slot": 0, "strategy": "single", "inputs": ["prompt"] },
{ "class": "TextEncodeQwenImageEditPlus", "slot": 0, "strategy": "single", "inputs": ["prompt"] },
{ "class": "TextEncodeQwenImage21", "slot": 0, "strategy": "single", "inputs": ["prompt"] },
{ "class": "TextEncodeQwenImage21", "slot": 1, "strategy": "single", "inputs": ["negative_prompt"] },
{ "class": "KikoTextEncode", "slot": 0, "strategy": "single", "inputs": ["text"] },
{ "class": "Text to Conditioning", "slot": 0, "strategy": "single", "inputs": ["text"] },
{
"class": "smZ CLIPTextEncode",
"slot": 0,
"strategy": "flag-parts",
"inputs": ["text", "text_g", "text_l"],
"params": { "flag": "with_SDXL" }
}
],
"strings": [
{ "class": "StringConstant", "slot": 0, "strategy": "literal", "inputs": ["string"] },
{ "class": "TextInput", "slot": 0, "strategy": "literal", "inputs": ["text"] },
{ "class": "DisplayText", "slot": 0, "strategy": "literal", "inputs": ["text"] },
{ "class": "ttN text", "slot": 0, "strategy": "literal", "inputs": ["text"] },
{ "class": "CR Text", "slot": 0, "strategy": "literal", "inputs": ["text"] },
{ "class": "CR Prompt Text", "slot": 0, "strategy": "literal", "inputs": ["prompt"] },
{ "class": "TextBoxMira", "slot": 0, "strategy": "literal", "inputs": ["text"] },
{
"class": "StringConstantMultiline",
"slot": 0,
"strategy": "strip-newlines",
"inputs": ["string"],
"params": { "flag": "strip_newlines" }
},
{
"class": "JoinStringMulti",
"slot": 0,
"strategy": "join-multi",
"inputs": ["string_1"],
"params": {
"count": "inputcount",
"delimiter": "delimiter",
"list_flag": "return_list",
"input_prefix": "string_"
}
}
],
"runtime": ["PromptSearchList", "TriggerWord Toggle (LoraManager)"],
"savers": {
"SaveImage": {
"strategy": "comfy-counter",
"prefix_input": "filename_prefix",
"image_input": "images",
"pattern": "{name}_{counter:05}_.{ext}"
},
"SaveAnimatedWEBP": {
"strategy": "comfy-counter",
"prefix_input": "filename_prefix",
"image_input": "images",
"pattern": "{name}_{counter:05}_.{ext}"
},
"SaveAnimatedPNG": {
"strategy": "comfy-counter",
"prefix_input": "filename_prefix",
"image_input": "images",
"pattern": "{name}_{counter:05}_.{ext}"
},
"SaveVideo": {
"strategy": "comfy-counter",
"prefix_input": "filename_prefix",
"image_input": "video",
"pattern": "{name}_{counter:05}_.{ext}"
},
"SaveWEBM": {
"strategy": "comfy-counter",
"prefix_input": "filename_prefix",
"image_input": "images",
"pattern": "{name}_{counter:05}_.{ext}"
},
"VHS_VideoCombine": {
"strategy": "vhs-counter",
"prefix_input": "filename_prefix",
"image_input": "images",
"pattern": "{name}_{counter:05}.{ext}"
}
},
"non_file_outputs": ["PreviewImage", "PreviewAny", "SaveImageWebsocket", "Image Comparer (rgthree)"],
"lineage": [
{ "class": "VAEDecode", "slot": 0, "strategy": "continue", "input": "samples" },
{ "class": "VAEDecodeTiled", "slot": 0, "strategy": "continue", "input": "samples" },
{ "class": "VAEEncode", "slot": 0, "strategy": "continue", "input": "pixels" },
{ "class": "VAEEncodeTiled", "slot": 0, "strategy": "continue", "input": "pixels" },
{ "class": "ImageUpscaleWithModel", "slot": 0, "strategy": "continue", "input": "image" },
{ "class": "ImageScale", "slot": 0, "strategy": "continue", "input": "image" },
{ "class": "ImageScaleBy", "slot": 0, "strategy": "continue", "input": "image" },
{ "class": "ImageScaleToTotalPixels", "slot": 0, "strategy": "continue", "input": "image" },
{ "class": "LatentUpscale", "slot": 0, "strategy": "continue", "input": "samples" },
{ "class": "LatentUpscaleBy", "slot": 0, "strategy": "continue", "input": "samples" },
{ "class": "Image Filter", "slot": 0, "strategy": "continue", "input": "images" },
{ "class": "Image Filter", "slot": 1, "strategy": "continue", "input": "latents" }
],
"stage_inputs": {
"shaped": [
"latent_image",
"guider",
"positive",
"negative",
"pipe",
"basic_pipe",
"detailer_pipe",
"sampler",
"sigmas",
"noise",
"text_embeds",
"hyvid_embeds"
],
"with_model": ["conditioning", "neg_conditioning", "samples", "latent"]
},
"pass_through": {
"skip_inputs": [
"model",
"clip",
"vae",
"clip_vision",
"clip_vision_output",
"control_net",
"style_model",
"upscale_model",
"image",
"images",
"pixels",
"mask",
"latent",
"latent_image",
"samples",
"noise",
"sampler",
"sigmas",
"guider"
]
},
"facts": {
"configuration_outputs": {
"RandomNoise": { "kind": "noise", "fields": ["noise_seed"] },
"KSamplerSelect": { "kind": "sampler", "fields": ["sampler_name"] },
"BasicScheduler": { "kind": "sigmas", "fields": ["steps", "scheduler"] },
"Flux2Scheduler": { "kind": "sigmas", "fields": ["steps"], "type_fields": ["scheduler"] },
"CFGGuider": { "kind": "guider", "fields": ["cfg", "model"] },
"BasicGuider": { "kind": "guider", "fields": ["model"] }
},
"model_outputs": {
"CheckpointLoader": "ckpt_name",
"CheckpointLoaderSimple": "ckpt_name",
"unCLIPCheckpointLoader": "ckpt_name",
"UNETLoader": "unet_name"
},
"model_passthroughs": [
"LoraLoader",
"LoraLoaderModelOnly",
"ModelSamplingFlux",
"ModelSamplingAuraFlow",
"ModelSamplingSD3",
"Lora Loader (LoraManager)",
"Power Lora Loader (rgthree)",
"ModelPatchTorchSettings",
"CFGNorm",
"PerturbedAttentionGuidance",
"CR Apply LoRA Stack"
],
"scalar_outputs": {
"PrimitiveInt": "number",
"PrimitiveFloat": "number",
"PrimitiveString": "string",
"PrimitiveStringMultiline": "string"
}
}
}