[object Object]

← back to Designer Wallcoverings

Cap Gemini thinking budget (thinkingBudget=0) on remaining uncapped gemini-3.5-flash calls

c40bab9f54b737d35d48c4e82f3a4f63fc90b60d · 2026-06-23 08:34:25 -0700 · Steve Abrams

18 enrichment/vision scripts billed thinking tokens after the 3.5-flash upgrade.
Added generationConfig.thinkingConfig.thinkingBudget=0 to each generateContent call
(multi-call files capped per-call). Skipped ai-expenses-tracker.ts (no API call,
model name only in a pricing table). All JS/PY syntax-checked clean.

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

Files touched

Diff

commit c40bab9f54b737d35d48c4e82f3a4f63fc90b60d
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Tue Jun 23 08:34:25 2026 -0700

    Cap Gemini thinking budget (thinkingBudget=0) on remaining uncapped gemini-3.5-flash calls
    
    18 enrichment/vision scripts billed thinking tokens after the 3.5-flash upgrade.
    Added generationConfig.thinkingConfig.thinkingBudget=0 to each generateContent call
    (multi-call files capped per-call). Skipped ai-expenses-tracker.ts (no API call,
    model name only in a pricing table). All JS/PY syntax-checked clean.
    
    Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
 DW-Agents/vendor-command-center/logo-cropper.js     |   3 ++-
 .../scripts/koroseal-enrichment.ts                  |   1 +
 DW-Programming/PhillipeRomanoTagger/server.js       |   6 +++---
 .../__pycache__/color-batch-cleaner.cpython-314.pyc | Bin 31748 -> 31811 bytes
 DW-Programming/china-seas-hex-colors.js             |   3 ++-
 DW-Programming/color-batch-cleaner.py               |   2 +-
 DW-Programming/enrich-launched-products.py          |   3 ++-
 DW-Programming/hex-color-blitz.js                   |   3 ++-
 DW-Programming/hollywood-hex-extract.js             |   4 ++--
 DW-Programming/phase3-ai-enrich-batch.py            |   3 ++-
 DW-Programming/phase3-ai-enrich-run.js              |   3 ++-
 dw-bm-section.png                                   | Bin 0 -> 4069372 bytes
 enrich-arte-fix.js                                  |   3 ++-
 gemini-enrich-arte.js                               |   2 +-
 gemini-enrich-arte9.js                              |   3 ++-
 scripts/ai-enrich-arte-gaps.js                      |   3 ++-
 scripts/ai-enrich-gaps.js                           |   3 ++-
 shopify/scripts/classify-texture-pattern.js         |   3 ++-
 shopify/scripts/texture-repeat-fixer.js             |   3 ++-
 .../scripts/tres-tintas-designer-descriptions.js    |   2 +-
 20 files changed, 33 insertions(+), 20 deletions(-)

diff --git a/DW-Agents/vendor-command-center/logo-cropper.js b/DW-Agents/vendor-command-center/logo-cropper.js
index 33b4e4f9..b6ddf3c4 100644
--- a/DW-Agents/vendor-command-center/logo-cropper.js
+++ b/DW-Agents/vendor-command-center/logo-cropper.js
@@ -48,7 +48,8 @@ If no logo, set percentage to 0. Max 30% — if the area is larger, it's probabl
             { inline_data: { mime_type: mimeType, data: base64 } },
             { text: prompt }
           ]
-        }]
+        }],
+        generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
       })
     });
 
diff --git a/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts b/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts
index a64e48a4..a169d85e 100644
--- a/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts
+++ b/DW-Programming/ImportNewSkufromURL/scripts/koroseal-enrichment.ts
@@ -404,6 +404,7 @@ async function analyzeWithGemini(imageUrl: string): Promise<string | null> {
           { text: 'Describe the colors, texture, and style of this wallcovering in 2-3 sentences.' },
         ],
       }],
