From da7d9b3fc94d772e0e7d65eb06bcdb5b5a154558 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Fri, 24 Jul 2026 14:04:07 +0200 Subject: [PATCH] Skip non-model reference categories in workflow analyzer Treat widget values under the configs and custom_nodes dynamic categories as non-model references so the workflow analyzer does not falsely mark them as missing models. Added a regression test to verify a checkpoint widget is still detected when a config widget is present. --- core/workflow_analyzer.py | 10 +++++++++- tests/test_workflow_analyzer.py | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/core/workflow_analyzer.py b/core/workflow_analyzer.py index 43a4d1d..191a45d 100644 --- a/core/workflow_analyzer.py +++ b/core/workflow_analyzer.py @@ -233,6 +233,7 @@ NESTED_MODEL_KEYS = { _DYNAMIC_CATEGORY_SENTINEL_PREFIX = "__model_resolver_folder_category__" _DYNAMIC_NODE_WIDGET_CATEGORY_CACHE: Dict[str, Dict[str, Any]] = {} _DYNAMIC_NODE_WIDGET_CATEGORY_LOCK = threading.RLock() +NON_MODEL_REFERENCE_CATEGORIES = {"custom_nodes", "configs"} # These ComfyUI INPUT_TYPES entries become widgets in widgets_values. Typed graph # inputs like MODEL or CLIP are links, so they should not shift widget indexes. @@ -1407,7 +1408,14 @@ def get_node_model_info( # For each widget value, check if it looks like a model file or URN for idx, value in enumerate(widgets_values): widget_name = get_widget_name_hint(node, idx) - model_widget_folder_key_hints = get_dynamic_widget_category_hints(node, idx) + dynamic_category_hints = get_dynamic_widget_category_hints(node, idx) + if dynamic_category_hints and all( + normalize_download_category(category) + in NON_MODEL_REFERENCE_CATEGORIES + for category in dynamic_category_hints + ): + continue + model_widget_folder_key_hints = dynamic_category_hints model_widget_choice_info = get_dynamic_widget_choice_info(node, idx) model_widget_category_hints = get_model_widget_category_hints(node, idx) model_widget_category_hint = ( diff --git a/tests/test_workflow_analyzer.py b/tests/test_workflow_analyzer.py index 840321c..94417e2 100644 --- a/tests/test_workflow_analyzer.py +++ b/tests/test_workflow_analyzer.py @@ -466,6 +466,40 @@ class ScannerFolderModelTests(unittest.TestCase): class WorkflowCategoryHintsTests(unittest.TestCase): + def test_non_model_config_widget_does_not_hide_checkpoint_widget(self): + workflow = { + "nodes": [ + { + "id": 470, + "type": "CheckpointLoader", + "widgets": [ + {"name": "config_name"}, + {"name": "ckpt_name"}, + ], + "widgets_values": [ + "v1-inference.yaml", + "model.safetensors", + ], + "outputs": [{"type": "MODEL", "links": [1]}], + } + ] + } + + def dynamic_category_hints(_node, widget_index): + if widget_index == 0: + return ["configs"] + return ["checkpoints"] + + with patch( + "core.workflow_analyzer.get_dynamic_widget_category_hints", + side_effect=dynamic_category_hints, + ): + refs = analyze_workflow_models(workflow, available_models=[]) + + self.assertEqual(1, len(refs)) + self.assertEqual("model.safetensors", refs[0]["original_path"]) + self.assertEqual("checkpoints", refs[0]["category"]) + def test_node_type_to_category_hints_is_populated(self): from core.workflow_analyzer import NODE_TYPE_TO_CATEGORY_HINTS # Verify standard loader mappings are correctly generated