@kinetixarts/server-craft-it
Version:
Craft IT - Model Context Protocol (MCP) compliant Server for AI-Powered Asset Generation using Gemini
77 lines • 3.76 kB
JavaScript
import { GoogleGenAI, Modality } from '@google/genai';
import { v4 as uuidv4 } from 'uuid';
import { storeAsset, DEFAULT_IMAGE_PATH } from '../assetStore.js';
// The API key is required for the service to function
const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
// Throw a clear error if the API key is missing
if (!GEMINI_API_KEY) {
throw new Error('GEMINI_API_KEY is not set in environment variables. ' +
'Please provide your Gemini API key via .env file or CLI configuration.');
}
const ai = new GoogleGenAI({ apiKey: GEMINI_API_KEY });
export class ImageGenerationService {
static async generateImage({ prompt, parameters, output_config, commandLineStoragePath, }) {
// Compose the prompt with style/parameters if provided
let fullPrompt = prompt;
if (parameters) {
if (parameters.primary_color) {
fullPrompt += ` Primary color: ${parameters.primary_color}.`;
}
if (parameters.style_descriptor) {
fullPrompt += ` Style: ${parameters.style_descriptor}.`;
}
}
// Gemini requires responseModalities to include IMAGE
const response = await ai.models.generateContent({
model: 'gemini-2.0-flash-preview-image-generation',
contents: fullPrompt,
config: {
responseModalities: [Modality.TEXT, Modality.IMAGE],
},
});
if (!response.candidates || !response.candidates[0] || !response.candidates[0].content || !response.candidates[0].content.parts) {
throw new Error('No candidates or content returned from Gemini API');
}
for (const part of response.candidates[0].content.parts) {
if (part.inlineData && part.inlineData.data) {
try {
// Determine storage path priority: command line > output_config > env var > default
const storagePath = commandLineStoragePath ||
output_config.storage_path ||
DEFAULT_IMAGE_PATH;
// Generate a unique ID for this asset
const assetId = uuidv4();
// Create the initial asset data
const assetData = {
base64: part.inlineData.data,
mimeType: typeof part.inlineData.mimeType === 'string' ? part.inlineData.mimeType : 'image/png',
};
// Store the asset both in memory and on disk
const storedAsset = await storeAsset(assetId, assetData, storagePath);
// Return the complete result
// Return the complete result
const result = {
id: assetId,
base64: storedAsset.base64,
mimeType: storedAsset.mimeType,
filePath: storedAsset.filePath,
};
return result;
}
catch (error) {
console.error('Error storing generated image:', error);
// Return just the image data if storage fails
// Return just the image data if storage fails
const result = {
id: uuidv4(),
base64: part.inlineData.data,
mimeType: typeof part.inlineData.mimeType === 'string' ? part.inlineData.mimeType : 'image/png',
};
return result;
}
}
}
throw new Error('No image data returned from Gemini API');
}
}
//# sourceMappingURL=ImageGenerationService.js.map