234 lines
9.3 KiB
TypeScript
234 lines
9.3 KiB
TypeScript
|
|
import { GoogleGenAI, Type, Part } from "@google/genai";
|
|
import { ProductPackage, AspectRatio, ImageSize, ProductType, CreativityLevel } from "./types";
|
|
|
|
const creativityMap: Record<CreativityLevel, number> = {
|
|
"Literal": 0.2,
|
|
"Balanced": 0.7,
|
|
"Artistic": 1.1,
|
|
"Avant-Garde": 1.6,
|
|
"Conservative": 0.3,
|
|
"Wild": 1.4
|
|
};
|
|
|
|
// ---------------------------------------------------------
|
|
// SYSTEM PERSONA DEFINITION
|
|
// ---------------------------------------------------------
|
|
const SYSTEM_INSTRUCTION = `
|
|
You are an elite AI Fusion Entity possessing the combined expertise of:
|
|
1. Global Etsy E-commerce Strategist (Market Trends 2024-2025)
|
|
2. Senior Art Director & Creative Lead (Impeccable Taste)
|
|
3. Neuromarketing Expert (Dopamine & Serotonin Visual Triggers)
|
|
4. SEO Visual Specialist (Search Intent Optimization)
|
|
5. Nano Banana / Stable Diffusion Prompt Engineer (Tag & Weight Mastery)
|
|
|
|
OBJECTIVE:
|
|
Translate raw user ideas into a "Commercial Masterpiece" Digital Product Package.
|
|
|
|
CORE ANALYSIS WORKFLOW (Internal Monologue):
|
|
Before generating output, perform this split-second analysis:
|
|
1. Market Fit: Identify the trending style for this niche (e.g. Boho, Minimalist, Dark Academia).
|
|
2. Neuro-Trigger: Define the emotion to sell (Calm, Joy, Nostalgia).
|
|
3. Composition: Plan the perfect thumbnail click composition.
|
|
|
|
PROMPT FORMULA (Strict Adherence):
|
|
The 'imagePrompt' MUST be a comma-separated string following this 'Nano Banana' structure:
|
|
[Quality & Neuro Boosters], [Subject with Art Direction], [Environment & Context], [Artistic Medium & Style], [Color Palette & Lighting], [Tech Specs]
|
|
|
|
MANDATORY BOOSTERS TO START:
|
|
(masterpiece:1.4), (best quality), (ultra-detailed), (commercial photography), (professional color grading), 8k resolution, (sharp focus), aesthetic, trending on etsy
|
|
|
|
EXAMPLE OUTPUT PROMPT:
|
|
"(masterpiece:1.4), (best quality), (ultra-detailed), 8k, professional wall art, (minimalist yoga pose illustration:1.3), continuous line art style, abstract shapes, organic forms, (earthy color palette:1.2), terracotta and beige tones, soft textured paper background, zen atmosphere, (calming aesthetic), clean composition, interior design mockup style, soft studio lighting, 300 dpi"
|
|
`;
|
|
|
|
/**
|
|
* MODULE 1: Generates the specialized SEO and Prompt package using the 5-Layer Persona.
|
|
*/
|
|
export const generateProductPackage = async (
|
|
niche: string,
|
|
productType: ProductType,
|
|
creativity: CreativityLevel,
|
|
referenceImages?: string[]
|
|
): Promise<ProductPackage> => {
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
|
|
const parts: Part[] = [
|
|
{ text: SYSTEM_INSTRUCTION },
|
|
{
|
|
text: `
|
|
TASK: Architect a High-Conversion ${productType} for the niche: "${niche}".
|
|
|
|
OUTPUT REQUIREMENTS (JSON):
|
|
1. imagePrompt: The Nano Banana optimized tag string (English).
|
|
2. seoTitle: Ultra-SEO optimized title (English).
|
|
3. keywords: 13 golden tags (English).
|
|
4. description: Neuro-marketing copy (English).
|
|
5. suggestedPrice: Competitive Etsy pricing.
|
|
6. printingGuide: Technical setup (English).
|
|
` }
|
|
];
|
|
|
|
if (referenceImages && referenceImages.length > 0) {
|
|
referenceImages.forEach(b64 => {
|
|
parts.push({ inlineData: { data: b64.split(',')[1], mimeType: 'image/png' } });
|
|
});
|
|
}
|
|
|
|
const response = await ai.models.generateContent({
|
|
model: "gemini-2.0-flash", // HYBRID STRATEGY: Flash Brain (Cost Optimized)
|
|
contents: { parts },
|
|
config: {
|
|
temperature: creativityMap[creativity],
|
|
responseMimeType: "application/json",
|
|
responseSchema: {
|
|
type: Type.OBJECT,
|
|
properties: {
|
|
imagePrompt: { type: Type.STRING },
|
|
seoTitle: { type: Type.STRING },
|
|
keywords: { type: Type.ARRAY, items: { type: Type.STRING } },
|
|
description: { type: Type.STRING },
|
|
suggestedPrice: { type: Type.STRING },
|
|
printingGuide: { type: Type.STRING }
|
|
},
|
|
required: ["imagePrompt", "seoTitle", "keywords", "description", "suggestedPrice", "printingGuide"]
|
|
}
|
|
}
|
|
});
|
|
|
|
return JSON.parse(response.text || "{}");
|
|
};
|
|
|
|
/**
|
|
* MODULE 2: MASTER ASSET GENERATION
|
|
* Uses the Optimized Prompt to generate the visual.
|
|
*/
|
|
export const generateImage = async (
|
|
prompt: string,
|
|
aspectRatio: AspectRatio,
|
|
size: ImageSize,
|
|
productType: ProductType,
|
|
referenceImages?: string[]
|
|
): Promise<string> => {
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
|
|
// Apply Product-Specific Composition Rules as a "Guidance Layer" on top of the prompt
|
|
let compositionGuidance = "";
|
|
if (productType === "Sticker") compositionGuidance = "Ensure the subject is isolated on a clean white background with a thick white sticker border (die-cut style). No drop shadows.";
|
|
if (productType === "Bookmark") compositionGuidance = "Ensure a narrow vertical composition suitable for a bookmark. Decorative borders.";
|
|
|
|
const masterPrompt = `
|
|
Act as the Senior Art Director & Visual Engine.
|
|
|
|
INPUT PROMPT (Nano Banana Format):
|
|
${prompt}
|
|
|
|
ADDITIONAL TECHNICAL GUIDANCE:
|
|
${compositionGuidance}
|
|
|
|
EXECUTION:
|
|
Generate the image adhering strictly to the aesthetic quality defined in the prompt tags.
|
|
`;
|
|
|
|
const parts: Part[] = [{ text: masterPrompt }];
|
|
|
|
if (referenceImages && referenceImages.length > 0) {
|
|
referenceImages.forEach(b64 => parts.push({ inlineData: { data: b64.split(',')[1], mimeType: 'image/png' } }));
|
|
}
|
|
|
|
const response = await ai.models.generateContent({
|
|
model: 'gemini-2.5-flash-image', // Or 'gemini-3-pro-image-preview' if available/preferred
|
|
contents: { parts },
|
|
config: { imageConfig: { aspectRatio, imageSize: size } }
|
|
});
|
|
|
|
const part = response.candidates?.[0]?.content?.parts?.find(p => p.inlineData);
|
|
return part?.inlineData ? `data:image/png;base64,${part.inlineData.data}` : "";
|
|
};
|
|
|
|
/**
|
|
* MODULE 3: MOCKUP SCENARIOS
|
|
*/
|
|
export const MOCKUP_SCENARIOS: Record<ProductType, string[]> = {
|
|
"Wall Art": ["Luxury penthouse gallery wall", "Modern kitchen breakfast nook", "Studio easel"],
|
|
"Bookmark": ["Tucked in a vintage book", "Flatlay with coffee", "Held in a journal"],
|
|
"Sticker": ["On a laptop lid", "On a hydroflask", "In a planner spread"],
|
|
"Planner": ["On a high-end tablet", "Minimalist desk setup", "Hand-held digital view"],
|
|
"Phone Wallpaper": ["Smartphone lifestyle photo", "Marble nightstand", "Lockscreen preview"],
|
|
"Social Media Kit": ["Grid preview", "Marketing agency desk", "Mobile profile layout"],
|
|
"Label": ["Product bottle mockup", "Jar label display", "Package shelf"]
|
|
};
|
|
|
|
/**
|
|
* MODULE 4: GENERATE SINGLE MOCKUP
|
|
*/
|
|
export const generateSingleMockup = async (base64Image: string, productType: ProductType, scenario: string): Promise<string> => {
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
const response = await ai.models.generateContent({
|
|
model: 'gemini-2.5-flash-image',
|
|
contents: {
|
|
parts: [
|
|
{ inlineData: { data: base64Image.split(',')[1], mimeType: 'image/png' } },
|
|
{ text: `Mockup Scenario: This ${productType} asset used in a ${scenario}. Realistic, professional commercial photography, soft studio lighting, 8k, highly detailed.` }
|
|
]
|
|
}
|
|
});
|
|
const part = response.candidates?.[0]?.content?.parts?.find(p => p.inlineData);
|
|
return part?.inlineData ? `data:image/png;base64,${part.inlineData.data}` : "";
|
|
};
|
|
|
|
/**
|
|
* MODULE 5: PRECISION REVISION
|
|
* Maintains the Expert Persona for revisions.
|
|
*/
|
|
export const performPrecisionRevision = async (base64Image: string, revisionBrief: string): Promise<{ image: string, optimizedPrompt: string }> => {
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
|
|
// 1. Translate and Optimize
|
|
const translationResponse = await ai.models.generateContent({
|
|
model: 'gemini-2.0-flash', // Cost Optimized Brain
|
|
contents: `
|
|
You are the "Nano Banana Prompt Engineer".
|
|
|
|
TASK: Translate the revision brief: "${revisionBrief}" into a comma-separated English tag list (Nano Banana format).
|
|
It should describe the NEW DESIRED STATE of the image.
|
|
|
|
Keep the original specific style tags unless the brief explicitly changes them.
|
|
Output ONLY the tag string.
|
|
`
|
|
});
|
|
const optimizedPrompt = translationResponse.text || revisionBrief;
|
|
|
|
// 2. Perform the Edit
|
|
const editResponse = await ai.models.generateContent({
|
|
model: 'gemini-2.5-flash-image',
|
|
contents: {
|
|
parts: [
|
|
{ inlineData: { data: base64Image.split(',')[1], mimeType: 'image/png' } },
|
|
{ text: `Precision Edit Instruction: Based on these tags: ${optimizedPrompt}. Maintain high fidelity and consistent art style.` }
|
|
]
|
|
}
|
|
});
|
|
|
|
const part = editResponse.candidates?.[0]?.content?.parts.find(p => p.inlineData);
|
|
const newImage = part?.inlineData ? `data:image/png;base64,${part.inlineData.data}` : base64Image;
|
|
|
|
return { image: newImage, optimizedPrompt };
|
|
};
|
|
|
|
/**
|
|
* MODULE 6: COMPETITOR ANALYSIS
|
|
*/
|
|
export const analyzeCompetitors = async (niche: string): Promise<{ text: string; sources: any[] }> => {
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
const response = await ai.models.generateContent({
|
|
model: 'gemini-3-flash-preview',
|
|
contents: `Act as an E-commerce Market Specialist. Analyze current Etsy trends for: "${niche}". Focus on visual style, color palettes, and top-selling themes.`,
|
|
config: { tools: [{ googleSearch: {} }] }
|
|
});
|
|
return {
|
|
text: response.text || "",
|
|
sources: response.candidates?.[0]?.groundingMetadata?.groundingChunks || []
|
|
};
|
|
};
|