Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion templates/engines/static/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"9x16": (2160, 3840),
}

VALID_HERO_MODES = ("flat_brand_color", "background", "top_band", "radiant_gradient")


def hex_to_rgb(h):
h = h.lstrip("#")
Expand Down Expand Up @@ -184,6 +186,20 @@ def base_canvas(size, variant, brand):
W, H = size
canvas = Image.new("RGB", (W, H), brand.cream)
band_h = 0
if hero_mode not in VALID_HERO_MODES:
print(
f"warning: unknown hero_mode={hero_mode!r} — falling back to "
f"flat_brand_color. Valid options: {', '.join(VALID_HERO_MODES)}.",
file=sys.stderr,
)
hero_mode = "flat_brand_color"
if hero_mode in ("background", "top_band") and not hero_path:
print(
f"warning: hero_mode={hero_mode!r} requires 'hero_image' in the variant, "
f"but none was provided — falling back to flat_brand_color.",
file=sys.stderr,
)
hero_mode = "flat_brand_color"
if hero_mode == "background" and hero_path:
bg = Image.open(hero_path).convert("RGB")
canvas = crop_cover(bg, W, H)
Expand All @@ -193,7 +209,6 @@ def base_canvas(size, variant, brand):
canvas = canvas.convert("RGB")
elif hero_mode == "radiant_gradient":
if brand.radiant is None:
import sys
print(
"warning: hero_mode='radiant_gradient' but brand.json has no "
"radiant_gradient block — falling back to flat_brand_color. "
Expand Down
4 changes: 2 additions & 2 deletions templates/env.example
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ OPENAI_API_KEY=
#OPENAI_MODEL=gpt-image-1

# Replicate — https://replicate.com/account/api-tokens
# Free tier includes flux-schnell; default model is google/nano-banana-2.
# Default model is black-forest-labs/flux-schnell (free tier).
REPLICATE_API_TOKEN=
#REPLICATE_MODEL=google/nano-banana-2
#REPLICATE_MODEL=black-forest-labs/flux-schnell

# Stability AI (Stable Image Core/Ultra/SD3) — https://platform.stability.ai/account/keys
STABILITY_API_KEY=
Expand Down
50 changes: 50 additions & 0 deletions test/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,56 @@ else
cat "$WORK/dispatcher-order.log"
fi

# 2g.7 — shared.base_canvas warns + falls back on unknown hero_mode (#35)
if python3 - <<PY > "$WORK/hero-mode-fallback.log" 2>&1
import sys
sys.path.insert(0, "$PROJECT/engines/static")
from shared import Brand, base_canvas, VALID_HERO_MODES
import json, pathlib

brand_json = json.loads((pathlib.Path("$PROJECT") / "brand.json").read_text())
brand = Brand(brand_json, pathlib.Path("$PROJECT"))

# Unknown mode -> warn to stderr, canvas still rendered
import io, contextlib
buf = io.StringIO()
with contextlib.redirect_stderr(buf):
canvas, band_h = base_canvas((400, 500), {"hero_mode": "generated"}, brand)
assert canvas.size == (400, 500), canvas.size
assert band_h == 0
stderr = buf.getvalue()
assert "unknown hero_mode='generated'" in stderr, stderr
for mode in VALID_HERO_MODES:
assert mode in stderr, f"missing {mode} in: {stderr}"

# Valid mode does NOT warn
buf2 = io.StringIO()
with contextlib.redirect_stderr(buf2):
base_canvas((400, 500), {"hero_mode": "flat_brand_color"}, brand)
assert "unknown hero_mode" not in buf2.getvalue(), buf2.getvalue()

# background w/o hero_path -> warn + fall back (not silent)
buf3 = io.StringIO()
with contextlib.redirect_stderr(buf3):
base_canvas((400, 500), {"hero_mode": "background"}, brand)
assert "requires 'hero_image'" in buf3.getvalue(), buf3.getvalue()
PY
then
pass "unknown hero_mode warns and falls back (not silent)"
else
fail "hero_mode fallback"
cat "$WORK/hero-mode-fallback.log"
fi

# 2g.8 — .env.example advertises the actual Replicate default model (#36)
if grep -q "black-forest-labs/flux-schnell" "$PROJECT/.env.example" \
&& ! grep -q "google/nano-banana-2" "$PROJECT/.env.example"; then
pass ".env.example Replicate default matches replicate.py"
else
fail ".env.example Replicate default stale"
grep -n "REPLICATE\|nano-banana\|flux-schnell" "$PROJECT/.env.example" || true
fi

deactivate

# ---------------------------------------------------------------------------
Expand Down
Loading