continue generating flow, add backend connection on main tabs

This commit is contained in:
Thomas Demirdjian
2025-08-28 17:18:28 +02:00
parent 0ca7544005
commit bb7b35626f
110 changed files with 1701 additions and 3408 deletions
+100 -3
View File
@@ -1,8 +1,9 @@
const admin = require("firebase-admin");
const serviceAccount = require("./serviceAccountKey.json");
const { googleAI, gemini25FlashLite } = require("@genkit-ai/googleai");
const { googleAI } = require("@genkit-ai/googleai");
const { GEMINI_API_KEY } = require("./config/keys");
const { genkit } = require("genkit");
const { genkit, z } = require("genkit");
const axios = require("axios");
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
@@ -16,7 +17,7 @@ exports.generateAI = async ({ system = "", prompt = "", schema }) => {
apiKey: GEMINI_API_KEY,
}),
],
model: gemini25FlashLite,
model: googleAI.model("gemini-2.5-flash"),
});
if (prompt?.length < 1) {
@@ -34,6 +35,102 @@ exports.generateAI = async ({ system = "", prompt = "", schema }) => {
return output;
};
// Générateur d'images via appel direct REST Imagen 3.0 (retour base64 pur)
exports.generateImage = async ({ system = "", prompt = "" }) => {
if (typeof prompt !== "string" || prompt.trim().length < 1) {
throw new Error(
"Vous devez spécifier un prompt pour effectuer cette action.",
);
}
const baseUrl =
"https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-002:predict";
const url = `${baseUrl}?key=${encodeURIComponent(GEMINI_API_KEY)}`;
const mkBody = (p) => ({
instances: [
{
prompt: p,
},
],
parameters: {
sampleCount: 1,
aspectRatio: "1:1",
personGeneration: "dont_allow",
},
});
const combinedPrompt = [
system,
"Contraintes supplémentaires: pas de personnes, pas de visages, style abstrait, formes géométriques, textures et motifs.",
prompt,
]
.filter(Boolean)
.join("\n\n");
const tryOnce = async (p) => {
const resp = await axios.post(url, mkBody(p), {
headers: { "Content-Type": "application/json" },
timeout: 120000,
});
const predictions = resp?.data?.predictions || [];
const first = predictions.find((x) => x?.bytesBase64Encoded);
return first
? {
b64: first.bytesBase64Encoded,
mimeType: first.mimeType || "image/png",
}
: { b64: "", mimeType: null };
};
// Primary try
let result = { b64: "", mimeType: null };
try {
result = await tryOnce(combinedPrompt);
} catch (e) {
const em = e?.response?.data || e?.message || e;
console.error("Imagen predict error", em);
}
// Fallbacks on safety filters/no predictions
if (!result?.b64) {
const fallback = [
"Crée une image de pochette d'album 1024x1024, abstraite, moderne et colorée.",
"Utilise des formes géométriques, textures et dégradés.",
"Aucune personne, aucun visage, aucun texte, aucun logo.",
].join("\n");
try {
result = await tryOnce(fallback);
} catch (e2) {
const em2 = e2?.response?.data || e2?.message || e2;
console.error("Imagen predict fallback FR error", em2);
}
}
if (!result?.b64) {
const fallbackEn = [
"Create a 1024x1024 abstract, modern, colorful album cover.",
"Use geometric shapes, textures, and gradients.",
"No people, no faces, no text, no logos.",
].join("\n");
try {
result = await tryOnce(fallbackEn);
} catch (e3) {
const em3 = e3?.response?.data || e3?.message || e3;
console.error("Imagen predict fallback EN error", em3);
}
}
if (!result?.b64) {
throw new Error("NO_IMAGE_OUTPUT");
}
return {
b64: String(result.b64).trim(),
mimeType: result.mimeType || "image/png",
};
};
// Exporter toutes les fonctions
exports.music = require("./src/music");
exports.lyrics = require("./src/lyrics");
exports.cover = require("./src/cover");