OpenMAIC-React / src /lib /media /image-providers.ts
muthuk1's picture
Convert OpenMAIC from Next.js to React (Vite)
f56a29b verified
/**
* Image Generation Service -- routes to provider adapters
*/
import type {
ImageProviderId,
ImageGenerationConfig,
ImageGenerationOptions,
ImageGenerationResult,
ImageProviderConfig,
} from './types';
import { generateWithSeedream, testSeedreamConnectivity } from './adapters/seedream-adapter';
import {
generateWithOpenAIImage,
testOpenAIImageConnectivity,
} from './adapters/openai-image-adapter';
import { generateWithQwenImage, testQwenImageConnectivity } from './adapters/qwen-image-adapter';
import { generateWithNanoBanana, testNanoBananaConnectivity } from './adapters/nano-banana-adapter';
import {
generateWithMiniMaxImage,
testMiniMaxImageConnectivity,
} from './adapters/minimax-image-adapter';
import { generateWithGrokImage, testGrokImageConnectivity } from './adapters/grok-image-adapter';
export const IMAGE_PROVIDERS: Record<ImageProviderId, ImageProviderConfig> = {
seedream: {
id: 'seedream',
name: 'Seedream',
requiresApiKey: true,
defaultBaseUrl: 'https://ark.cn-beijing.volces.com',
models: [
{ id: 'doubao-seedream-5-0-260128', name: 'Seedream 5.0 Lite' },
{ id: 'doubao-seedream-4-5-251128', name: 'Seedream 4.5' },
{ id: 'doubao-seedream-4-0-250828', name: 'Seedream 4.0' },
{ id: 'doubao-seedream-3-0-t2i-250415', name: 'Seedream 3.0' },
],
supportedAspectRatios: ['16:9', '4:3', '1:1', '9:16'],
},
'openai-image': {
id: 'openai-image',
name: 'OpenAI Image',
requiresApiKey: true,
defaultBaseUrl: 'https://api.openai.com/v1',
models: [
{ id: 'gpt-image-2', name: 'GPT Image 2' },
{ id: 'gpt-image-2-2026-04-21', name: 'GPT Image 2 (2026-04-21)' },
{ id: 'gpt-image-1.5', name: 'GPT Image 1.5' },
{ id: 'gpt-image-1', name: 'GPT Image 1' },
{ id: 'gpt-image-1-mini', name: 'GPT Image 1 Mini' },
{ id: 'chatgpt-image-latest', name: 'ChatGPT Image Latest' },
],
supportedAspectRatios: ['16:9', '4:3', '1:1', '9:16'],
},
'qwen-image': {
id: 'qwen-image',
name: 'Qwen Image',
requiresApiKey: true,
defaultBaseUrl: 'https://dashscope.aliyuncs.com',
models: [
{ id: 'qwen-image-2.0-pro', name: 'Qwen Image 2.0 Pro' },
{ id: 'qwen-image-2.0-pro-2026-03-03', name: 'Qwen Image 2.0 Pro (2026-03-03)' },
{ id: 'qwen-image-2.0', name: 'Qwen Image 2.0' },
{ id: 'qwen-image-2.0-2026-03-03', name: 'Qwen Image 2.0 (2026-03-03)' },
{ id: 'qwen-image-max', name: 'Qwen Image Max' },
{ id: 'qwen-image-max-2025-12-30', name: 'Qwen Image Max (2025-12-30)' },
{ id: 'qwen-image-plus', name: 'Qwen Image Plus' },
{
id: 'qwen-image-plus-2026-01-09',
name: 'Qwen Image Plus (2026-01-09)',
},
{ id: 'qwen-image', name: 'Qwen Image' },
{ id: 'z-image-turbo', name: 'Z-Image Turbo' },
],
supportedAspectRatios: ['16:9', '4:3', '1:1', '9:16'],
},
'nano-banana': {
id: 'nano-banana',
name: 'Nano Banana (Gemini)',
requiresApiKey: true,
defaultBaseUrl: 'https://generativelanguage.googleapis.com',
models: [
{
id: 'gemini-3.1-flash-image-preview',
name: 'Gemini 3.1 Flash Image (Nano Banana 2)',
},
{
id: 'gemini-3-pro-image-preview',
name: 'Gemini 3 Pro Image (Nano Banana Pro)',
},
{
id: 'gemini-2.5-flash-image',
name: 'Gemini 2.5 Flash Image (Nano Banana)',
},
],
supportedAspectRatios: ['16:9', '4:3', '1:1'],
},
'minimax-image': {
id: 'minimax-image',
name: 'MiniMax Image',
requiresApiKey: true,
defaultBaseUrl: 'https://api.minimaxi.com',
models: [
{ id: 'image-01', name: 'Image 01' },
{ id: 'image-01-live', name: 'Image 01 Live' },
],
supportedAspectRatios: ['16:9', '4:3', '1:1', '9:16'],
},
'grok-image': {
id: 'grok-image',
name: 'Grok Image (xAI)',
requiresApiKey: true,
defaultBaseUrl: 'https://api.x.ai/v1',
models: [
{ id: 'grok-imagine-image', name: 'Grok Imagine Image' },
{ id: 'grok-imagine-image-pro', name: 'Grok Imagine Image Pro' },
],
supportedAspectRatios: ['16:9', '4:3', '1:1', '9:16'],
},
};
export async function testImageConnectivity(
config: ImageGenerationConfig,
): Promise<{ success: boolean; message: string }> {
switch (config.providerId) {
case 'seedream':
return testSeedreamConnectivity(config);
case 'openai-image':
return testOpenAIImageConnectivity(config);
case 'qwen-image':
return testQwenImageConnectivity(config);
case 'nano-banana':
return testNanoBananaConnectivity(config);
case 'minimax-image':
return testMiniMaxImageConnectivity(config);
case 'grok-image':
return testGrokImageConnectivity(config);
default:
return {
success: false,
message: `Unsupported image provider: ${config.providerId}`,
};
}
}
export async function generateImage(
config: ImageGenerationConfig,
options: ImageGenerationOptions,
): Promise<ImageGenerationResult> {
switch (config.providerId) {
case 'seedream':
return generateWithSeedream(config, options);
case 'openai-image':
return generateWithOpenAIImage(config, options);
case 'qwen-image':
return generateWithQwenImage(config, options);
case 'nano-banana':
return generateWithNanoBanana(config, options);
case 'minimax-image':
return generateWithMiniMaxImage(config, options);
case 'grok-image':
return generateWithGrokImage(config, options);
default:
throw new Error(`Unsupported image provider: ${config.providerId}`);
}
}
export function aspectRatioToDimensions(
ratio: string,
maxWidth = 1024,
): { width: number; height: number } {
const [w, h] = ratio.split(':').map(Number);
if (!w || !h) return { width: maxWidth, height: Math.round((maxWidth * 9) / 16) };
return { width: maxWidth, height: Math.round((maxWidth * h) / w) };
}