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"] == ""