fix: use new v1beta/interactions endpoint for gemini 3.1 image generation instead of legacy predict
Build and Deploy / build-and-push (push) Successful in 38s
Build and Deploy / build-and-push (push) Successful in 38s
This commit is contained in:
+23
-12
@@ -380,8 +380,8 @@ app.post('/api/sparkplug/generate-images', authenticate, async (req, res) => {
|
|||||||
const apiKey = keys.NANO_BANANA_API_KEY || keys.GEMINI_API_KEY;
|
const apiKey = keys.NANO_BANANA_API_KEY || keys.GEMINI_API_KEY;
|
||||||
if (!apiKey) return res.status(400).json({ error: 'Nano Banana (Gemini) API key missing' });
|
if (!apiKey) return res.status(400).json({ error: 'Nano Banana (Gemini) API key missing' });
|
||||||
|
|
||||||
// We will use axios to call the Gemini Imagen REST API
|
// We will use axios to call the new Gemini 3.1 REST API via /interactions
|
||||||
const baseUrl = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-flash-lite-image:predict';
|
const baseUrl = 'https://generativelanguage.googleapis.com/v1beta/interactions';
|
||||||
|
|
||||||
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 = [];
|
const imageUrls = [];
|
||||||
@@ -391,22 +391,33 @@ app.post('/api/sparkplug/generate-images', authenticate, async (req, res) => {
|
|||||||
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 = {
|
||||||
instances: [
|
model: "gemini-3.1-flash-lite-image",
|
||||||
{
|
input: [
|
||||||
prompt: fullPrompt
|
{ type: "text", text: fullPrompt }
|
||||||
}
|
]
|
||||||
],
|
|
||||||
parameters: {
|
|
||||||
sampleCount: 1,
|
|
||||||
outputOptions: { mimeType: 'image/png' }
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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' }
|
||||||
});
|
});
|
||||||
|
|
||||||
const base64Image = response.data.predictions[0].bytesBase64Encoded;
|
// The new interactions endpoint returns the interaction object.
|
||||||
|
// We look for the image output.
|
||||||
|
let base64Image = null;
|
||||||
|
if (response.data.interaction?.output_image?.data) {
|
||||||
|
base64Image = response.data.interaction.output_image.data;
|
||||||
|
} 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) {
|
||||||
|
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');
|
||||||
|
|
||||||
const filename = `sparkplug-${req.user.id}-${Date.now()}-${index}.png`;
|
const filename = `sparkplug-${req.user.id}-${Date.now()}-${index}.png`;
|
||||||
|
|||||||
Reference in New Issue
Block a user