fix(image): restore image size control

This commit is contained in:
silveroxides
2026-09-01 11:49:44 +02:00
parent f180509263
commit 6048af0e6c
2 changed files with 39 additions and 3 deletions
+12 -3
View File
@@ -248,6 +248,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
IO.String.Input("retry_pattern", default="", optional=True, multiline=False, tooltip="Regex pattern to match in response text. If matched, retry with new seed. Leave empty to disable."),
IO.Int.Input("max_retries", default=3, min=0, max=10, step=1, tooltip="Maximum number of retry attempts when pattern matches. 0 disables retry."),
IO.String.Input("timeout_fallback_text", default="", optional=True, multiline=True, tooltip="Text returned when the Gemini request times out. Leave empty to return the standard timeout message."),
IO.Combo.Input("image_size", options=["None", "512", "1K", "2K", "4K"], default="None", tooltip="Generated image resolution. Gemini 3.1 Flash Lite Image supports only 1K; 512 is supported only by Gemini 3.1 Flash Image."),
cls.GeminiVideoConfig.Input("video", optional=True, tooltip="Optional configured Gemini video input with embedded audio and sampling FPS."),
IO.Autogrow.Input(
"image_inputs",
@@ -447,7 +448,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
use_proxy=False, proxy_host="127.0.0.1", proxy_port=7890, timeout=30,
include_thoughts=False, thinking_level=None, media_resolution=None,
retry_pattern="", max_retries=3, use_cache=False,
cache_ttl_minutes=60, cache_seed=0):
cache_ttl_minutes=60, cache_seed=0, image_size="None"):
# 1. Hashing Images
def get_tensor_hash(tensor):
@@ -468,6 +469,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
# Defaults
eff_include_images = False
eff_aspect_ratio = "None"
eff_image_size = "None"
eff_thinking_level = "None"
eff_thinking_budget = -1
eff_include_thoughts = False
@@ -479,6 +481,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
if include_images and model in cls.IMAGE_MODELS:
eff_include_images = True
eff_aspect_ratio = str(aspect_ratio)
eff_image_size = "None" if image_size in (None, "None") else str(image_size)
# When generating images, thinking params are ignored
elif model == cls.GEMINI_3_7_FLASH:
@@ -515,6 +518,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
int(max_output_tokens),
eff_include_images, # EFFECTIVE include_images
eff_aspect_ratio, # EFFECTIVE aspect_ratio
eff_image_size, # EFFECTIVE image_size
str(bypass_mode),
eff_thinking_budget, # EFFECTIVE thinking_budget
use_seed,
@@ -698,7 +702,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
def _build_generate_content_config(cls, model, temperature, top_p, top_k, max_output_tokens, seed,
include_images, response_modalities, aspect_ratio, padded_system_instruction,
thinking_level, thinking_budget, include_thoughts, media_resolution,
allow_all_people=False):
image_size="None", allow_all_people=False):
# Centralized builder for GenerateContentConfig used by different model/feature branches
safety = [
types.SafetySetting(category="HARM_CATEGORY_HARASSMENT", threshold="BLOCK_NONE"),
@@ -713,6 +717,8 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
image_config = {}
if aspect_ratio not in (None, "None"):
image_config["aspect_ratio"] = aspect_ratio
if image_size not in (None, "None"):
image_config["image_size"] = image_size
if allow_all_people:
image_config["person_generation"] = "ALLOW_ALL"
return types.GenerateContentConfig(
@@ -781,6 +787,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
use_proxy=False, proxy_host="127.0.0.1", proxy_port=7890, use_seed=False, seed=0, timeout=30,
include_thoughts=False, thinking_level=None, media_resolution=None,
retry_pattern="", max_retries=3, timeout_fallback_text="",
image_size="None",
video: GeminiVideoConfig.Type | None = None,
image_inputs: IO.Autogrow.Type | None = None) -> IO.NodeOutput:
@@ -811,7 +818,8 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
image_inputs,
use_proxy, proxy_host, proxy_port, timeout,
include_thoughts, thinking_level, media_resolution,
retry_pattern, max_retries, use_cache, cache_ttl_minutes, cache_seed
retry_pattern, max_retries, use_cache, cache_ttl_minutes, cache_seed,
image_size=image_size,
)
if cached is not None:
@@ -1077,6 +1085,7 @@ class SSL_GeminiTextPrompt(IO.ComfyNode):
thinking_budget=thinking_budget,
include_thoughts=include_thoughts,
media_resolution=media_resolution,
image_size=image_size,
allow_all_people=bool(config.get("use_vertexai_env", False) or config.get("vertexai_express", False)),
)
+27
View File
@@ -888,6 +888,7 @@ def test_confirmed_current_models_are_visible_without_deprecated_image_aliases()
model_input = next(input_ for input_ in schema.inputs if input_.id == "model")
input_ids = [input_.id for input_ in schema.inputs]
aspect_ratio = next(input_ for input_ in schema.inputs if input_.id == "aspect_ratio")
image_size = next(input_ for input_ in schema.inputs if input_.id == "image_size")
for model in (
"gemini-3.7-flash",
@@ -903,6 +904,9 @@ def test_confirmed_current_models_are_visible_without_deprecated_image_aliases()
assert input_ids[input_ids.index("include_images") + 1] == "aspect_ratio"
assert aspect_ratio.options == ["None", "1:1", "9:16", "16:9", "3:4", "4:3", "3:2", "2:3", "5:4", "4:5", "21:9"]
assert aspect_ratio.default == "None"
assert input_ids[input_ids.index("timeout_fallback_text") + 1] == "image_size"
assert image_size.options == ["None", "512", "1K", "2K", "4K"]
assert image_size.default == "None"
def test_image_config_omits_none_aspect_ratio():
@@ -948,6 +952,29 @@ def test_image_config_preserves_concrete_aspect_ratio():
assert config.image_config.aspect_ratio == "16:9"
def test_image_config_preserves_requested_image_size():
config = gemini_nodes.SSL_GeminiTextPrompt._build_generate_content_config(
model="gemini-3.1-flash-image",
temperature=1.0,
top_p=0.95,
top_k=40,
max_output_tokens=8192,
seed=7,
include_images=True,
response_modalities=["IMAGE", "TEXT"],
aspect_ratio="None",
padded_system_instruction="system",
thinking_level="None",
thinking_budget=0,
include_thoughts=False,
media_resolution="unspecified",
image_size="2K",
)
assert config.image_config.aspect_ratio is None
assert config.image_config.image_size == "2K"
def test_enterprise_image_config_allows_all_people():
config = gemini_nodes.SSL_GeminiTextPrompt._build_generate_content_config(
model="gemini-3.1-flash-image",