UNPKG

minimax-mcp-tools

Version:

Async MCP server with Minimax API integration for image generation and text-to-speech

118 lines 4.3 kB
import { MinimaxBaseClient } from '../core/base-client.js'; import { API_CONFIG, DEFAULTS, MODELS, CONSTRAINTS } from '../config/constants.js'; import { FileHandler } from '../utils/file-handler.js'; import { ErrorHandler } from '../utils/error-handler.js'; export class ImageGenerationService extends MinimaxBaseClient { constructor(options = {}) { super(options); } async generateImage(params) { try { const payload = this.buildPayload(params); const response = await this.post(API_CONFIG.ENDPOINTS.IMAGE_GENERATION, payload); return await this.processImageResponse(response, params); } catch (error) { const processedError = ErrorHandler.handleAPIError(error); ErrorHandler.logError(processedError, { service: 'image', params }); throw processedError; } } buildPayload(params) { const imageDefaults = DEFAULTS.IMAGE; const model = params.style ? 'image-01-live' : 'image-01'; const payload = { model: model, prompt: params.prompt, n: 1, prompt_optimizer: true, response_format: 'url' }; if (params.customSize) { payload.width = params.customSize.width; payload.height = params.customSize.height; } else { payload.aspect_ratio = params.aspectRatio || imageDefaults.aspectRatio; } if (params.seed !== undefined) { payload.seed = params.seed; } if (model === 'image-01') { if (params.subjectReference) { payload.subject_reference = [{ type: 'character', image_file: params.subjectReference }]; } } else if (model === 'image-01-live') { if (params.style) { payload.style = { style_type: params.style.style_type, style_weight: params.style.style_weight || 0.8 }; } } return payload; } async processImageResponse(response, params) { const imageUrls = response.data?.image_urls || []; const imageBase64 = response.data?.image_base64 || []; if (!imageUrls.length && !imageBase64.length) { throw new Error('No images generated in API response'); } const savedFiles = []; const errors = []; const imageSources = imageUrls.length ? imageUrls : imageBase64; for (let i = 0; i < imageSources.length; i++) { try { const filename = FileHandler.generateUniqueFilename(params.outputFile, i, imageSources.length); if (imageBase64.length && !imageUrls.length) { await FileHandler.saveBase64Image(imageBase64[i], filename); } else { await FileHandler.downloadFile(imageSources[i], filename); } savedFiles.push(filename); } catch (error) { errors.push(`Image ${i + 1}: ${error.message}`); } } if (savedFiles.length === 0) { throw new Error(`Failed to save any images: ${errors.join('; ')}`); } const modelUsed = params.style ? 'image-01-live' : 'image-01'; const result = { files: savedFiles, count: savedFiles.length, model: modelUsed, prompt: params.prompt }; if (errors.length > 0) { result.warnings = errors; } return result; } async validateSubjectReference(reference) { if (!reference) return null; try { return await FileHandler.convertToBase64(reference); } catch (error) { throw new Error(`Invalid subject reference: ${error.message}`); } } getSupportedModels() { return Object.keys(MODELS.IMAGE); } getSupportedAspectRatios() { return CONSTRAINTS.IMAGE.ASPECT_RATIOS; } getModelInfo(modelName) { return MODELS.IMAGE[modelName] || null; } } //# sourceMappingURL=image-service.js.map