fix(metadata): record the actual checkpoint on Set/Get and stale-cache workflows

trace_model_path dead-ended on KJNodes GetNode virtual links and fell back
to the first entry in MODELS, which could be a stale checkpoint name
resurrected from the process-lifetime node_cache — images ended up with a
wrong or missing Hashes.model.

- SetNodeExtractor now records MODEL passthrough as a model_variable entry
  (variable name -> source node id), cached per node like other metadata
- trace_model_path resolves GetNode variable references through those
  entries instead of giving up (last SetNode wins, per KJNodes semantics)
- _fill_missing_metadata validates cached checkpoint names against the
  node's current widget values and rebuilds stale entries from the current
  inputs instead of resurrecting the previous model
This commit is contained in:
Will Miao
2026-10-09 20:44:39 +08:00
parent 1a6b0f78a3
commit 406096c0e1
4 changed files with 370 additions and 7 deletions
+28
View File
@@ -584,6 +584,20 @@ class ConditioningCombineExtractor(NodeMetadataExtractor):
)
def _get_model_link_source(metadata, node_id):
"""Return the upstream node id feeding this node's MODEL input link."""
prompt = metadata.get("current_prompt")
original_prompt = getattr(prompt, "original_prompt", None)
if not original_prompt or node_id not in original_prompt:
return None
node_inputs = original_prompt[node_id].get("inputs", {})
for key in ("MODEL", "model"):
link = node_inputs.get(key)
if isinstance(link, list) and link:
return str(link[0])
return None
class SetNodeExtractor(NodeMetadataExtractor):
@staticmethod
def extract(node_id, inputs, outputs, metadata):
@@ -591,6 +605,20 @@ class SetNodeExtractor(NodeMetadataExtractor):
return
variable_name = _get_node_variable_name(metadata, node_id, inputs)
# Record MODEL passthrough as a variable reference so trace_model_path
# can follow the matching GetNode back to the real loader — Set/Get
# links are virtual and absent from the API prompt.
if variable_name:
source_node_id = _get_model_link_source(metadata, node_id)
if source_node_id is not None:
metadata.setdefault(MODELS, {})[node_id] = {
"type": "model_variable",
"variable_name": variable_name,
"source_node_id": source_node_id,
"node_id": node_id,
}
conditioning = inputs.get("CONDITIONING")
if conditioning is None:
conditioning = inputs.get("conditioning")