[object Object]

← back to Wallco Ai

migrate remaining retired gemini-2.0-flash vision refs to gemini-2.5-flash

efb671cccd72e9be28309072e0b544801f9262f1 · 2026-06-01 15:01:59 -0700 · Steve Abrams

scripts/bleed_guard.js, rate_design.js: URL model now env-overridable
(GEMINI_VISION_MODEL, default gemini-2.5-flash).
audit-{dogs-breed,stoned-animals-mood,cohort-generic,drunk-animals-abstraction}.js:
AUDIT_MODEL default flipped 2.0-flash -> 2.5-flash.
server.js: 6 live model:gemini-2.0-flash vision call sites also migrated
(regenerate-reverse describe + ghost detect + opacity verify, interior-designer
critique, cataloging, style analysis) - these 404d on the retired model.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit efb671cccd72e9be28309072e0b544801f9262f1
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jun 1 15:01:59 2026 -0700

    migrate remaining retired gemini-2.0-flash vision refs to gemini-2.5-flash
    
    scripts/bleed_guard.js, rate_design.js: URL model now env-overridable
    (GEMINI_VISION_MODEL, default gemini-2.5-flash).
    audit-{dogs-breed,stoned-animals-mood,cohort-generic,drunk-animals-abstraction}.js:
    AUDIT_MODEL default flipped 2.0-flash -> 2.5-flash.
    server.js: 6 live model:gemini-2.0-flash vision call sites also migrated
    (regenerate-reverse describe + ghost detect + opacity verify, interior-designer
    critique, cataloging, style analysis) - these 404d on the retired model.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 TODO.md                                    |  2 +-
 scripts/audit-cohort-generic.js            |  2 +-
 scripts/audit-dogs-breed.js                |  4 ++--
 scripts/audit-drunk-animals-abstraction.js |  4 ++--
 scripts/audit-stoned-animals-mood.js       |  4 ++--
 scripts/bleed_guard.js                     |  2 +-
 scripts/rate_design.js                     |  2 +-
 server.js                                  | 14 +++++++-------
 8 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/TODO.md b/TODO.md
