feat(inspect): port legacy parser rules the new resolver missed (installed nodes)
R6 and R9 for nodes whose sources are installed beside ComfyUI, each entry's input names and output slots read from the node's code (the task report lists file and line): - detailer stages UltimateSDUpscale (image), UltimateSDUpscaleNoUpscale (upscaled_image) and DetailerForEach (image), judged with their upstream samplers like FaceDetailer; - pass-throughs ControlNetInpaintingAliMamaApply and LTXVConditioning (positive 0, negative 1) and FluxKontextMultiReferenceLatentMethod; - encoder Text to Conditioning, strings TextInput and DisplayText; - facts model pass-throughs Lora Loader (LoraManager), Power Lora Loader (rgthree), ModelPatchTorchSettings, CFGNorm, PerturbedAttentionGuidance. Impact Pack encodes a detailer's non-empty wildcard instead of its positive input, so FaceDetailer and DetailerForEach now list it as a prompt override: a literal wildcard is decided at run time and a linked one names its source, instead of resolving to the positive input. The overwritten PromptManager refusal (R1) still holds behind the new pass-throughs. The default profile does not read the table.
This commit is contained in:
@@ -54,6 +54,7 @@ SAVER_PATTERNS = MappingProxyType(
|
||||
"vhs-counter": "{name}_{counter:05}.{ext}",
|
||||
}
|
||||
)
|
||||
_SAMPLER_OPTIONS = frozenset({"prompt_overrides"})
|
||||
_CONFIGURATION_KINDS = frozenset({"noise", "sampler", "sigmas", "guider"})
|
||||
_SCALAR_KINDS = frozenset({"number", "string"})
|
||||
_TYPE_FIELDS = frozenset({"type_fields"})
|
||||
@@ -177,9 +178,13 @@ def _check_sampler(entry: dict, strategy: str, where: str) -> None:
|
||||
entry,
|
||||
where,
|
||||
frozenset({"strategy", "conditioning", stage, "facts"}),
|
||||
frozenset(),
|
||||
_SAMPLER_OPTIONS,
|
||||
)
|
||||
_name(entry[stage], where)
|
||||
# Inputs that, when set, replace the prompt the sampler's conditioning
|
||||
# inputs carry (a detailer's wildcard); the prompt is then not read.
|
||||
if "prompt_overrides" in entry:
|
||||
_names(entry["prompt_overrides"], where + ".prompt_overrides")
|
||||
keys = {"guider"} if strategy == "custom-advanced" else {"positive", "negative"}
|
||||
conditioning = entry["conditioning"]
|
||||
_fields(conditioning, where + ".conditioning", frozenset(keys), frozenset())
|
||||
|
||||
@@ -1241,6 +1241,7 @@ class _GraphResolver:
|
||||
try:
|
||||
name, inputs = self.node(sampler_id)
|
||||
entry = self.sampler_entry(name)
|
||||
self.check_overrides(sampler_id, entry, inputs)
|
||||
# A second sampler in the latent ancestry denotes a multistage run;
|
||||
# associating the final image with one prompt pair would be a guess.
|
||||
latent = entry.get("latent")
|
||||
@@ -1284,6 +1285,21 @@ class _GraphResolver:
|
||||
node=error.node,
|
||||
)
|
||||
|
||||
def check_overrides(self, sampler_id: str, entry: Mapping, inputs: dict) -> None:
|
||||
"""A set prompt override replaces the conditioning inputs' prompt.
|
||||
|
||||
Exact ``""`` (or a missing input) leaves the prompt alone. A literal is
|
||||
processed at run time (a detailer wildcard); a link is a source the
|
||||
inspector does not follow, so it is named.
|
||||
"""
|
||||
for name in entry.get("prompt_overrides", ()):
|
||||
value = inputs.get(name)
|
||||
if value is None or value == "":
|
||||
continue
|
||||
if _link(value):
|
||||
raise self.unsupported("Unsupported prompt override", str(value[0]))
|
||||
raise self.named(_RUNTIME_REASON, "runtime-value", sampler_id)
|
||||
|
||||
def latent_source(self, value: Any, seen: set, depth: int) -> None:
|
||||
if not _link(value) or depth >= self.max_depth:
|
||||
code = "malformed" if not _link(value) else "depth-limit"
|
||||
|
||||
Reference in New Issue
Block a user