+      generationConfig: { thinkingConfig: { thinkingBudget: 0 } },
     };
 
     return new Promise((resolve) => {
diff --git a/DW-Programming/PhillipeRomanoTagger/server.js b/DW-Programming/PhillipeRomanoTagger/server.js
index 5494bc37..4ea95d7d 100644
--- a/DW-Programming/PhillipeRomanoTagger/server.js
+++ b/DW-Programming/PhillipeRomanoTagger/server.js
@@ -310,7 +310,7 @@ async function analyzeImageWithGemini(imageUrl, productTitle, productDescription
     const base64Image = Buffer.from(imageBuffer).toString('base64');
     const mimeType = imageResponse.headers.get('content-type') || 'image/jpeg';
 
-    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash' });
+    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash', generationConfig: { thinkingConfig: { thinkingBudget: 0 } } });
 
     // Clean description (remove HTML)
     const cleanDescription = productDescription
@@ -552,7 +552,7 @@ async function generateDescriptionSuggestion(currentDescription, aiAnalysis, pro
   }
 
   try {
-    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash' });
+    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash', generationConfig: { thinkingConfig: { thinkingBudget: 0 } } });
 
     // Clean current description
     const cleanDescription = (currentDescription || '')
@@ -609,7 +609,7 @@ async function generateSEOSuggestion(productTitle, aiAnalysis, suggestedTags) {
   }
 
   try {
-    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash' });
+    const model = gemini.getGenerativeModel({ model: 'gemini-3.5-flash', generationConfig: { thinkingConfig: { thinkingBudget: 0 } } });
 
     // Extract short product name (first word or two)
     const shortName = productTitle.split(' - ')[0].split(' ').slice(0, 2).join(' ').slice(0, 15);
diff --git a/DW-Programming/__pycache__/color-batch-cleaner.cpython-314.pyc b/DW-Programming/__pycache__/color-batch-cleaner.cpython-314.pyc
index 9a20ef37..8b89ee6a 100644
Binary files a/DW-Programming/__pycache__/color-batch-cleaner.cpython-314.pyc and b/DW-Programming/__pycache__/color-batch-cleaner.cpython-314.pyc differ
diff --git a/DW-Programming/china-seas-hex-colors.js b/DW-Programming/china-seas-hex-colors.js
index ee970126..17736f1f 100644
--- a/DW-Programming/china-seas-hex-colors.js
+++ b/DW-Programming/china-seas-hex-colors.js
@@ -49,7 +49,8 @@ async function getHexFromGemini(imageBuffer) {
     contents: [{ parts: [
       { text: "Analyze this wallpaper image. Return ONLY a single hex color code (e.g. #8B4513) representing the dominant/primary color. Just the hex code, nothing else." },
       { inlineData: { mimeType: "image/jpeg", data: b64 } }
-    ]}]
+    ]}],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   });
 
   return new Promise((resolve, reject) => {
diff --git a/DW-Programming/color-batch-cleaner.py b/DW-Programming/color-batch-cleaner.py
index 22d06a6b..708e4635 100644
--- a/DW-Programming/color-batch-cleaner.py
+++ b/DW-Programming/color-batch-cleaner.py
@@ -312,7 +312,7 @@ def phase1(color_name):
                                 {"text": item['prompt']},
                                 {"inline_data": {"mime_type": "image/jpeg", "data": img_b64}}
                             ]}],
-                            "generationConfig": {"temperature": 0.1, "maxOutputTokens": 50}
+                            "generationConfig": {"temperature": 0.1, "maxOutputTokens": 50, "thinkingConfig": {"thinkingBudget": 0}}
                         }
                     }
                     f.write(json.dumps(request) + '\n')
diff --git a/DW-Programming/enrich-launched-products.py b/DW-Programming/enrich-launched-products.py
index c79c75e9..429244b1 100644
--- a/DW-Programming/enrich-launched-products.py
+++ b/DW-Programming/enrich-launched-products.py
@@ -67,7 +67,8 @@ for p in products:
                 {"text": PROMPT_TEMPLATE.format(context=p["prompt_context"])},
                 {"inlineData": {"mimeType": "image/jpeg", "data": img_b64}}
             ]
-        }]
+        }],
+        "generationConfig": {"thinkingConfig": {"thinkingBudget": 0}}
     }
 
     resp = requests.post(GEMINI_URL, json=payload, timeout=60)
