nano-banana-pro: respect explicit --resolution when editing images (#36880)

* nano-banana-pro: respect explicit --resolution when editing images

* Changelog: note nano banana resolution fix

* Update CHANGELOG.md

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
This commit is contained in:
Mark Zhang
2026-03-06 23:44:54 +08:00
committed by GitHub
parent a820c63912
commit 37a3fb0f86
3 changed files with 77 additions and 13 deletions

View File

@@ -196,6 +196,7 @@ Docs: https://docs.openclaw.ai
- Agents/gateway config guidance: stop exposing `config.schema` through the agent `gateway` tool, remove prompt/docs guidance that told agents to call it, and keep agents on `config.get` plus `config.patch`/`config.apply` for config changes. (#7382) thanks @kakuteki.
- Agents/failover: classify periodic provider limit exhaustion text (for example `Weekly/Monthly Limit Exhausted`) as `rate_limit` while keeping explicit `402 Payment Required` variants in billing, so failover continues without misclassifying billing-wrapped quota errors. (#33813) thanks @zhouhe-xydt.
- Mattermost/interactive button callbacks: allow external callback base URLs and stop requiring loopback-origin requests so button clicks work when Mattermost reaches the gateway over Tailscale, LAN, or a reverse proxy. (#37543) thanks @mukhtharcm.
- Skills/nano-banana-pro resolution override: respect explicit `--resolution` values during image editing and only auto-detect output size from input images when the flag is omitted. (#36880) Thanks @shuofengzhang and @vincentkoc.
## 2026.3.2

View File

@@ -42,6 +42,33 @@ def get_api_key(provided_key: str | None) -> str | None:
return os.environ.get("GEMINI_API_KEY")
def auto_detect_resolution(max_input_dim: int) -> str:
"""Infer output resolution from the largest input image dimension."""
if max_input_dim >= 3000:
return "4K"
if max_input_dim >= 1500:
return "2K"
return "1K"
def choose_output_resolution(
requested_resolution: str | None,
max_input_dim: int,
has_input_images: bool,
) -> tuple[str, bool]:
"""Choose final resolution and whether it was auto-detected.
Auto-detection is only applied when the user did not pass --resolution.
"""
if requested_resolution is not None:
return requested_resolution, False
if has_input_images and max_input_dim > 0:
return auto_detect_resolution(max_input_dim), True
return "1K", False
def main():
parser = argparse.ArgumentParser(
description="Generate images using Nano Banana Pro (Gemini 3 Pro Image)"
@@ -66,8 +93,8 @@ def main():
parser.add_argument(
"--resolution", "-r",
choices=["1K", "2K", "4K"],
default="1K",
help="Output resolution: 1K (default), 2K, or 4K"
default=None,
help="Output resolution: 1K, 2K, or 4K. If omitted with input images, auto-detect from largest image dimension."
)
parser.add_argument(
"--aspect-ratio", "-a",
@@ -105,13 +132,12 @@ def main():
# Load input images if provided (up to 14 supported by Nano Banana Pro)
input_images = []
output_resolution = args.resolution
max_input_dim = 0
if args.input_images:
if len(args.input_images) > 14:
print(f"Error: Too many input images ({len(args.input_images)}). Maximum is 14.", file=sys.stderr)
sys.exit(1)
max_input_dim = 0
for img_path in args.input_images:
try:
with PILImage.open(img_path) as img:
@@ -126,15 +152,16 @@ def main():
print(f"Error loading input image '{img_path}': {e}", file=sys.stderr)
sys.exit(1)
# Auto-detect resolution from largest input if not explicitly set
if args.resolution == "1K" and max_input_dim > 0: # Default value
if max_input_dim >= 3000:
output_resolution = "4K"
elif max_input_dim >= 1500:
output_resolution = "2K"
else:
output_resolution = "1K"
print(f"Auto-detected resolution: {output_resolution} (from max input dimension {max_input_dim})")
output_resolution, auto_detected = choose_output_resolution(
requested_resolution=args.resolution,
max_input_dim=max_input_dim,
has_input_images=bool(input_images),
)
if auto_detected:
print(
f"Auto-detected resolution: {output_resolution} "
f"(from max input dimension {max_input_dim})"
)
# Build contents (images first if editing, prompt only if generating)
if input_images:

View File

@@ -0,0 +1,36 @@
import importlib.util
from pathlib import Path
import pytest
MODULE_PATH = Path(__file__).with_name("generate_image.py")
SPEC = importlib.util.spec_from_file_location("generate_image", MODULE_PATH)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)
@pytest.mark.parametrize(
("max_input_dim", "expected"),
[
(0, "1K"),
(1499, "1K"),
(1500, "2K"),
(2999, "2K"),
(3000, "4K"),
],
)
def test_auto_detect_resolution_thresholds(max_input_dim, expected):
assert MODULE.auto_detect_resolution(max_input_dim) == expected
def test_choose_output_resolution_auto_detects_when_resolution_omitted():
assert MODULE.choose_output_resolution(None, 2200, True) == ("2K", True)
def test_choose_output_resolution_defaults_to_1k_without_inputs():
assert MODULE.choose_output_resolution(None, 0, False) == ("1K", False)
def test_choose_output_resolution_respects_explicit_1k_with_large_input():
assert MODULE.choose_output_resolution("1K", 3500, True) == ("1K", False)