feat(prompting): omit default prompt flags

This commit is contained in:
Artificial Sweetener
2026-04-04 20:51:28 -04:00
parent 127a510c6d
commit 10affefa27
4 changed files with 111 additions and 35 deletions
+56 -27
View File
@@ -128,7 +128,10 @@ def _render_version(value: Any, _: NormalizedValues) -> str:
def _render_stylize(value: Any, _: NormalizedValues) -> str:
"""Render the long-form stylize flag when a non-zero value is present."""
return f" --stylize {value}" if coerce_int(value) else ""
coerced_value = coerce_int(value)
if coerced_value in (None, 0, 100):
return ""
return f" --stylize {coerced_value}"
def _render_short_stylize(value: Any, _: NormalizedValues) -> str:
@@ -153,35 +156,45 @@ def _render_weird(value: Any, _: NormalizedValues) -> str:
def _render_quality(value: Any, _: NormalizedValues) -> str:
"""Render the current shared quality selector into Midjourney flags."""
values_by_label = {
"Draft Quality": "0.5",
"Default Quality": "1",
"High Quality": "2",
}
return f" --q {values_by_label.get(value, '1')}"
if value in (None, "", "Default Quality"):
return ""
if value == "Draft Quality":
return " --q 0.5"
if value == "High Quality":
return " --q 2"
return ""
def _render_legacy_quality(value: Any, _: NormalizedValues) -> str:
"""Render the legacy quality selector used by older model families."""
values_by_label = {
"Bad Quality": "0.25",
"Draft Quality": "0.5",
"Default Quality": "1",
}
return f" --q {values_by_label.get(value, '1')}"
if value in (None, "", "Default Quality"):
return ""
if value == "Bad Quality":
return " --q 0.25"
if value == "Draft Quality":
return " --q 0.5"
return ""
def _render_v7_quality(value: Any, _: NormalizedValues) -> str:
"""Render the Midjourney v7 quality selector into prompt flags."""
if value in (None, "", "Default Quality"):
return ""
if value == "Draft Quality":
return " --draft"
if value == "High Quality":
return " --q 2"
if value == "Ultra Quality":
return " --q 4"
return ""
values_by_label = {
"Default Quality": "1",
"High Quality": "2",
"Ultra Quality": "4",
}
return f" --q {values_by_label.get(value, '1')}"
def _render_aspect_ratio(value: Any, _: NormalizedValues) -> str:
"""Render a non-default aspect ratio while leaving the default implicit."""
normalized_value = str(value or "").strip()
if not normalized_value or normalized_value == "1:1":
return ""
return f" --ar {normalized_value}"
def _normalize_batch_count(value: Any, _: NormalizedValues) -> int:
@@ -287,7 +300,11 @@ INPUT_SPECS: dict[str, InputSpec] = {
"min": 0,
"max": 1000,
"step": 1,
"tooltip": "Controls the strength of Midjourney’s learned aesthetic priors - higher adds more artistic, less literal details. (--stylize)",
"tooltip": (
"Controls the strength of Midjourney’s learned aesthetic priors - "
"higher adds more artistic, less literal details. Default 100 is "
"implicit; non-default values render --stylize."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_stylize,
@@ -326,10 +343,13 @@ INPUT_SPECS: dict[str, InputSpec] = {
field_type="STRING",
field_options={
"default": "1:1",
"tooltip": "Aspect ratio (W:H), e.g., 16:9, 4:3, etc (--ar)",
"tooltip": (
"Aspect ratio (W:H), e.g., 16:9 or 4:3. Default 1:1 is implicit; "
"non-default ratios render --ar."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_flag("--ar"),
renderer=_render_aspect_ratio,
normalizer=_normalize_ratio_field,
),
"niji_aspect_ratio": InputSpec(
@@ -338,10 +358,13 @@ INPUT_SPECS: dict[str, InputSpec] = {
field_type="STRING",
field_options={
"default": "1:1",
"tooltip": "Aspect ratio (W:H) between 1:2 and 2:1, e.g., 2:3, 3:2, 1:1. Used for Niji, MJ v4c, etc. (--ar)",
"tooltip": (
"Aspect ratio (W:H) between 1:2 and 2:1, e.g., 2:3, 3:2, 1:1. "
"Default 1:1 is implicit; non-default ratios render --ar."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_flag("--ar"),
renderer=_render_aspect_ratio,
normalizer=_normalize_ratio_field,
validator=_validate_v4c_ratio,
),
@@ -351,7 +374,10 @@ INPUT_SPECS: dict[str, InputSpec] = {
field_type=["Draft Quality", "Default Quality", "High Quality"],
field_options={
"default": "Default Quality",
"tooltip": "Draft (--q 0.5), Default (--q 1), High (--q 2). Not all models support every value.",
"tooltip": (
"Draft renders --q 0.5, Default is implicit, High renders --q 2. "
"Not all models support every value."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_quality,
@@ -366,7 +392,7 @@ INPUT_SPECS: dict[str, InputSpec] = {
"Controls generation speed and detail for legacy MJ models (v1–v5, Niji 5, etc). "
"Bad Quality (--q 0.25): Fastest/lowest detail. "
"Draft Quality (--q 0.5): Lower quality, faster/cheaper. "
"Default Quality (--q 1): Normal quality (default). "
"Default Quality: Normal implicit quality. "
"Higher values are NOT supported."
),
},
@@ -384,7 +410,10 @@ INPUT_SPECS: dict[str, InputSpec] = {
],
field_options={
"default": "Default Quality",
"tooltip": "Draft Quality (--draft), Default (--q 1), High (--q 2), Ultra (--q 4, v7 only).",
"tooltip": (
"Draft Quality renders --draft, Default Quality is implicit, "
"High renders --q 2, Ultra renders --q 4 (v7 only)."
),
},
role=InputRole.PROMPT_FLAG,
renderer=_render_v7_quality,
+1 -2
View File
@@ -222,13 +222,12 @@ def test_midjourney_v7_node_submits_prompt_images_through_runtime(
images=wrapped_images,
)
assert fake_runtime.imagine_calls[0]["prompt_text"] == "cat --q 1 --iw 2 --v 7"
assert fake_runtime.imagine_calls[0]["prompt_text"] == "cat --iw 2 --v 7"
image_inputs = fake_runtime.imagine_calls[0]["image_inputs"]
assert image_inputs is not None
assert len(image_inputs.prompt_images) == 1
assert image_inputs.prompt_images[0].startswith("data:image/png;base64,")
def test_niji6_node_submits_batched_images_through_runtime(
plugin_package, make_node, fake_runtime_service_factory
):
+48 -1
View File
@@ -40,11 +40,58 @@ def test_v7_quality_spec_maps_expected_flags(plugin_package):
assert renderer is not None
assert renderer("Draft Quality", {}) == " --draft"
assert renderer("Default Quality", {}) == " --q 1"
assert renderer("Default Quality", {}) == ""
assert renderer("High Quality", {}) == " --q 2"
assert renderer("Ultra Quality", {}) == " --q 4"
def test_shared_quality_spec_omits_default_flag(plugin_package):
"""Leave the shared default quality implicit while keeping explicit variants."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
renderer = specs_module.INPUT_SPECS["quality"].renderer
assert renderer is not None
assert renderer("Draft Quality", {}) == " --q 0.5"
assert renderer("Default Quality", {}) == ""
assert renderer("High Quality", {}) == " --q 2"
def test_legacy_quality_spec_omits_default_flag(plugin_package):
"""Leave the legacy default quality implicit while preserving old variants."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
renderer = specs_module.INPUT_SPECS["quality_legacy"].renderer
assert renderer is not None
assert renderer("Bad Quality", {}) == " --q 0.25"
assert renderer("Draft Quality", {}) == " --q 0.5"
assert renderer("Default Quality", {}) == ""
def test_aspect_ratio_specs_omit_default_ratio_flag(plugin_package):
"""Render only non-default aspect-ratio flags across shared selectors."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
shared_renderer = specs_module.INPUT_SPECS["aspect_ratio"].renderer
niji_renderer = specs_module.INPUT_SPECS["niji_aspect_ratio"].renderer
assert shared_renderer is not None
assert niji_renderer is not None
assert shared_renderer("1:1", {}) == ""
assert shared_renderer("16:9", {}) == " --ar 16:9"
assert niji_renderer("1:1", {}) == ""
assert niji_renderer("2:1", {}) == " --ar 2:1"
def test_stylize_spec_omits_default_flag(plugin_package):
"""Render only non-default long-form stylize values."""
specs_module = sys.modules[f"{plugin_package.__name__}.prompting.input_specs"]
renderer = specs_module.INPUT_SPECS["stylize"].renderer
assert renderer is not None
assert renderer(0, {}) == ""
assert renderer(100, {}) == ""
assert renderer(250, {}) == " --stylize 250"
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"]
+6 -5
View File
@@ -31,8 +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 --stylize 100 --raw --chaos 5 --ar 1:1"
" --repeat 2 --tile --seed 9"
"cat::1.4 --v 7 --no dog::0.5 --raw --chaos 5 --repeat 2 --tile --seed 9"
)
assert build_result.build_controls["translate_weights"] is True
assert build_result.submission_controls == {
@@ -112,8 +111,7 @@ def test_v7_prompt_builder_renders_bare_personalization(plugin_package):
},
)
assert build_result.prompt_text == "cat --p --q 1"
assert build_result.prompt_text == "cat --p"
def test_v7_prompt_builder_rejects_conflicting_personalization_controls(
plugin_package,
@@ -148,6 +146,7 @@ def test_v7_prompt_builder_skips_image_weight_for_plain_images(plugin_package):
)
assert "--iw" not in build_result.prompt_text
assert "--q" not in build_result.prompt_text
assert build_result.submission_controls["images"] is not None
@@ -167,6 +166,7 @@ def test_v7_prompt_builder_allows_manual_reference_flags_in_custom_args(plugin_p
assert "--sref https://example.invalid/style.png" in build_result.prompt_text
assert "--oref https://example.invalid/subject.png" in build_result.prompt_text
assert "--q" not in build_result.prompt_text
def test_v7_prompt_builder_rejects_omni_reference_with_draft_or_ultra_quality(
@@ -230,7 +230,7 @@ def test_niji7_prompt_builder_appends_niji7_supported_flags(plugin_package):
)
assert build_result.prompt_text == (
"cat --no dog --stylize 100 --chaos 5 --weird 20 --ar 2:1"
"cat --no dog --chaos 5 --weird 20 --ar 2:1"
" --repeat 2 --tile --seed 8 --raw --chaos 9 --sw 0 --sv 4"
)
@@ -262,6 +262,7 @@ def test_batch_prompt_builder_maps_total_images_to_repeat_flags(
)
assert build_result.values["batch"] in {4, 8, 12, 160}
assert "--q" not in build_result.prompt_text
if expected_fragment:
assert expected_fragment in build_result.prompt_text
else: