← back to Wallco Ai
dogs/luxe gen: GEMINI_IMAGE_MODEL env override (re-roll on a newer Nano Banana) + dogs --force; provenance marker reflects model used
547c9df7ba7cc750c8f919c052cda2919281834e · 2026-06-03 08:28:32 -0700 · Steve
Files touched
M scripts/gen-luxe.jsM scripts/generate-dogs.js
Diff
commit 547c9df7ba7cc750c8f919c052cda2919281834e
Author: Steve <steve@designerwallcoverings.com>
Date: Wed Jun 3 08:28:32 2026 -0700
dogs/luxe gen: GEMINI_IMAGE_MODEL env override (re-roll on a newer Nano Banana) + dogs --force; provenance marker reflects model used
---
scripts/gen-luxe.js | 7 +++++--
scripts/generate-dogs.js | 15 +++++++++++----
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/scripts/gen-luxe.js b/scripts/gen-luxe.js
index da7fabc..d63cd37 100644
--- a/scripts/gen-luxe.js
+++ b/scripts/gen-luxe.js
@@ -65,8 +65,11 @@ function psql(sql) {
if (r.status !== 0) throw new Error(r.stderr || 'psql failed');
return r.stdout.trim();
}
+// Image model env-overridable (default = original Nano Banana). Set
+// GEMINI_IMAGE_MODEL=gemini-3.1-flash-image / gemini-3-pro-image to re-roll. — 2026-06
+const IMG_MODEL = process.env.GEMINI_IMAGE_MODEL || 'gemini-2.5-flash-image';
async function geminiImage(prompt) {
- const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent?key=${readKey()}`;
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${IMG_MODEL}:generateContent?key=${readKey()}`;
const r = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -294,7 +297,7 @@ INSERT INTO spoon_all_designs
image_url, local_path, dominant_hex, category, is_published, parent_design_id)
VALUES
('seamless_tile', 'wallco.ai', 24, 24,
- 'gemini-2.5-flash-image-luxe-v2',
+ ${esc(IMG_MODEL + '-luxe-v2')},
${esc('Luxe regen of #' + SRC_ID + ' anchored to de Gournay / House of Hackney / 1838-flock / Cole & Son / Brunschwig & Fils.' + (textureBrief ? ' Ground: ' + textureBrief + '.' : '') + (lastSubjectResult ? ' Subject-verify: primary=' + (SUBJECTS[0]||'?') + ' present=' + (lastSubjectResult.present.includes(SUBJECTS[0]) ? 'YES' : 'NO') + ' all=[' + lastSubjectResult.present.join(',') + ']/missing=[' + lastSubjectResult.missing.join(',') + '].' : '') + ' Motif: ' + MOTIF)},
${newSeed},
'/designs/img/by-id/__NEW__',
diff --git a/scripts/generate-dogs.js b/scripts/generate-dogs.js
index e07ecb4..f84f437 100644
--- a/scripts/generate-dogs.js
+++ b/scripts/generate-dogs.js
@@ -89,6 +89,7 @@ function parseArgs() {
if (a[i] === '--breeds') o.breeds = parseInt(a[++i], 10);
else if (a[i] === '--colorways') o.colorways = parseInt(a[++i], 10);
else if (a[i] === '--only') o.only = a[++i].split(',').map(s => s.trim()).filter(Boolean);
+ else if (a[i] === '--force') o.force = true; // regenerate even if a row exists (re-roll on a new model)
}
return o;
}
@@ -102,9 +103,13 @@ function readKey() {
return m[1].trim();
}
const GEMINI_KEY = readKey();
+// Image model is env-overridable (default = original Nano Banana). Set
+// GEMINI_IMAGE_MODEL=gemini-3.1-flash-image (Nano Banana 3.1) or
+// gemini-3-pro-image (Nano Banana Pro) to re-roll on a newer model. — 2026-06
+const IMG_MODEL = process.env.GEMINI_IMAGE_MODEL || 'gemini-2.5-flash-image';
async function geminiImage(prompt) {
- const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-image:generateContent?key=${GEMINI_KEY}`;
+ const url = `https://generativelanguage.googleapis.com/v1beta/models/${IMG_MODEL}:generateContent?key=${GEMINI_KEY}`;
const r = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
@@ -148,9 +153,10 @@ print(json.dumps([{'hex':'#{:02x}{:02x}{:02x}'.format(*rgb),'pct':round(n/total*
}
// ── one design ───────────────────────────────────────────────────────────────
+let FORCE = false; // --force: bypass the idempotency skip to re-roll on a new model
async function genOne(breed, cw) {
const category = `dogs · ${breed.slug}`;
- if (alreadyExists(category, cw.slug)) {
+ if (!FORCE && alreadyExists(category, cw.slug)) {
console.log(` · skip ${breed.slug}/${cw.slug} (already in PG)`);
return { skipped: true };
}
@@ -192,7 +198,7 @@ INSERT INTO spoon_all_designs
dominant_hex, palette, category, product_line, is_published)
VALUES
('seamless_tile', 'wallco.ai', 24, 24,
- 'gemini-2.5-flash-image-repeat-v2',
+ ${esc(IMG_MODEL + '-repeat-v2')},
${esc(storedPrompt)}, ${seed},
'/designs/img/by-id/__NEW__', ${esc(outPath)},
${esc(dominant)}, ${esc(JSON.stringify(palette))}::jsonb,
@@ -207,12 +213,13 @@ RETURNING id;`;
// ── main ─────────────────────────────────────────────────────────────────────
(async () => {
const opt = parseArgs();
+ FORCE = !!opt.force;
let breeds = BREEDS.slice(0, opt.breeds);
if (opt.only) breeds = BREEDS.filter(b => opt.only.includes(b.slug));
const colorways = COLORWAYS.slice(0, opt.colorways);
const total = breeds.length * colorways.length;
console.log(`generate-dogs: ${breeds.length} breeds × ${colorways.length} colorways = ${total} designs`);
- console.log(`engine: gemini-2.5-flash-image-repeat-v2 · is_published=FALSE (curate-then-publish)\n`);
+ console.log(`engine: ${IMG_MODEL}-repeat-v2 · is_published=FALSE (curate-then-publish)\n`);
const t0 = Date.now();
let ok = 0, skip = 0, fail = 0, retries = 0;
← 46bc416 detectors: handle Nano Banana C2PA JPEG (b64 magic /9j/, pat
·
back to Wallco Ai
·
mural-master: room-size 12x11ft scenic-master builder + vert 5bfe5e9 →