fix(editor): an empty Negative prompt box means empty
Studio reads studio_settings.refiner.negative_prompt whenever the wired negative_prompt is blank. The editor writes the wired one and has no field for the stored one, so clearing the visible box handed control to a negative saved in an earlier session, invisibly — a 353-character negative encoding on a run whose Negative prompt field was empty. The editor's box now writes both, empty included. The log says which source supplied the text instead of only how long it was.
This commit is contained in:
@@ -17,6 +17,13 @@
|
||||
Phrases are ranked by weight before the cap, and the prompt is located from
|
||||
`minimax_token_tags` rather than assumed to be the tail of the conditioning.
|
||||
|
||||
### Fixed
|
||||
- **Clearing the editor's Negative prompt box now actually clears it.** Studio falls back to
|
||||
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.
|
||||
|
||||
### Reverted
|
||||
- **GGUF loading is back to expanding the checkpoint at load.** The quantized path through
|
||||
ComfyUI-GGUF loaded in seconds instead of a minute, and produced a model the sampler could
|
||||
|
||||
+8
-3
@@ -14930,10 +14930,15 @@ class FunPackStudio:
|
||||
# not evaluated. It still has to be encoded (the output is a real port, and
|
||||
# negative_erase reads it), but it is a full text-encoder pass and it has to
|
||||
# be visible when accounting for what a run loaded and when.
|
||||
# WHICH of the two supplied it. They are different boxes in different
|
||||
# places, and a stored one silently outranking an empty wired one reads
|
||||
# as the field on screen having no effect.
|
||||
source = ("the wired negative_prompt input"
|
||||
if str(negative_prompt or "").strip()
|
||||
else "Studio's SAVED setting (the wired negative_prompt input "
|
||||
"is empty)")
|
||||
print(f"[FunPackStudio] encoding the negative prompt with the wired CLIP "
|
||||
f"({len(effective_negative)} chars)"
|
||||
+ (" — nothing else in this run supplies one"
|
||||
if negative_conditioning is None else ""))
|
||||
f"({len(effective_negative)} chars) from {source}")
|
||||
neg_encoded = clip.encode_from_tokens_scheduled(clip.tokenize(effective_negative))
|
||||
if neg_encoded:
|
||||
out_negative = neg_encoded
|
||||
|
||||
@@ -505,6 +505,11 @@ def build(object_info: dict, models_config: dict, params: dict, media: dict | No
|
||||
# (first run after the user clicks "Reset Studio session"); explicit so it's never
|
||||
# left on from a previous run.
|
||||
_rf["reset_session"] = bool(params.get("reset_session"))
|
||||
# The editor's Negative prompt box is the ONLY negative in the editor, so it is
|
||||
# authoritative — including when it is empty. Studio falls back to this stored
|
||||
# setting whenever the wired negative is blank, which meant clearing the box left a
|
||||
# negative from a previous session in force with nothing on screen saying so.
|
||||
_rf["negative_prompt"] = str(params.get("negative_prompt") or "")
|
||||
# Project `$name` variables — Studio resolves them dead-last (after split), per scene.
|
||||
_vars = params.get("variables")
|
||||
if isinstance(_vars, (list, dict)) and _vars:
|
||||
|
||||
@@ -1251,3 +1251,22 @@ def test_two_ACTIVE_sources_on_one_port_are_still_refused():
|
||||
models = {k: v for k, v in _two_alternatives("none").items() if k != "full_control"}
|
||||
assert any("already wired from" in e
|
||||
for e in pipeline_wiring.validate_models_wiring(models))
|
||||
|
||||
|
||||
def test_an_empty_editor_negative_clears_studios_saved_one():
|
||||
"""Studio falls back to studio_settings.refiner.negative_prompt whenever the wired
|
||||
negative is blank. The editor has no field for that stored copy, so clearing the visible
|
||||
Negative prompt box left an old negative in force with nothing on screen saying so."""
|
||||
import json
|
||||
graph, _report = builder.build(OI, {"slots": []}, {**PARAMS, "negative_prompt": ""})
|
||||
settings = json.loads(graph["studio"]["inputs"]["studio_settings"])
|
||||
assert settings["refiner"]["negative_prompt"] == ""
|
||||
|
||||
|
||||
def test_the_editor_negative_reaches_studios_settings_too():
|
||||
import json
|
||||
graph, _report = builder.build(OI, {"slots": []},
|
||||
{**PARAMS, "negative_prompt": "no hats"})
|
||||
settings = json.loads(graph["studio"]["inputs"]["studio_settings"])
|
||||
assert settings["refiner"]["negative_prompt"] == "no hats"
|
||||
assert graph["neg"]["inputs"]["value"] == "no hats"
|
||||
|
||||
Reference in New Issue
Block a user