fix: generation

This commit is contained in:
xavidop
2025-07-23 17:16:03 +02:00
parent c7f4ff9899
commit 88463d6554
2 changed files with 102 additions and 126 deletions
@@ -9,7 +9,6 @@
* - GenerateFromPhotoOutput - The return type for the generatePokemonCardFromPhoto function.
*/
import { ai } from '@/ai/genkit';
import { z } from 'genkit';
import OpenAI from 'openai';
import { getUserApiKeys } from '@/lib/firestore';
@@ -46,77 +45,66 @@ const GenerateFromPhotoOutputSchema = z.object({
export type GenerateFromPhotoOutput = z.infer<typeof GenerateFromPhotoOutputSchema>;
export async function generatePokemonCardFromPhoto(input: GenerateFromPhotoInput): Promise<GenerateFromPhotoOutput> {
return generateFromPhotoFlow(input);
}
const generateFromPhotoFlow = ai.defineFlow(
{
name: 'generateFromPhotoFlow',
inputSchema: GenerateFromPhotoInputSchema,
outputSchema: GenerateFromPhotoOutputSchema,
},
async (params: GenerateFromPhotoInput) => {
try {
// Get user's API keys from Firestore
const userApiKeys = await getUserApiKeys(params.userId);
const apiKey = userApiKeys?.openaiApiKey || process.env.OPENAI_API_KEY;
if (!apiKey) {
return {
error: 'OpenAI API key is required. Please configure your API key in Settings or set OPENAI_API_KEY environment variable.'
};
}
const openai = new OpenAI({
apiKey: apiKey,
});
// Generate the detailed prompt for the Pokemon card based on photo
console.log("Generating Pokemon card using reference photo...");
// Generate the enhanced prompt for the Pokemon card
const enhancedPrompt = generatePhotoBasedCardPrompt(params);
console.log("Generated prompt for image generation:", enhancedPrompt);
// Use OpenAI responses.create with reference image for image generation
const response = await openai.responses.create({
model: "gpt-4.1",
input: [
{
role: "user",
content: [
{ type: "input_text", text: enhancedPrompt },
{
type: "input_image",
image_url: params.photoDataUri,
detail: "high"
},
],
},
],
tools: [{ type: "image_generation" }],
});
const imageData = response.output
.filter((output) => output.type === "image_generation_call")
.map((output) => output.result);
if (imageData.length > 0) {
const imageBase64 = imageData[0];
return {
imageBase64: imageBase64 || "",
prompt: enhancedPrompt,
};
} else {
console.log("No image generated, response output:", response.output);
return { error: 'No image generated from the reference photo.' };
}
} catch (error: any) {
console.error('Error generating Pokemon card from photo:', error);
return { error: `Failed to generate Pokemon card: ${error?.message || 'Unknown error'}` };
try {
// Get user's API keys from Firestore
const userApiKeys = await getUserApiKeys(input.userId);
const apiKey = userApiKeys?.openaiApiKey || process.env.OPENAI_API_KEY;
if (!apiKey) {
return {
error: 'OpenAI API key is required. Please configure your API key in Settings or set OPENAI_API_KEY environment variable.'
};
}
const openai = new OpenAI({
apiKey: apiKey,
});
// Generate the detailed prompt for the Pokemon card based on photo
console.log("Generating Pokemon card using reference photo...");
// Generate the enhanced prompt for the Pokemon card
const enhancedPrompt = generatePhotoBasedCardPrompt(input);
console.log("Generated prompt for image generation:", enhancedPrompt);
// Use OpenAI responses.create with reference image for image generation
const response = await openai.responses.create({
model: "gpt-4.1",
input: [
{
role: "user",
content: [
{ type: "input_text", text: enhancedPrompt },
{
type: "input_image",
image_url: input.photoDataUri,
detail: "high"
},
],
},
],
tools: [{ type: "image_generation" }],
});
const imageData = response.output
.filter((output) => output.type === "image_generation_call")
.map((output) => output.result);
if (imageData.length > 0) {
const imageBase64 = imageData[0];
return {
imageBase64: imageBase64 || "",
prompt: enhancedPrompt,
};
} else {
console.log("No image generated, response output:", response.output);
return { error: 'No image generated from the reference photo.' };
}
} catch (error: any) {
console.error('Error generating Pokemon card from photo:', error);
return { error: `Failed to generate Pokemon card: ${error?.message || 'Unknown error'}` };
}
);
}
function generatePhotoBasedCardPrompt(params: GenerateFromPhotoInput): string {
const {
+44 -56
View File
@@ -9,7 +9,6 @@
* - GeneratePokemonCardOutput - The return type for the generatePokemonCard function.
*/
import { ai } from '@/ai/genkit';
import { z } from 'genkit';
import { GoogleGenAI } from '@google/genai';
import { getUserApiKeys } from '@/lib/firestore';
@@ -44,64 +43,53 @@ const GeneratePokemonCardOutputSchema = z.object({
export type GeneratePokemonCardOutput = z.infer<typeof GeneratePokemonCardOutputSchema>;
export async function generatePokemonCard(input: GeneratePokemonCardInput): Promise<GeneratePokemonCardOutput> {
return generatePokemonCardFlow(input);
}
const generatePokemonCardFlow = ai.defineFlow(
{
name: 'generatePokemonCardFlow',
inputSchema: GeneratePokemonCardInputSchema,
outputSchema: GeneratePokemonCardOutputSchema,
},
async (params: GeneratePokemonCardInput) => {
try {
// Get user's API keys from Firestore
const userApiKeys = await getUserApiKeys(params.userId);
const apiKey = userApiKeys?.geminiApiKey || process.env.GOOGLE_GENAI_API_KEY || process.env.GEMINI_API_KEY;
if (!apiKey) {
return {
error: 'Gemini API key is required. Please configure your API key in Settings or set GOOGLE_GENAI_API_KEY environment variable.'
};
}
const genAI = new GoogleGenAI({
apiKey: apiKey,
});
// Generate the detailed prompt for the Pokemon card
const prompt = generateCardPrompt(params);
console.log("Generated prompt:", prompt);
const response = await genAI.models.generateImages({
model: 'models/imagen-4.0-ultra-generate-preview-06-06',
prompt: prompt,
config: {
numberOfImages: 1,
outputMimeType: 'image/jpeg',
aspectRatio: '3:4' // Pokemon cards are roughly 3:4 aspect ratio
},
});
if (!response?.generatedImages || response.generatedImages.length === 0) {
return { error: 'No images generated.' };
}
const generatedImage = response.generatedImages[0];
if (!generatedImage?.image?.imageBytes) {
return { error: 'Generated image data is missing.' };
}
return {
imageBase64: generatedImage.image.imageBytes,
prompt: prompt,
try {
// Get user's API keys from Firestore
const userApiKeys = await getUserApiKeys(input.userId);
const apiKey = userApiKeys?.geminiApiKey || process.env.GOOGLE_GENAI_API_KEY || process.env.GEMINI_API_KEY;
if (!apiKey) {
return {
error: 'Gemini API key is required. Please configure your API key in Settings or set GOOGLE_GENAI_API_KEY environment variable.'
};
} catch (error: any) {
console.error('Error generating Pokemon card:', error);
return { error: `Failed to generate Pokemon card: ${error?.message || 'Unknown error'}` };
}
const genAI = new GoogleGenAI({
apiKey: apiKey,
});
// Generate the detailed prompt for the Pokemon card
const prompt = generateCardPrompt(input);
console.log("Generated prompt:", prompt);
const response = await genAI.models.generateImages({
model: 'models/imagen-4.0-ultra-generate-preview-06-06',
prompt: prompt,
config: {
numberOfImages: 1,
outputMimeType: 'image/jpeg',
aspectRatio: '3:4' // Pokemon cards are roughly 3:4 aspect ratio
},
});
if (!response?.generatedImages || response.generatedImages.length === 0) {
return { error: 'No images generated.' };
}
const generatedImage = response.generatedImages[0];
if (!generatedImage?.image?.imageBytes) {
return { error: 'Generated image data is missing.' };
}
return {
imageBase64: generatedImage.image.imageBytes,
prompt: prompt,
};
} catch (error: any) {
console.error('Error generating Pokemon card:', error);
return { error: `Failed to generate Pokemon card: ${error?.message || 'Unknown error'}` };
}
);
}
function generateCardPrompt(params: GeneratePokemonCardInput): string {
const {