feat(seed): make explicit seed sending opt-in

This commit is contained in:
Artificial Sweetener
2026-04-04 20:51:48 -04:00
parent 10affefa27
commit b9ebdf9d76
8 changed files with 104 additions and 4 deletions
+1
View File
@@ -27,6 +27,7 @@ class MidjourneyCustomRequest(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("style_references"),
bind("character_references"),
+5
View File
@@ -51,6 +51,7 @@ class MidjourneyV4Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
bind("custom_args"),
@@ -111,6 +112,7 @@ class MidjourneyV5Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
@@ -171,6 +173,7 @@ class MidjourneyV6Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
@@ -233,6 +236,7 @@ class MidjourneyV7Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
bind("custom_args"),
),
@@ -281,6 +285,7 @@ class MidjourneyV8AlphaRequest(PromptDrivenNode):
bind("aspect_ratio"),
bind("batch"),
bind("seed"),
bind("send_explicit_seed"),
bind("custom_args"),
),
image_capability_target="midjourney_v8_alpha",
+4
View File
@@ -28,6 +28,7 @@ class Niji5Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
@@ -88,6 +89,7 @@ class Niji4Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
bind("custom_args"),
@@ -144,6 +146,7 @@ class Niji6Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("translate_weights"),
@@ -198,6 +201,7 @@ class Niji7Request(PromptDrivenNode):
bind("batch"),
bind("tile"),
bind("seed"),
bind("send_explicit_seed"),
bind("use_raw"),
*IMAGINE_SUBMISSION_BINDINGS,
bind("custom_args"),
+23 -1
View File
@@ -212,6 +212,8 @@ def _render_batch_repeat(value: Any, _: NormalizedValues) -> str:
def _render_seed(value: Any, _: NormalizedValues) -> str:
"""Render the seed flag when the seed is a non-negative integer."""
if not _.get("send_explicit_seed"):
return ""
coerced_value = coerce_int(value)
return (
f" --seed {value}" if coerced_value is not None and coerced_value >= 0 else ""
@@ -455,11 +457,31 @@ INPUT_SPECS: dict[str, InputSpec] = {
"min": 0,
"max": 4294967295,
"step": 1,
"tooltip": "Random seed for reproducibility (--seed)",
"tooltip": (
"Optional Midjourney seed value. Midjourney randomizes by "
'default when no seed is sent. Enable "Send Explicit Seed" to '
"include this value as --seed."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_seed,
),
"send_explicit_seed": InputSpec(
key="send_explicit_seed",
field_name="send_explicit_seed",
field_type="BOOLEAN",
field_options={
"default": False,
"label_on": "Send Explicit Seed",
"label_off": "Send Explicit Seed",
"tooltip": (
"When enabled, Mutiny sends the Seed value to Midjourney as "
"--seed. Leave disabled to use Midjourney's default randomized "
"seed behavior."
),
},
role=InputRole.PROMPT_FLAG,
),
"use_raw": InputSpec(
key="use_raw",
field_name="use_raw",
+18
View File
@@ -228,6 +228,24 @@ def test_midjourney_v7_node_submits_prompt_images_through_runtime(
assert len(image_inputs.prompt_images) == 1
assert image_inputs.prompt_images[0].startswith("data:image/png;base64,")
def test_midjourney_v7_node_sends_seed_only_when_explicitly_enabled(
plugin_package, make_node, fake_runtime_service_factory
):
"""Submit ``--seed`` only when the explicit seed toggle is enabled."""
node_class = plugin_package.NODE_CLASS_MAPPINGS["MidjourneyV7Request"]
fake_runtime = fake_runtime_service_factory()
node = make_node(node_class, _runtime_service=fake_runtime)
node.generate(
prompt="cat",
seed=42,
send_explicit_seed=True,
)
assert fake_runtime.imagine_calls[0]["prompt_text"] == "cat --seed 42 --v 7"
def test_niji6_node_submits_batched_images_through_runtime(
plugin_package, make_node, fake_runtime_service_factory
):
+22
View File
@@ -92,6 +92,28 @@ def test_stylize_spec_omits_default_flag(plugin_package):
assert renderer(250, {}) == " --stylize 250"
def test_seed_spec_requires_explicit_send_toggle(plugin_package):
"""Render the seed flag only when explicit seed sending is enabled."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
renderer = specs_module.INPUT_SPECS["seed"].renderer
assert renderer is not None
assert renderer(42, {"send_explicit_seed": False}) == ""
assert renderer(42, {"send_explicit_seed": True}) == " --seed 42"
def test_send_explicit_seed_spec_declares_boolean_default(plugin_package):
"""Expose the explicit-seed toggle with the approved UI contract."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
seed_toggle_spec = specs_module.INPUT_SPECS["send_explicit_seed"]
assert seed_toggle_spec.field_name == "send_explicit_seed"
assert seed_toggle_spec.field_type == "BOOLEAN"
assert seed_toggle_spec.field_options["default"] is False
assert seed_toggle_spec.field_options["label_on"] == "Send Explicit Seed"
assert seed_toggle_spec.field_options["label_off"] == "Send Explicit Seed"
def test_use_raw_spec_renders_raw_mode_flag(plugin_package):
"""Render the shared Raw Mode toggle as ``--raw`` for all supported nodes."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
+21 -3
View File
@@ -31,7 +31,7 @@ def test_custom_request_prompt_builder_fixes_version_spacing(plugin_package):
)
assert build_result.prompt_text == (
"cat::1.4 --v 7 --no dog::0.5 --raw --chaos 5 --repeat 2 --tile --seed 9"
"cat::1.4 --v 7 --no dog::0.5 --raw --chaos 5 --repeat 2 --tile"
)
assert build_result.build_controls["translate_weights"] is True
assert build_result.submission_controls == {
@@ -86,7 +86,7 @@ def test_v7_prompt_builder_renders_wrapped_image_metadata(plugin_package):
assert build_result.prompt_text == (
"cat --no dog --stylize 250 --chaos 7 --weird 12 --p p123 --ar 16:9"
" --q 2 --exp 5 --repeat 3 --tile --seed 42 --raw --stylize 900"
" --q 2 --exp 5 --repeat 3 --tile --raw --stylize 900"
" --iw 1.5 --sw 0 --sv 5 --ow 321"
)
assert build_result.submission_controls["images"] is wrapped_prompt_images
@@ -113,6 +113,24 @@ def test_v7_prompt_builder_renders_bare_personalization(plugin_package):
assert build_result.prompt_text == "cat --p"
def test_v7_prompt_builder_sends_seed_only_when_explicitly_enabled(plugin_package):
"""Render ``--seed`` only when the explicit seed toggle is enabled."""
prompting_module = sys.modules[f"{plugin_package.__name__}.prompting"]
node_class = plugin_package.NODE_CLASS_MAPPINGS["MidjourneyV7Request"]
build_result = prompting_module.build_prompt(
node_class.NODE_DEFINITION,
{
"prompt": "cat",
"seed": 42,
"send_explicit_seed": True,
},
)
assert build_result.prompt_text == "cat --seed 42"
def test_v7_prompt_builder_rejects_conflicting_personalization_controls(
plugin_package,
):
@@ -231,7 +249,7 @@ def test_niji7_prompt_builder_appends_niji7_supported_flags(plugin_package):
assert build_result.prompt_text == (
"cat --no dog --chaos 5 --weird 20 --ar 2:1"
" --repeat 2 --tile --seed 8 --raw --chaos 9 --sw 0 --sv 4"
" --repeat 2 --tile --raw --chaos 9 --sw 0 --sv 4"
)
+10
View File
@@ -122,6 +122,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"images",
"style_references",
"character_references",
@@ -144,6 +145,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"images",
"translate_weights",
"custom_args",
@@ -165,6 +167,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"images",
"translate_weights",
@@ -190,6 +193,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"images",
"translate_weights",
@@ -218,6 +222,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"custom_args",
],
@@ -234,6 +239,7 @@ EXPECTED_NODE_METADATA = {
"aspect_ratio",
"batch",
"seed",
"send_explicit_seed",
"custom_args",
],
"return_types": ("IMAGE",),
@@ -253,6 +259,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"images",
"translate_weights",
"custom_args",
@@ -275,6 +282,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"images",
"translate_weights",
@@ -300,6 +308,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"images",
"translate_weights",
@@ -322,6 +331,7 @@ EXPECTED_NODE_METADATA = {
"batch",
"tile",
"seed",
"send_explicit_seed",
"use_raw",
"images",
"custom_args",