From 1eb3af32be7d675edae2fe0b9ae60baf0f5b9105 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Tue, 25 Aug 2026 03:07:41 +0200 Subject: [PATCH] Ignore stale embedded model metadata when a node exposes an explicit model widget --- core/services/loaded_models_service.py | 17 +++++++++ tests/test_loaded_models_routes.py | 51 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/core/services/loaded_models_service.py b/core/services/loaded_models_service.py index 92a6475..d952a11 100644 --- a/core/services/loaded_models_service.py +++ b/core/services/loaded_models_service.py @@ -225,6 +225,15 @@ class LoadedModelsService: return str(scope["subgraph_id"]) == str(ref.subgraph_id or "") return True + def has_explicit_model_widget_ref(node): + """Return whether the node already exposes a normal model widget.""" + return any( + node_matches_ref(node, ref) + and ref.widget_index is not None + and not ref.extra_value("is_urn", False) + for ref in all_model_refs + ) + # Collect all loaded models with their values loaded_models = [] total_refs = len(all_model_refs) @@ -353,6 +362,14 @@ class LoadedModelsService: ) node_type = node.get("type", "") + if has_explicit_model_widget_ref(node): + # Standard loaders persist stale/default entries in + # properties.models. The analyzed widget reference is the + # authoritative active model for nodes with an explicit + # model widget; keep properties.models as a fallback for + # nodes that do not expose one. + continue + properties = node.get("properties", {}) if not isinstance(properties, dict): properties = {} diff --git a/tests/test_loaded_models_routes.py b/tests/test_loaded_models_routes.py index d6ef2a0..37cffc1 100644 --- a/tests/test_loaded_models_routes.py +++ b/tests/test_loaded_models_routes.py @@ -177,6 +177,57 @@ async def test_loaded_models_route_includes_urn_and_embedded_models(): assert body["total"] == 2 +@pytest.mark.asyncio +async def test_loaded_models_route_ignores_stale_embedded_metadata_for_widget_loader(): + handlers, _ = _build_routes( + { + "available_models": [], + "model_refs": [ + { + "original_path": ( + r"KREA2\Krea2_Turbo_convrot_int8mixed.safetensors" + ), + "node_id": 761, + "widget_index": 0, + "node_type": "UNETLoader", + "category": "diffusion_models", + } + ], + } + ) + handler = handlers[("POST", "/model_resolver/loaded")] + workflow = { + "nodes": [ + { + "id": 761, + "type": "UNETLoader", + "widgets_values": [ + r"KREA2\Krea2_Turbo_convrot_int8mixed.safetensors", + "default", + ], + "properties": { + "models": [ + { + "name": "z_image_turbo_bf16.safetensors", + "directory": "diffusion_models", + } + ] + }, + } + ] + } + + with patch.dict(sys.modules, {"folder_paths": None}): + response = await handler(_request({"workflow": workflow})) + + body = json.loads(response.text) + assert response.status == 200 + assert body["total"] == 1 + assert [model["name"] for model in body["loaded_models"]] == [ + "Krea2_Turbo_convrot_int8mixed.safetensors" + ] + + @pytest.mark.asyncio async def test_loaded_models_route_returns_error_when_inventory_fails(): handlers, values = _build_routes()