diff --git a/DW-Programming/hex-color-blitz.js b/DW-Programming/hex-color-blitz.js
index dbbc6b12..2a3547ff 100644
--- a/DW-Programming/hex-color-blitz.js
+++ b/DW-Programming/hex-color-blitz.js
@@ -209,7 +209,8 @@ async function getHexFromGemini(imageBuffer, imageUrl) {
     contents: [{ parts: [
       { text: "Analyze this wallcovering image. Return ONLY a single hex color code (e.g. #8B4513) representing the dominant/primary background color. Just the hex code, nothing else." },
       { inlineData: { mimeType: mime, data: b64 } }
-    ]}]
+    ]}],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   });
 
   return new Promise((resolve, reject) => {
diff --git a/DW-Programming/hollywood-hex-extract.js b/DW-Programming/hollywood-hex-extract.js
index 659ceea6..a35ae2cf 100644
--- a/DW-Programming/hollywood-hex-extract.js
+++ b/DW-Programming/hollywood-hex-extract.js
@@ -72,7 +72,7 @@ Return ONLY the JSON, no markdown, no explanation.` },
           { inline_data: { mime_type: 'image/jpeg', file_uri: imageUrl } }
         ]
       }],
-      generationConfig: { temperature: 0.1 }
+      generationConfig: { temperature: 0.1, thinkingConfig: { thinkingBudget: 0 } }
     });
 
     // Use URL-based image instead of inline
@@ -90,7 +90,7 @@ Return ONLY the JSON, no markdown, no explanation.` },
           { file_data: { mime_type: 'image/png', file_uri: imageUrl } }
         ]
       }],
-      generationConfig: { temperature: 0.1 }
+      generationConfig: { temperature: 0.1, thinkingConfig: { thinkingBudget: 0 } }
     });
 
     const url = new URL(`https://generativelanguage.googleapis.com/v1beta/models/${GEMINI_MODEL}:generateContent?key=${GEMINI_KEY}`);
diff --git a/DW-Programming/phase3-ai-enrich-batch.py b/DW-Programming/phase3-ai-enrich-batch.py
index 31695985..582f205c 100644
--- a/DW-Programming/phase3-ai-enrich-batch.py
+++ b/DW-Programming/phase3-ai-enrich-batch.py
@@ -85,7 +85,8 @@ def call_gemini(image_bytes, mime_type):
         }],
         "generationConfig": {
             "temperature": 0.2,
-            "maxOutputTokens": 1024
+            "maxOutputTokens": 1024,
+            "thinkingConfig": {"thinkingBudget": 0}
         }
     }
 
diff --git a/DW-Programming/phase3-ai-enrich-run.js b/DW-Programming/phase3-ai-enrich-run.js
index db793969..6a5c54af 100644
--- a/DW-Programming/phase3-ai-enrich-run.js
+++ b/DW-Programming/phase3-ai-enrich-run.js
@@ -106,7 +106,8 @@ async function analyzeWithGemini(imageBuffer, mimeType) {
         { text: GEMINI_PROMPT },
         { inline_data: { mime_type: mimeType, data: base64 } }
       ]
-    }]
+    }],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   };
 
   const resp = await postJson(GEMINI_URL, body);
diff --git a/dw-bm-section.png b/dw-bm-section.png
new file mode 100644
index 00000000..6c562e7c
Binary files /dev/null and b/dw-bm-section.png differ
diff --git a/enrich-arte-fix.js b/enrich-arte-fix.js
index 06c210ed..e11dcc74 100644
--- a/enrich-arte-fix.js
+++ b/enrich-arte-fix.js
@@ -37,7 +37,8 @@ function callGemini(b64, mime, prompt) {
       contents: [{ parts: [
         { text: prompt },
         { inline_data: { mime_type: mime, data: b64 } }
-      ]}]
+      ]}],
+      generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
     });
     const url = new URL(GEMINI_URL);
     const req = https.request({
diff --git a/gemini-enrich-arte.js b/gemini-enrich-arte.js
index eb9a58ba..a022118f 100644
--- a/gemini-enrich-arte.js
+++ b/gemini-enrich-arte.js
@@ -72,7 +72,7 @@ async function analyzeOne(product) {
         { inlineData: { mimeType: 'image/jpeg', data: b64 } }
       ]
     }],
-    generationConfig: { temperature: 0.2 }
+    generationConfig: { temperature: 0.2, thinkingConfig: { thinkingBudget: 0 } }
   };
   
   const res = await callGemini(body);
diff --git a/gemini-enrich-arte9.js b/gemini-enrich-arte9.js
index 72b68a96..3048cbe7 100644
--- a/gemini-enrich-arte9.js
+++ b/gemini-enrich-arte9.js
@@ -61,7 +61,8 @@ function callGemini(b64, productName) {
           { text: `Product: ${productName}\n\n${PROMPT}` },
           { inline_data: { mime_type: 'image/jpeg', data: b64 } }
         ]