index 7be4987..d43d3d7 100644
--- a/TODO.md
+++ b/TODO.md
@@ -8,7 +8,7 @@ up unchecked rows automatically.
 - [x] Root cause: `0/N survived the quality gate (code null)` was NOT a gate rejection. The batch child SIGTERM-timed-out mid-flight. Batch route budgeted 150s/render (`Math.max(180000, n*150000)`) but comfy polls up to 15min/render (commit 86d053ad). Every multi-render comfy batch was killed before finishing; runs 27/28/30 hit their exact timeouts (3/10/30 min) and died at code=null. 5 designs (10251-10255) DID land in prod PG, correctly unpublished — the run rows lied.
 - [x] Fix (commit 3eeffee3, server.js + lib/{ghost,composition,subject}-detector.js): (1) per-render budget 150s→18min +5min slack, cap 4h (env `WALLCO_BATCH_PER_RENDER_MS`); (2) code=null signal-kill distinguished from real gate-reject(code 1), reported accurately; (3) reconciler falls back to harvesting `✓ #<id>` lines when killed-child never prints the `Created…IDs:` summary; (4) boot reaper closes runs stuck in `running` >30min (8 prod orphans incl pm2-wipe #29); (5) retired gemini-2.0-flash (404 since 2026-06-01) → gemini-2.5-flash in the 3 in-gen detectors (matches b25dd485).
 - [ ] DEPLOY Steve-gated: `./deploy-kamatera.sh` from ~/Projects/wallco-ai. On boot the reaper closes the 8 stuck `running` rows (#1,2,21-25,29). node -c clean. No publish/override touched.
-- [ ] Not in batch path, but still on retired 2.0-flash (curation/audit tools — fix when convenient): scripts/bleed_guard.js, scripts/rate_design.js, scripts/audit-{dogs-breed,stoned-animals-mood,cohort-generic,drunk-animals-abstraction}.js.
+- [x] Migrated remaining retired 2.0-flash refs → gemini-2.5-flash (LOCAL, not yet deployed): scripts/bleed_guard.js + scripts/rate_design.js (URL model now env-overridable `GEMINI_VISION_MODEL` default 2.5-flash); scripts/audit-{dogs-breed,stoned-animals-mood,cohort-generic,drunk-animals-abstraction}.js (`AUDIT_MODEL` default 2.5-flash). ALSO caught 6 live `model:'gemini-2.0-flash'` vision call sites in server.js that the prior note missed (regenerate-reverse describe + ghost detect + opacity verify; interior-designer critique; cataloging; style analysis) — all → 2.5-flash, the same model the rest of wallco's vision path uses. node -c passed on all 7 files. Not deployed (Steve gates deploys).
 
 ## Prompt-vs-image rating (2026-06-01, Steve-approved both gated steps)
 - [x] Migration: user_prompt_match (smallint) + user_prompt_verdict (text) + user_prompt_rated_at (timestamptz). LOCAL via CREATE OR REPLACE VIEW (spoon_all_designs is a view over all_designs locally); PROD via ALTER TABLE spoon_all_designs (it's a real table on prod — topology drift). Both applied + verified.
diff --git a/scripts/audit-cohort-generic.js b/scripts/audit-cohort-generic.js
index f4a86fa..43ebc24 100644
--- a/scripts/audit-cohort-generic.js
+++ b/scripts/audit-cohort-generic.js
@@ -34,7 +34,7 @@ if (!CATEGORY || !INTENT) {
   process.exit(2);
 }
 
-const MODEL   = process.env.AUDIT_MODEL || 'gemini-2.0-flash';
+const MODEL   = process.env.AUDIT_MODEL || 'gemini-2.5-flash';
 const SERVER  = process.env.AUDIT_SERVER || 'http://127.0.0.1:9905';
 const SLUG    = CATEGORY.replace(/[^a-z0-9_-]+/gi, '-').replace(/^-|-$/g, '');
 const OUT_JSONL = `/tmp/${SLUG}-audit-results.jsonl`;
diff --git a/scripts/audit-dogs-breed.js b/scripts/audit-dogs-breed.js
index 98cf23e..07a4842 100644
--- a/scripts/audit-dogs-breed.js
+++ b/scripts/audit-dogs-breed.js
@@ -15,7 +15,7 @@
  *   /tmp/dogs-audit-keep-list.json
  *   /tmp/dogs-audit-breed-drift.json (recognizable dog but wrong breed)
  *
- * Cost: ~220 * 1400 in-tokens = ~$0.03 on gemini-2.0-flash.
+ * Cost: ~220 * 1400 in-tokens = ~$0.03 on gemini-2.5-flash.
  */
 'use strict';
 
@@ -28,7 +28,7 @@ const https = require('https');
 const API_KEY = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
 if (!API_KEY) { console.error('GEMINI_API_KEY not set'); process.exit(1); }
 
-const MODEL = process.env.AUDIT_MODEL || 'gemini-2.0-flash';
+const MODEL = process.env.AUDIT_MODEL || 'gemini-2.5-flash';
 const SERVER = process.env.AUDIT_SERVER || 'http://127.0.0.1:9905';
 const OUT_JSONL = '/tmp/dogs-audit-results.jsonl';
 const KILL_OUT = '/tmp/dogs-audit-kill-list.json';
diff --git a/scripts/audit-drunk-animals-abstraction.js b/scripts/audit-drunk-animals-abstraction.js
index a459e5e..df4487c 100755
--- a/scripts/audit-drunk-animals-abstraction.js
+++ b/scripts/audit-drunk-animals-abstraction.js
@@ -15,7 +15,7 @@
  * NO writes to DB. NO deploy. Surface-only — Steve confirms the kill-list
  * before any unpublish.
  *
- * Model: gemini-2.0-flash (input $0.10/M, output $0.40/M) — ~$0.04 total
+ * Model: gemini-2.5-flash (input $0.10/M, output $0.40/M) — ~$0.04 total
  * for 854 images at ~340 tokens/req.
  */
 'use strict';
@@ -32,7 +32,7 @@ if (!API_KEY) {
   process.exit(1);
 }
 
-const MODEL = process.env.AUDIT_MODEL || 'gemini-2.0-flash';
+const MODEL = process.env.AUDIT_MODEL || 'gemini-2.5-flash';
 const SERVER = process.env.AUDIT_SERVER || 'http://127.0.0.1:9905';
 const OUT_JSONL = '/tmp/drunk-animals-audit-results.jsonl';
 const KILL_OUT = '/tmp/drunk-animals-audit-kill-list.json';
diff --git a/scripts/audit-stoned-animals-mood.js b/scripts/audit-stoned-animals-mood.js
index 37fa605..176c123 100644
--- a/scripts/audit-stoned-animals-mood.js
+++ b/scripts/audit-stoned-animals-mood.js
@@ -21,7 +21,7 @@
  *   /tmp/stoned-animals-audit-kill-list.json (KILL ids only)
  *   /tmp/stoned-animals-audit-keep-list.json (KEEP ids only)
  *
- * Model: gemini-2.0-flash (~$0.12 for ~700 published designs).
+ * Model: gemini-2.5-flash (~$0.12 for ~700 published designs).
  */
 'use strict';
 
@@ -34,7 +34,7 @@ const https = require('https');
 const API_KEY = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY;
 if (!API_KEY) { console.error('GEMINI_API_KEY not set'); process.exit(1); }
 
-const MODEL = process.env.AUDIT_MODEL || 'gemini-2.0-flash';
+const MODEL = process.env.AUDIT_MODEL || 'gemini-2.5-flash';
 const SERVER = process.env.AUDIT_SERVER || 'http://127.0.0.1:9905';
 const CATEGORY = process.env.AUDIT_CATEGORY || 'stoned-animals';
 const OUT_JSONL = '/tmp/stoned-animals-audit-results.jsonl';
diff --git a/scripts/bleed_guard.js b/scripts/bleed_guard.js
index cda70b7..f098756 100755
--- a/scripts/bleed_guard.js
+++ b/scripts/bleed_guard.js
@@ -151,7 +151,7 @@ Return STRICT JSON only:
     generationConfig: { temperature: 0, response_mime_type: 'application/json' },
   };
   const r = await fetch(
-    `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${KEY}`,
+    `https://generativelanguage.googleapis.com/v1beta/models/${process.env.GEMINI_VISION_MODEL || 'gemini-2.5-flash'}:generateContent?key=${KEY}`,
     { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify(body) }
   );
   if (!r.ok) {
diff --git a/scripts/rate_design.js b/scripts/rate_design.js
index a36ce8b..bae8286 100644
--- a/scripts/rate_design.js
+++ b/scripts/rate_design.js
@@ -68,7 +68,7 @@ Return STRICT JSON only:
 
 async function gemini(prompt, imageB64) {
   const r = await fetch(
-    `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key=${KEY}`,
+    `https://generativelanguage.googleapis.com/v1beta/models/${process.env.GEMINI_VISION_MODEL || 'gemini-2.5-flash'}:generateContent?key=${KEY}`,
     {
       method: 'POST',
       headers: { 'Content-Type': 'application/json' },
diff --git a/server.js b/server.js
index 466e44f..14d8db9 100644
--- a/server.js
+++ b/server.js
@@ -10886,7 +10886,7 @@ RETURNING id`);
 });
 
 // POST /api/design/:id/regenerate-reverse — full re-roll via reverse-engineered prompt.
-// Step 1: gemini-2.0-flash Vision reads the source image and writes a CLEAN
+// Step 1: gemini-2.5-flash Vision reads the source image and writes a CLEAN
 //         generation prompt describing it (no ghost layers, no translucent
 //         duplicates, single flat layer)
 // Step 2: gemini-2.5-flash-image generates a fresh image from that prompt
@@ -10952,7 +10952,7 @@ app.post('/api/design/:id/regenerate-reverse', express.json({ limit: '4kb' }), a
       let describeJ;
       try {
         describeJ = await geminiCall({
-          model: 'gemini-2.0-flash',
+          model: 'gemini-2.5-flash',
           parts: [
             { inline_data: { mime_type: 'image/png', data: srcB64 } },
             { text: describePrompt },
@@ -11350,7 +11350,7 @@ RETURNING id`);
     let detectJ;
     try {
       detectJ = await geminiCall({
-        model: 'gemini-2.0-flash',
+        model: 'gemini-2.5-flash',
         parts: [
           { inline_data: { mime_type: 'image/png', data: srcB64 } },
           { text: detectPrompt },
@@ -11417,7 +11417,7 @@ RETURNING id`);
         `{"has_translucent_layers": true|false, "confidence": <0..1>, "what_you_see": "<short explanation>"}`
       );
       const j = await geminiCall({
-        model: 'gemini-2.0-flash',
+        model: 'gemini-2.5-flash',
         parts: [
           { inline_data: { mime_type: 'image/png', data: b64Result } },
           { text: verifyPrompt },
@@ -22386,7 +22386,7 @@ app.post('/api/studio/interior-design-review', __reviewLimiter, async (req, res)
       try {
         const b64 = fs.readFileSync(d.local_path).toString('base64');
         const j = await geminiCall({
-          model: 'gemini-2.0-flash',
+          model: 'gemini-2.5-flash',
           parts: [
             { inlineData: { mimeType: 'image/jpeg', data: b64 } },
             { text: `You are a luxury interior designer reviewing a new wallpaper pattern.
@@ -22447,7 +22447,7 @@ app.post('/api/design/:id/ai-designer', requireAdmin, express.json({ limit: '16k
     let j;
     try {
       j = await geminiCall({
-        model: 'gemini-2.0-flash',
+        model: 'gemini-2.5-flash',
         parts: [
           { inlineData: { mimeType: 'image/jpeg', data: b64 } },
           { text: `You are a luxury interior designer cataloging a new wallpaper pattern for Designer Wallcoverings.
@@ -22725,7 +22725,7 @@ print(f"#{r:02x}{g:02x}{b:02x}")
     try {
       const b64 = fs.readFileSync(target).toString('base64');
       const j = await geminiCall({
-        model: 'gemini-2.0-flash',
+        model: 'gemini-2.5-flash',
         parts: [
           { inlineData: { mimeType: 'image/jpeg', data: b64 } },
           { text: `Analyze this design. Return STRICT JSON:

← 9d134cd TODO: log generator batch-timeout diagnosis + local fix (dep  ·  back to Wallco Ai  ·  designs: move social-share ↗ FAB right of the bulk-select ch 9f255b7 →