From e73588f213f383bb2c8ad5ce8ff7b211105cc502 Mon Sep 17 00:00:00 2001 From: digital-garbage <133010426+digital-garbage@users.noreply.github.com> Date: Sun, 23 Aug 2026 08:52:29 +0300 Subject: [PATCH] fix(editor): don't inherit a negative prompt from the imported workflow The `neg` primitive is seeded from the reference graph's widget values, and was only overwritten when the editor sent a non-None negative. The positive beside it is written unconditionally. So an imported workflow's negative stayed on the node and encoded on every run, while the editor's Negative prompt box sat empty and editable. Empty now means empty, on both. --- CHANGELOG.md | 4 +++- movie_editor/backend/builder.py | 8 ++++++-- movie_editor/tests/test_builder.py | 10 ++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51a26251..8a2c86c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,9 @@ a negative stored in its own settings whenever the wired one is blank, and the editor has no field for that stored copy — so emptying the visible box left an earlier negative in force with nothing on screen saying so. The editor's box is authoritative, empty included. - The log now names which of the two supplied the text. + The log now names which of the two supplied the text. The negative primitive is also + written unconditionally, like the positive beside it — guarded, it kept the widget value + harvested from an IMPORTED workflow, so someone else's negative encoded on every run. ### Reverted - **GGUF loading is back to expanding the checkpoint at load.** The quantized path through diff --git a/movie_editor/backend/builder.py b/movie_editor/backend/builder.py index 83f8c764..ed34e3a8 100644 --- a/movie_editor/backend/builder.py +++ b/movie_editor/backend/builder.py @@ -421,8 +421,12 @@ def build(object_info: dict, models_config: dict, params: dict, media: dict | No # 2. param overrides on the primitives + sampler seed. graph["pos"]["inputs"]["value"] = params.get("prompt", "") - if params.get("negative_prompt") is not None: - graph["neg"]["inputs"]["value"] = params["negative_prompt"] + # Unconditional, like the positive above it. Guarded on `is not None`, an absent key + # left the node holding the widget value harvested from the IMPORTED workflow — so a + # negative that came in with someone else's graph kept encoding on every run while + # the editor's Negative prompt box sat empty and editable. The box is the only + # negative the editor has; empty has to mean empty. + graph["neg"]["inputs"]["value"] = params.get("negative_prompt") or "" if params.get("num_frames_per_scene") is not None: graph["frames"]["inputs"]["value"] = family_frames(family, params["num_frames_per_scene"]) if params.get("frame_rate") is not None: diff --git a/movie_editor/tests/test_builder.py b/movie_editor/tests/test_builder.py index afac0eb1..52f20a5e 100644 --- a/movie_editor/tests/test_builder.py +++ b/movie_editor/tests/test_builder.py @@ -1270,3 +1270,13 @@ def test_the_editor_negative_reaches_studios_settings_too(): settings = json.loads(graph["studio"]["inputs"]["studio_settings"]) assert settings["refiner"]["negative_prompt"] == "no hats" assert graph["neg"]["inputs"]["value"] == "no hats" + + +def test_an_imported_negative_does_not_survive_an_empty_box(): + """`neg` is seeded from the imported workflow's widget values. Overwriting it only when + the editor sent a non-None negative meant an imported one kept encoding forever, with an + empty editable box on screen claiming otherwise.""" + params = dict(PARAMS) + params.pop("negative_prompt", None) + graph, _report = builder.build(OI, {"slots": []}, params) + assert graph["neg"]["inputs"]["value"] == ""