-      }]
+      }],
+      generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
     });
     
     const url = new URL(GEMINI_URL);
diff --git a/scripts/ai-enrich-arte-gaps.js b/scripts/ai-enrich-arte-gaps.js
index d2906d3a..1ad8019f 100644
--- a/scripts/ai-enrich-arte-gaps.js
+++ b/scripts/ai-enrich-arte-gaps.js
@@ -72,7 +72,8 @@ async function callGemini(imageUrl, title) {
         { text: `${PROMPT}\n\nProduct: ${title}` },
         { inline_data: { mime_type: mimeType, data: base64 } }
       ]
-    }]
+    }],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   };
 
   const resp = await fetch(GEMINI_URL, {
diff --git a/scripts/ai-enrich-gaps.js b/scripts/ai-enrich-gaps.js
index d72cfbaa..9d703b42 100644
--- a/scripts/ai-enrich-gaps.js
+++ b/scripts/ai-enrich-gaps.js
@@ -35,7 +35,8 @@ async function callGemini(imageUrl, title) {
         { text: `${PROMPT}\n\nProduct: ${title}` },
         { inline_data: null }
       ]
-    }]
+    }],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   };
 
   // Fetch image and convert to base64
diff --git a/shopify/scripts/classify-texture-pattern.js b/shopify/scripts/classify-texture-pattern.js
index ec4c8e2c..e1c6fd28 100644
--- a/shopify/scripts/classify-texture-pattern.js
+++ b/shopify/scripts/classify-texture-pattern.js
@@ -44,7 +44,8 @@ async function classifyImage(imageUrl) {
           { text: PROMPT },
           { inlineData: { mimeType, data: base64 } }
         ]
-      }]
+      }],
+      generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
     };
 
     const resp = await fetch(GEMINI_URL, {
diff --git a/shopify/scripts/texture-repeat-fixer.js b/shopify/scripts/texture-repeat-fixer.js
index a56dc4ee..2593cbd4 100644
--- a/shopify/scripts/texture-repeat-fixer.js
+++ b/shopify/scripts/texture-repeat-fixer.js
@@ -65,7 +65,8 @@ async function classifyWithGemini(imageUrl) {
           }
         }
       ]
-    }]
+    }],
+    generationConfig: { thinkingConfig: { thinkingBudget: 0 } }
   });
 
   return new Promise((resolve, reject) => {
diff --git a/shopify/scripts/tres-tintas-designer-descriptions.js b/shopify/scripts/tres-tintas-designer-descriptions.js
index 9d122fbd..92467637 100644
--- a/shopify/scripts/tres-tintas-designer-descriptions.js
+++ b/shopify/scripts/tres-tintas-designer-descriptions.js
@@ -105,7 +105,7 @@ async function gemini(imgUrl) {
   const prompt = 'You are a senior interior designer cataloguing a wallcovering. Respond ONLY with compact JSON (no fence): {"colorways":[2-4 PRECISE trade colorway names like Greige, Celadon, Oxblood, Alabaster, Indigo, Terracotta — never generic beige/green/grey],"dominant":"single dominant colorway","style":[1-2 interior styles like Contemporary, Mid-Century Modern, Chinoiserie],"motif":"pattern/motif e.g. Abstract, Damask, Floral, Geometric, Stripe","mood":"3-6 word mood phrase"}';
   const r = await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${GEMINI_MODEL}:generateContent?key=${GKEY}`, {
     method: 'POST', headers: { 'Content-Type': 'application/json' },
-    body: JSON.stringify({ contents: [{ parts: [{ text: prompt }, { inline_data: { mime_type: 'image/jpeg', data: b64 } }] }] }) });
+    body: JSON.stringify({ contents: [{ parts: [{ text: prompt }, { inline_data: { mime_type: 'image/jpeg', data: b64 } }] }], generationConfig: { thinkingConfig: { thinkingBudget: 0 } } }) });
   const j = await r.json();
   const txt = j?.candidates?.[0]?.content?.parts?.[0]?.text || '';
   return JSON.parse(txt.replace(/```json|```/g, '').trim());

← a1410525 Disable Gemini thinking budget on capped enrichment calls (t  ·  back to Designer Wallcoverings  ·  Draft gated Gemini key rotation memo (leaked AIza key in 6 M 2711b778 →