fix: switch to Gemini Imagen 3 API endpoint to fix image base64 extraction
Build and Deploy / build-and-push (push) Successful in 31s

This commit is contained in:
AI Bot
2026-09-02 14:14:57 +05:30
parent b0e01f9adc
commit ec17eb833c
+15 -22
View File
@@ -370,52 +370,46 @@ app.post('/api/sparkplug/extract', authenticate, upload.single('file'), async (r
} }
}); });
// 2. Generate Images (Nano Banana / Gemini Imagen) // 2. Generate Images (Gemini Imagen 3)
app.post('/api/sparkplug/generate-images', authenticate, async (req, res) => { app.post('/api/sparkplug/generate-images', authenticate, async (req, res) => {
const { prompt } = req.body; const { prompt } = req.body;
if (!prompt) return res.status(400).json({ error: 'No prompt provided' }); if (!prompt) return res.status(400).json({ error: 'No prompt provided' });
try { try {
const keys = await getKeysFromProfile(req.user.id); const keys = await getKeysFromProfile(req.user.id);
const apiKey = keys.NANO_BANANA_API_KEY || keys.GEMINI_API_KEY; const apiKey = keys.GEMINI_API_KEY || keys.NANO_BANANA_API_KEY;
if (!apiKey) return res.status(400).json({ error: 'Nano Banana (Gemini) API key missing' }); if (!apiKey) return res.status(400).json({ error: 'Gemini API key missing' });
// We will use axios to call the new Gemini 3.1 REST API via /interactions // Use the standard Gemini Imagen 3 API
const baseUrl = 'https://generativelanguage.googleapis.com/v1beta/interactions'; const baseUrl = 'https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-images:predict';
const views = ['Front view', 'Back view', 'Left side view', 'Right side view']; const views = ['Front view', 'Back view', 'Left side view', 'Right side view'];
const imageUrls = [];
// Run parallel generation for all 4 views // Run parallel generation for all 4 views
const promises = views.map(async (view, index) => { const promises = views.map(async (view, index) => {
const fullPrompt = `${prompt}. ${view}, isolated on a pure white background, studio lighting.`; const fullPrompt = `${prompt}. ${view}, isolated on a pure white background, studio lighting.`;
const payload = { const payload = {
model: "gemini-3.1-flash-lite-image", instances: [
input: [ { prompt: fullPrompt }
{ type: "text", text: fullPrompt } ],
] parameters: {
sampleCount: 1,
aspectRatio: "1:1"
}
}; };
const response = await axios.post(`${baseUrl}?key=${apiKey}`, payload, { const response = await axios.post(`${baseUrl}?key=${apiKey}`, payload, {
headers: { 'Content-Type': 'application/json' } headers: { 'Content-Type': 'application/json' }
}); });
// The new interactions endpoint returns the interaction object.
// We look for the image output.
let base64Image = null; let base64Image = null;
if (response.data.interaction?.output_image?.data) { if (response.data && response.data.predictions && response.data.predictions.length > 0) {
base64Image = response.data.interaction.output_image.data; base64Image = response.data.predictions[0].bytesBase64Encoded;
} else if (response.data.interaction?.output?.blocks) {
// Fallback for raw REST shape if output_image is an SDK-only convenience wrapper
const imgBlock = response.data.interaction.output.blocks.find(b => b.type === 'image' || b.image);
if (imgBlock) {
base64Image = imgBlock.image?.data || imgBlock.data;
}
} }
if (!base64Image) { if (!base64Image) {
throw new Error("Could not extract base64 image data from Gemini response: " + JSON.stringify(response.data)); throw new Error(`Could not extract base64 image data from Gemini response: ${JSON.stringify(response.data)}`);
} }
const buffer = Buffer.from(base64Image, 'base64'); const buffer = Buffer.from(base64Image, 'base64');
@@ -432,7 +426,6 @@ app.post('/api/sparkplug/generate-images', authenticate, async (req, res) => {
} catch (err) { } catch (err) {
let errorMsg = err.message; let errorMsg = err.message;
if (err.response && err.response.data) { if (err.response && err.response.data) {
// Just stringify the entire response data so we can see the exact error from Google!
errorMsg = typeof err.response.data === 'object' ? JSON.stringify(err.response.data) : err.response.data; errorMsg = typeof err.response.data === 'object' ? JSON.stringify(err.response.data) : err.response.data;
} }
console.error("Gemini Image Gen Error:", errorMsg); console.error("Gemini Image Gen Error:", errorMsg);