From 8e4989ec0940ea3dbbd8872434300a31fce74a2d Mon Sep 17 00:00:00 2001 From: digital-garbage <133010426+digital-garbage@users.noreply.github.com> Date: Wed, 30 Sep 2026 17:55:18 +0300 Subject: [PATCH] fix: settings export hides stale loader inputs and SLA settings while SLA is off Co-Authored-By: Claude Sonnet 5.5 --- CHANGELOG.md | 3 +++ movie_editor/backend/settings_card.py | 20 +++++++++++++++++--- tests/test_settings_card_noise.py | 24 ++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d37840a5..52ab0ca5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## [Unreleased] +### Fixed +- Export settings no longer prints a loader input the node no longer has (a stale `sla_enabled: on`) or SLA's settings while `sla` is off. + ### Added - Shot cut times (H3, off by default): every `[Shot N]` after the first opens with its cut time, spread over the scene's length by text and rounded to whole seconds; a shot whose main point changes is split in two. Prompts that already carry times are left alone. - Shot views (H3, off by default): later shots may open with POV / side / front / from above / below / behind, never the same twice in a row; shot 1 is skipped. diff --git a/movie_editor/backend/settings_card.py b/movie_editor/backend/settings_card.py index 6996b636..be86adc7 100644 --- a/movie_editor/backend/settings_card.py +++ b/movie_editor/backend/settings_card.py @@ -172,6 +172,13 @@ _OWNED_EXTRA = { # Segmented detailing is no longer offered in the Editor (see detailing.py), but a raw # ComfyUI graph can still tick it, so the card still has to hide its settings when it # is off. + # SLA's settings sit on the loader node next to its `sla` switch. With the switch off they + # decide nothing, but a changed one was printed as if SLA were running. + "sla_sparsity": ("sla", None), + "sla_block_size": ("sla", None), + "sla_protect_audio": ("sla", None), + "sla_min_seq_len": ("sla", None), + "sla_dense_last_steps": ("sla", None), "detail_targets": ("segmented_detailing", None), "detail_strength": ("segmented_detailing", None), "detail_threshold": ("segmented_detailing", None), @@ -416,8 +423,9 @@ def _node_inputs(node_class: str) -> tuple: """ try: from . import bridge - spec = bridge._funpack_attr("samplers" if "Sampler" in node_class else "conditioning", - node_class).INPUT_TYPES() + module = ("samplers" if "Sampler" in node_class + else "loaders" if "Loader" in node_class else "conditioning") + spec = bridge._funpack_attr(module, node_class).INPUT_TYPES() except Exception: return frozenset(), {} declared, defaults = set(), {} @@ -551,9 +559,15 @@ def collect(models: dict, host: dict, *, project_name=None, version=None, title = (slot.get("label") or slot.get("role_label") or slot.get("node_class") or slot.get("id") or "node") rows = [] - for name, value in (slot.get("inputs") or {}).items(): + values = slot.get("inputs") or {} + declared, defaults = _node_inputs(str(slot.get("node_class") or "")) + for name, value in values.items(): if name in _NOISE_INPUTS: continue + if declared and name not in declared: # a leftover the node no longer has + continue + if not _switched_on(name, values, defaults): # e.g. sla_* with `sla` off + continue if _is_wired(slot, name, slots): rows.append((name, "‹wired›")) continue diff --git a/tests/test_settings_card_noise.py b/tests/test_settings_card_noise.py index 9c371011..66edfe70 100644 --- a/tests/test_settings_card_noise.py +++ b/tests/test_settings_card_noise.py @@ -230,3 +230,27 @@ def test_defaults_are_read_off_the_node_not_copied_here(): import inspect src = inspect.getsource(sc._node_inputs) assert "INPUT_TYPES()" in src + + +def test_sla_settings_are_hidden_while_sla_is_off(): + """A changed sla_* knob with the `sla` switch off reached the card as a live setting.""" + changed = {"sla": False, "sla_sparsity": 0.5, "sla_block_size": "128", "sla_dense_last_steps": 4} + assert [n for n, _ in sc._live_rows(changed, defaults={"sla": False})] == [] + on = dict(changed, sla=True) + names = [n for n, _ in sc._live_rows(on, defaults={"sla": False})] + assert {"sla", "sla_sparsity", "sla_block_size", "sla_dense_last_steps"} <= set(names) + + +def test_a_model_slot_does_not_print_a_stale_input_or_sla_settings_with_sla_off(): + """`sla_enabled: on` sat in a project's stored loader inputs from an older version, and the + card printed it (and the sla_* knobs) under `sla: off`.""" + slot = {"id": "s1", "node_class": "FunPackDiffusionModelLoader", "label": "Diffusion model", + "inputs": {"attention": "sage3", "sla": False, "sla_enabled": True, + "sla_sparsity": 0.85, "sla_block_size": "64"}} + card = sc.collect({"slots": [slot]}, {}) + rows = dict(next(s for s in card["sections"] if s["title"] == "Diffusion model")["rows"]) + assert rows == {"attention": "sage3", "sla": "off"} or set(rows) == {"attention", "sla"}, rows + slot["inputs"]["sla"] = True + rows = dict(next(s for s in sc.collect({"slots": [slot]}, {})["sections"] + if s["title"] == "Diffusion model")["rows"]) + assert "sla_sparsity" in rows and "sla_enabled" not in rows