diff --git a/src/app/api/generate/route.ts b/src/app/api/generate/route.ts index 56eeb440..85f60496 100644 --- a/src/app/api/generate/route.ts +++ b/src/app/api/generate/route.ts @@ -1258,8 +1258,7 @@ async function generateWithFalQueue( */ function getKieModelDefaults(modelId: string): Record { switch (modelId) { - // GPT Image models require aspect_ratio and quality - // Only supports: 1:1, 2:3, 3:2 (default 3:2 = landscape) + // GPT Image models case "gpt-image/1.5-text-to-image": case "gpt-image/1.5-image-to-image": return { @@ -1278,76 +1277,7 @@ function getKieModelDefaults(modelId: string): Record { case "seedream/4.5-edit": return { aspect_ratio: "1:1", - }; - - // Nano Banana Pro (Kie's version) - case "nano-banana-pro": - return { - aspect_ratio: "1:1", - }; - - // Google Nano Banana models - case "google/nano-banana": - case "google/nano-banana-edit": - return { - aspect_ratio: "1:1", - }; - - // Sora video models - case "sora-2-text-to-video": - case "sora-2-image-to-video": - case "sora-2-pro-text-to-video": - case "sora-2-pro-image-to-video": - return { - aspect_ratio: "16:9", - duration: "5", - }; - - // Veo video models (use camelCase) - case "veo3": - case "veo3_fast": - return { - aspectRatio: "16:9", - }; - - // Bytedance Seedance - case "bytedance/seedance-1.5-pro": - return { - aspect_ratio: "16:9", - duration: "5", - }; - - // Kling video models - case "kling-2.6/text-to-video": - case "kling-2.6/image-to-video": - return { - aspect_ratio: "16:9", - duration: "5", - }; - - // Wan video models - case "wan/2-6-text-to-video": - case "wan/2-6-image-to-video": - case "wan/2-2-a14b-text-to-video-turbo": - case "wan/2-2-a14b-image-to-video-turbo": - case "wan/2-6-video-to-video": - return { - aspect_ratio: "16:9", - duration: "5", - }; - - // Imagen 4 models - case "google/imagen4": - case "google/imagen4-fast": - case "google/imagen4-ultra": - return { - aspect_ratio: "1:1", - }; - - // Google Pro image-to-image - case "google/pro-image-to-image": - return { - aspect_ratio: "1:1", + quality: "basic", }; // Flux-2 models @@ -1359,82 +1289,73 @@ function getKieModelDefaults(modelId: string): Record { aspect_ratio: "1:1", }; - // Flux Kontext models (camelCase params, top-level) - case "flux-kontext-pro": - case "flux-kontext-max": - return { - aspectRatio: "1:1", - outputFormat: "png", - }; - - // Grok Imagine models + // Grok Imagine image models case "grok-imagine/text-to-image": - case "grok-imagine/image-to-image": return { aspect_ratio: "1:1", }; + case "grok-imagine/image-to-image": + return {}; + // Grok Imagine video models case "grok-imagine/text-to-video": - case "grok-imagine/image-to-video": return { - aspect_ratio: "16:9", - duration: "5", + aspect_ratio: "2:3", + duration: "6", + mode: "normal", }; - // Ideogram models - case "ideogram/v3-reframe": - case "ideogram/character": - case "ideogram/character-edit": + case "grok-imagine/image-to-video": return { - aspect_ratio: "1:1", + aspect_ratio: "2:3", + duration: "6", + mode: "normal", }; - // Qwen models - case "qwen/text-to-image": - case "qwen/image-to-image": - case "qwen/image-edit": + // Kling 2.6 video models + case "kling-2.6/text-to-video": + case "kling-2.6/image-to-video": return { - aspect_ratio: "1:1", + aspect_ratio: "16:9", + duration: "5", + sound: true, }; - // Runway models (camelCase params, top-level) - case "runway/gen4": - case "runway/aleph": + // Kling 2.6 motion control + case "kling-2.6/motion-control": return { - aspectRatio: "16:9", - duration: 10, + mode: "720p", + character_orientation: "video", }; - // Hailuo video models - case "hailuo/2-3-image-to-video-pro": - case "hailuo/2-3-image-to-video-standard": - case "hailuo/02-text-to-video-pro": - case "hailuo/02-image-to-video-pro": + // Kling 2.5 turbo models + case "kling/v2-5-turbo-text-to-video-pro": + case "kling/v2-5-turbo-image-to-video-pro": return { aspect_ratio: "16:9", duration: "5", + cfg_scale: 0.5, }; - // Bytedance Seedance variants - case "bytedance/v1-pro-text-to-video": - case "bytedance/v1-pro-image-to-video": - case "bytedance/v1-pro-fast-image-to-video": - case "bytedance/v1-lite-text-to-video": - case "bytedance/v1-lite-image-to-video": + // Wan video models + case "wan/2-6-text-to-video": + case "wan/2-6-image-to-video": return { - aspect_ratio: "16:9", duration: "5", + resolution: "1080p", }; - // Kling older models - case "kling/v2-1-master-text-to-video": - case "kling/v2-1-master-image-to-video": - case "kling/v2-5-turbo-text-to-video-pro": - case "kling/v2-5-turbo-image-to-video-pro": + case "wan/2-6-video-to-video": return { - aspect_ratio: "16:9", duration: "5", + resolution: "1080p", + }; + + // Topaz video upscale + case "topaz/video-upscale": + return { + upscale_factor: "2", }; default: @@ -1447,38 +1368,20 @@ function getKieModelDefaults(modelId: string): Record { */ function getKieImageInputKey(modelId: string): string { // Model-specific parameter names - if (modelId === "nano-banana-pro") return "image_input"; if (modelId === "seedream/4.5-edit") return "image_urls"; if (modelId === "gpt-image/1.5-image-to-image") return "input_urls"; - if (modelId === "veo3" || modelId === "veo3_fast") return "imageUrls"; - // Flux Kontext uses singular image_url - if (modelId.startsWith("flux-kontext-")) return "image_url"; - // Runway uses camelCase imageUrl - if (modelId.startsWith("runway/")) return "imageUrl"; + // Flux-2 I2I models use input_urls + if (modelId === "flux-2/pro-image-to-image" || modelId === "flux-2/flex-image-to-image") return "input_urls"; + // Kling 2.5 turbo I2V uses singular image_url + if (modelId === "kling/v2-5-turbo-image-to-video-pro") return "image_url"; + // Kling 2.6 motion control uses input_urls + if (modelId === "kling-2.6/motion-control") return "input_urls"; + // Topaz video upscale uses video_url (singular) + if (modelId === "topaz/video-upscale") return "video_url"; // Default for most models return "image_urls"; } -/** - * Check if a model is a Veo model (uses different API endpoint) - */ -function isKieVeoModel(modelId: string): boolean { - return modelId === "veo3" || modelId === "veo3_fast"; -} - -/** - * Check if a model is a Flux Kontext model (uses dedicated endpoint) - */ -function isKieFluxKontextModel(modelId: string): boolean { - return modelId.startsWith("flux-kontext-"); -} - -/** - * Check if a model is a Runway model (uses dedicated endpoint) - */ -function isKieRunwayModel(modelId: string): boolean { - return modelId.startsWith("runway/"); -} /** * Detect actual image type from binary data (magic bytes) @@ -1585,17 +1488,13 @@ async function pollKieTaskCompletion( requestId: string, apiKey: string, taskId: string, - isVeo: boolean ): Promise<{ success: boolean; data?: Record; error?: string }> { const maxWaitTime = 10 * 60 * 1000; // 10 minutes for video const pollInterval = 2000; // 2 seconds const startTime = Date.now(); let lastStatus = ""; - // Different endpoints for Veo vs standard models - const pollUrl = isVeo - ? `https://api.kie.ai/api/v1/veo/record-info?taskId=${taskId}` - : `https://api.kie.ai/api/v1/jobs/recordInfo?taskId=${taskId}`; + const pollUrl = `https://api.kie.ai/api/v1/jobs/recordInfo?taskId=${taskId}`; while (true) { if (Date.now() - startTime > maxWaitTime) { @@ -1645,11 +1544,8 @@ async function generateWithKie( input: GenerationInput ): Promise { const modelId = input.model.id; - const isVeo = isKieVeoModel(modelId); - const isFluxKontext = isKieFluxKontextModel(modelId); - const isRunway = isKieRunwayModel(modelId); - console.log(`[API:${requestId}] Kie.ai generation - Model: ${modelId}, Images: ${input.images?.length || 0}, Prompt: ${input.prompt.length} chars, Veo: ${isVeo}, FluxKontext: ${isFluxKontext}, Runway: ${isRunway}`); + console.log(`[API:${requestId}] Kie.ai generation - Model: ${modelId}, Images: ${input.images?.length || 0}, Prompt: ${input.prompt.length} chars`); // Build the input object (all parameters go inside "input" for Kie API) // Start with model-specific required defaults @@ -1688,8 +1584,12 @@ async function generateWithKie( // Set the correct parameter name for this model const imageKey = getKieImageInputKey(modelId); - // All image params are arrays in Kie API - inputParams[imageKey] = imageUrls; + // Some models use singular string, others use arrays + if (imageKey === "image_url" || imageKey === "video_url") { + inputParams[imageKey] = imageUrls[0]; + } else { + inputParams[imageKey] = imageUrls; + } } // Handle dynamic inputs (from schema-mapped connections) @@ -1700,7 +1600,12 @@ async function generateWithKie( if (typeof value === 'string' && value.startsWith('data:image')) { // Single data URL - upload it const url = await uploadImageToKie(requestId, apiKey, value); - inputParams[key] = [url]; + // Singular keys get a string, plural keys get an array + if (key === "image_url" || key === "video_url" || key === "tail_image_url") { + inputParams[key] = url; + } else { + inputParams[key] = [url]; + } } else if (Array.isArray(value)) { // Array of values - check if they're data URLs that need uploading const processedArray: string[] = []; @@ -1724,72 +1629,13 @@ async function generateWithKie( } } - // Build request body - dedicated endpoints use top-level params (no input wrapper) - let requestBody: Record; - - if (isVeo) { - // Veo format: { model, prompt, aspectRatio, imageUrls, generationType } - requestBody = { - model: modelId, - prompt: inputParams.prompt, - aspectRatio: inputParams.aspectRatio || inputParams.aspect_ratio || "16:9", - generationType: inputParams.imageUrls || inputParams.image_urls - ? "FIRST_AND_LAST_FRAMES_2_VIDEO" - : "TEXT_2_VIDEO", - }; - // Add image URLs if present - if (inputParams.imageUrls) { - requestBody.imageUrls = inputParams.imageUrls; - } else if (inputParams.image_urls) { - requestBody.imageUrls = inputParams.image_urls; - } - } else if (isFluxKontext) { - // Flux Kontext format: top-level camelCase params, model name derived from ID - requestBody = { - model: modelId === "flux-kontext-max" ? "max" : "pro", - prompt: inputParams.prompt, - aspectRatio: inputParams.aspectRatio || inputParams.aspect_ratio || "1:1", - }; - if (inputParams.outputFormat) requestBody.outputFormat = inputParams.outputFormat; - if (inputParams.safetyTolerance !== undefined) requestBody.safetyTolerance = inputParams.safetyTolerance; - if (inputParams.seed !== undefined) requestBody.seed = inputParams.seed; - // Singular image_url for Kontext - if (inputParams.image_url) { - requestBody.image_url = Array.isArray(inputParams.image_url) ? inputParams.image_url[0] : inputParams.image_url; - } - } else if (isRunway) { - // Runway format: top-level camelCase params - requestBody = { - model: modelId, - prompt: inputParams.prompt, - aspectRatio: inputParams.aspectRatio || inputParams.aspect_ratio || "16:9", - }; - if (inputParams.duration !== undefined) requestBody.duration = inputParams.duration; - if (inputParams.quality) requestBody.quality = inputParams.quality; - if (inputParams.seed !== undefined) requestBody.seed = inputParams.seed; - // Singular imageUrl for Runway - if (inputParams.imageUrl) { - requestBody.imageUrl = Array.isArray(inputParams.imageUrl) ? inputParams.imageUrl[0] : inputParams.imageUrl; - } - } else { - // Standard format: { model, input: { ... } } - requestBody = { - model: modelId, - input: inputParams, - }; - } + // All remaining Kie models use the standard createTask endpoint + const requestBody: Record = { + model: modelId, + input: inputParams, + }; - // Select endpoint based on model type - let createUrl: string; - if (isVeo) { - createUrl = "https://api.kie.ai/api/v1/veo/generate"; - } else if (isFluxKontext) { - createUrl = "https://api.kie.ai/api/v1/flux/kontext/generate"; - } else if (isRunway) { - createUrl = "https://api.kie.ai/api/v1/runway/generate"; - } else { - createUrl = "https://api.kie.ai/api/v1/jobs/createTask"; - } + const createUrl = "https://api.kie.ai/api/v1/jobs/createTask"; console.log(`[API:${requestId}] Calling Kie.ai API: ${createUrl}`); // Log full request body for debugging (truncate very long prompts) @@ -1861,7 +1707,7 @@ async function generateWithKie( console.log(`[API:${requestId}] Kie task created: ${taskId}`); // Poll for completion - const pollResult = await pollKieTaskCompletion(requestId, apiKey, taskId, isVeo); + const pollResult = await pollKieTaskCompletion(requestId, apiKey, taskId); if (!pollResult.success) { return { diff --git a/src/app/api/models/[modelId]/route.ts b/src/app/api/models/[modelId]/route.ts index 5f005f57..6b9c75c3 100644 --- a/src/app/api/models/[modelId]/route.ts +++ b/src/app/api/models/[modelId]/route.ts @@ -496,43 +496,37 @@ function extractParametersFromSchema( function getKieSchema(modelId: string): ExtractedSchema { // Common parameters for image models const imageParams: ModelParameter[] = [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"], default: "1:1" }, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["1:1", "4:3", "3:4", "16:9", "9:16"], default: "1:1" }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ]; - // Common parameters for video models - const videoParams: ModelParameter[] = [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 20, default: 10 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ]; + // Flux-2 aspect ratios (includes auto and additional ratios) + const flux2AspectRatios = ["1:1", "4:3", "3:4", "16:9", "9:16", "3:2", "2:3", "auto"]; // Model-specific schemas const schemas: Record = { - // Image models + // ============ Image models ============ "z-image": { parameters: imageParams, inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "seedream/4.5-text-to-image": { - parameters: imageParams, + parameters: [ + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["1:1", "4:3", "3:4", "16:9", "9:16", "2:3", "3:2", "21:9"], default: "1:1" }, + { name: "quality", type: "string", description: "Output quality", enum: ["basic", "high"], default: "basic" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, + ], inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "seedream/4.5-edit": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "nano-banana-pro": { parameters: [ - ...imageParams, - { name: "resolution", type: "string", description: "Output resolution", enum: ["1K", "2K", "4K"], default: "1K" }, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["1:1", "4:3", "3:4", "16:9", "9:16", "2:3", "3:2", "21:9"], default: "1:1" }, + { name: "quality", type: "string", description: "Output quality", enum: ["basic", "high"], default: "basic" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [ { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_input", type: "image", required: false, label: "Image" }, + { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, "gpt-image/1.5-text-to-image": { @@ -552,363 +546,150 @@ function getKieSchema(modelId: string): ExtractedSchema { { name: "input_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "google/nano-banana": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "google/nano-banana-edit": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - // Video models - "sora-2-text-to-video": { - parameters: videoParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "sora-2-image-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "sora-2-pro-text-to-video": { - parameters: videoParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "sora-2-pro-image-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "veo3_fast": { - parameters: [ - { name: "aspectRatio", type: "string", description: "Output aspect ratio (camelCase for Veo)", enum: ["16:9", "9:16"], default: "16:9" }, - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 8, default: 8 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "imageUrls", type: "image", required: false, label: "Image", isArray: true }, - ], - }, - "veo3": { - parameters: [ - { name: "aspectRatio", type: "string", description: "Output aspect ratio (camelCase for Veo)", enum: ["16:9", "9:16"], default: "16:9" }, - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 8, default: 8 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "imageUrls", type: "image", required: false, label: "Image", isArray: true }, - ], - }, - "bytedance/seedance-1.5-pro": { - parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "number", description: "Video duration in seconds", minimum: 5, maximum: 10, default: 5 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: false, label: "Image", isArray: true }, - ], - }, - "kling-2.6/text-to-video": { - parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "kling-2.6/image-to-video": { - parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "wan/2-6-text-to-video": { - parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 10, default: 5 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "wan/2-6-image-to-video": { - parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 10, default: 5 }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - // --- New image models --- - "google/imagen4": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "google/imagen4-fast": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "google/imagen4-ultra": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "google/pro-image-to-image": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, "flux-2/pro-text-to-image": { parameters: [ - ...imageParams, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: flux2AspectRatios, default: "1:1" }, { name: "resolution", type: "string", description: "Output resolution", enum: ["1K", "2K"], default: "1K" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "flux-2/pro-image-to-image": { parameters: [ - ...imageParams, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: flux2AspectRatios, default: "1:1" }, { name: "resolution", type: "string", description: "Output resolution", enum: ["1K", "2K"], default: "1K" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [ { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + { name: "input_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, "flux-2/flex-text-to-image": { parameters: [ - ...imageParams, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: flux2AspectRatios, default: "1:1" }, { name: "resolution", type: "string", description: "Output resolution", enum: ["1K", "2K"], default: "1K" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "flux-2/flex-image-to-image": { parameters: [ - ...imageParams, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: flux2AspectRatios, default: "1:1" }, { name: "resolution", type: "string", description: "Output resolution", enum: ["1K", "2K"], default: "1K" }, - ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "flux-kontext-pro": { - parameters: [ - { name: "aspectRatio", type: "string", description: "Output aspect ratio", enum: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"], default: "1:1" }, - { name: "outputFormat", type: "string", description: "Output image format", enum: ["png", "jpeg", "webp"], default: "png" }, - { name: "safetyTolerance", type: "integer", description: "Safety tolerance level (0=strict, 6=permissive)", minimum: 0, maximum: 6, default: 2 }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [ { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_url", type: "image", required: false, label: "Image" }, + { name: "input_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "flux-kontext-max": { + "grok-imagine/text-to-image": { parameters: [ - { name: "aspectRatio", type: "string", description: "Output aspect ratio", enum: ["1:1", "16:9", "9:16", "4:3", "3:4", "21:9", "9:21"], default: "1:1" }, - { name: "outputFormat", type: "string", description: "Output image format", enum: ["png", "jpeg", "webp"], default: "png" }, - { name: "safetyTolerance", type: "integer", description: "Safety tolerance level (0=strict, 6=permissive)", minimum: 0, maximum: 6, default: 2 }, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["2:3", "3:2", "1:1", "16:9", "9:16"], default: "1:1" }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_url", type: "image", required: false, label: "Image" }, - ], - }, - "grok-imagine/text-to-image": { - parameters: imageParams, inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "grok-imagine/image-to-image": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "ideogram/v3-reframe": { - parameters: imageParams, + parameters: [], inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "ideogram/character": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "ideogram/character-edit": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "qwen/text-to-image": { - parameters: imageParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "qwen/image-to-image": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "qwen/image-edit": { - parameters: imageParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - // --- New video models --- - "runway/gen4": { - parameters: [ - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 10, default: 10 }, - { name: "quality", type: "string", description: "Output quality", enum: ["standard", "high"], default: "standard" }, - { name: "aspectRatio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, - ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "imageUrl", type: "image", required: false, label: "Image" }, - ], - }, - "runway/aleph": { + // ============ Video models ============ + "grok-imagine/text-to-video": { parameters: [ - { name: "duration", type: "integer", description: "Video duration in seconds", minimum: 5, maximum: 10, default: 10 }, - { name: "quality", type: "string", description: "Output quality", enum: ["standard", "high"], default: "standard" }, - { name: "aspectRatio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["2:3", "3:2", "1:1", "16:9", "9:16"], default: "2:3" }, + { name: "duration", type: "string", description: "Video duration in seconds", enum: ["6", "10"], default: "6" }, + { name: "mode", type: "string", description: "Generation mode", enum: ["fun", "normal", "spicy"], default: "normal" }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "imageUrl", type: "image", required: false, label: "Image" }, - ], - }, - "grok-imagine/text-to-video": { - parameters: videoParams, inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, "grok-imagine/image-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + parameters: [ + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["2:3", "3:2", "1:1", "16:9", "9:16"], default: "2:3" }, + { name: "duration", type: "string", description: "Video duration in seconds", enum: ["6", "10"], default: "6" }, + { name: "mode", type: "string", description: "Generation mode", enum: ["fun", "normal", "spicy"], default: "normal" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - }, - "hailuo/2-3-image-to-video-pro": { - parameters: videoParams, inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "hailuo/2-3-image-to-video-standard": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + "kling-2.6/text-to-video": { + parameters: [ + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, + { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "sound", type: "boolean", description: "Enable sound generation", default: true }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - }, - "hailuo/02-text-to-video-pro": { - parameters: videoParams, inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, - "hailuo/02-image-to-video-pro": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, - ], - }, - "bytedance/v1-pro-text-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: false, label: "Image", isArray: true }, - ], - }, - "bytedance/v1-pro-image-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + "kling-2.6/image-to-video": { + parameters: [ + { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, + { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "sound", type: "boolean", description: "Enable sound generation", default: true }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - }, - "bytedance/v1-pro-fast-image-to-video": { - parameters: videoParams, inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "bytedance/v1-lite-text-to-video": { - parameters: videoParams, - inputs: [ - { name: "prompt", type: "text", required: true, label: "Prompt" }, - { name: "image_urls", type: "image", required: false, label: "Image", isArray: true }, + "kling-2.6/motion-control": { + parameters: [ + { name: "mode", type: "string", description: "Output resolution", enum: ["720p", "1080p"], default: "720p" }, + { name: "character_orientation", type: "string", description: "Character orientation source", enum: ["image", "video"], default: "video" }, ], - }, - "bytedance/v1-lite-image-to-video": { - parameters: videoParams, inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + { name: "input_urls", type: "image", required: true, label: "Image", isArray: true }, + { name: "video_urls", type: "image", required: true, label: "Video", isArray: true }, ], }, - "kling/v2-1-master-text-to-video": { + "kling/v2-5-turbo-text-to-video-pro": { parameters: [ { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "cfg_scale", type: "number", description: "Guidance scale", minimum: 0, maximum: 1, default: 0.5 }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], + inputs: [ + { name: "prompt", type: "text", required: true, label: "Prompt" }, + { name: "negative_prompt", type: "text", required: false, label: "Negative Prompt" }, + ], }, - "kling/v2-1-master-image-to-video": { + "kling/v2-5-turbo-image-to-video-pro": { parameters: [ { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "cfg_scale", type: "number", description: "Guidance scale", minimum: 0, maximum: 1, default: 0.5 }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + { name: "negative_prompt", type: "text", required: false, label: "Negative Prompt" }, + { name: "image_url", type: "image", required: true, label: "Image" }, + { name: "tail_image_url", type: "image", required: false, label: "Tail Image" }, ], }, - "kling/v2-5-turbo-text-to-video-pro": { + "wan/2-6-text-to-video": { parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "duration", type: "string", description: "Video duration in seconds", enum: ["5", "10", "15"], default: "5" }, + { name: "resolution", type: "string", description: "Output resolution", enum: ["720p", "1080p"], default: "1080p" }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], }, - "kling/v2-5-turbo-image-to-video-pro": { + "wan/2-6-image-to-video": { parameters: [ - { name: "aspect_ratio", type: "string", description: "Output aspect ratio", enum: ["16:9", "9:16", "1:1"], default: "16:9" }, - { name: "duration", type: "string", description: "Video duration", enum: ["5", "10"], default: "5" }, + { name: "duration", type: "string", description: "Video duration in seconds", enum: ["5", "10", "15"], default: "5" }, + { name: "resolution", type: "string", description: "Output resolution", enum: ["720p", "1080p"], default: "1080p" }, { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, ], inputs: [ @@ -916,22 +697,23 @@ function getKieSchema(modelId: string): ExtractedSchema { { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, ], }, - "wan/2-2-a14b-text-to-video-turbo": { - parameters: videoParams, - inputs: [{ name: "prompt", type: "text", required: true, label: "Prompt" }], - }, - "wan/2-2-a14b-image-to-video-turbo": { - parameters: videoParams, + "wan/2-6-video-to-video": { + parameters: [ + { name: "duration", type: "string", description: "Video duration in seconds", enum: ["5", "10"], default: "5" }, + { name: "resolution", type: "string", description: "Output resolution", enum: ["720p", "1080p"], default: "1080p" }, + { name: "seed", type: "integer", description: "Random seed for reproducibility", minimum: 0 }, + ], inputs: [ { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Image", isArray: true }, + { name: "video_urls", type: "image", required: true, label: "Video", isArray: true }, ], }, - "wan/2-6-video-to-video": { - parameters: videoParams, + "topaz/video-upscale": { + parameters: [ + { name: "upscale_factor", type: "string", description: "Upscale factor", enum: ["1", "2", "4"], default: "2" }, + ], inputs: [ - { name: "prompt", type: "text", required: false, label: "Prompt" }, - { name: "image_urls", type: "image", required: true, label: "Video/Image", isArray: true }, + { name: "video_url", type: "image", required: true, label: "Video" }, ], }, }; diff --git a/src/app/api/models/route.ts b/src/app/api/models/route.ts index 468c87df..21ba4950 100644 --- a/src/app/api/models/route.ts +++ b/src/app/api/models/route.ts @@ -53,7 +53,7 @@ const RELEVANT_CATEGORIES = [ // Kie.ai models (hardcoded - no discovery API available) const KIE_MODELS: ProviderModel[] = [ - // ============ Image Models ============ + // ============ Image Models (11) ============ { id: "z-image", name: "Z-Image", @@ -84,16 +84,6 @@ const KIE_MODELS: ProviderModel[] = [ pricing: { type: "per-run", amount: 0.032, currency: "USD" }, pageUrl: "https://kie.ai/seedream", }, - { - id: "nano-banana-pro", - name: "Nano Banana Pro (Kie)", - description: "High-quality image generation supporting both text-to-image and image-to-image.", - provider: "kie", - capabilities: ["text-to-image", "image-to-image"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.10, currency: "USD" }, - pageUrl: "https://kie.ai/nano-banana", - }, { id: "gpt-image/1.5-text-to-image", name: "GPT Image 1.5", @@ -114,62 +104,6 @@ const KIE_MODELS: ProviderModel[] = [ pricing: { type: "per-run", amount: 0.06, currency: "USD" }, pageUrl: "https://kie.ai/gpt-image-1", }, - { - id: "google/nano-banana", - name: "Google Nano Banana (Kie)", - description: "Google's image generation model via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.05, currency: "USD" }, - pageUrl: "https://kie.ai/nano-banana", - }, - { - id: "google/nano-banana-edit", - name: "Google Nano Banana Edit", - description: "Google's image editing model via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.05, currency: "USD" }, - pageUrl: "https://kie.ai/nano-banana", - }, - { - id: "google/imagen4", - name: "Imagen 4", - description: "Google Imagen 4 text-to-image generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/google/imagen4", - }, - { - id: "google/imagen4-fast", - name: "Imagen 4 Fast", - description: "Google Imagen 4 fast text-to-image generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/google/imagen4", - }, - { - id: "google/imagen4-ultra", - name: "Imagen 4 Ultra", - description: "Google Imagen 4 Ultra high-quality text-to-image generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/google/imagen4", - }, - { - id: "google/pro-image-to-image", - name: "Gemini Pro Edit", - description: "Google Gemini Pro image editing via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/nano-banana", - }, { id: "flux-2/pro-text-to-image", name: "FLUX.2 Pro", @@ -206,24 +140,6 @@ const KIE_MODELS: ProviderModel[] = [ coverImage: undefined, pageUrl: "https://kie.ai/flux-2", }, - { - id: "flux-kontext-pro", - name: "Flux Kontext Pro", - description: "Flux Kontext Pro image generation and editing via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image", "image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/features/flux1-kontext", - }, - { - id: "flux-kontext-max", - name: "Flux Kontext Max", - description: "Flux Kontext Max image generation and editing via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image", "image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/features/flux1-kontext", - }, { id: "grok-imagine/text-to-image", name: "Grok Imagine", @@ -242,130 +158,24 @@ const KIE_MODELS: ProviderModel[] = [ coverImage: undefined, pageUrl: "https://kie.ai/grok-imagine", }, + // ============ Video Models (11) ============ { - id: "ideogram/v3-reframe", - name: "Ideogram V3 Reframe", - description: "Ideogram V3 image reframing via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/ideogram-v3", - }, - { - id: "ideogram/character", - name: "Ideogram Character", - description: "Ideogram character-consistent text-to-image generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/ideogram-v3", - }, - { - id: "ideogram/character-edit", - name: "Ideogram Character Edit", - description: "Ideogram character-consistent image editing via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/ideogram-v3", - }, - { - id: "qwen/text-to-image", - name: "Qwen Image", - description: "Qwen text-to-image generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/qwen-image", - }, - { - id: "qwen/image-to-image", - name: "Qwen Image Edit", - description: "Qwen image editing via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/qwen-image", - }, - { - id: "qwen/image-edit", - name: "Qwen Image Inpaint", - description: "Qwen image inpainting via Kie.ai.", - provider: "kie", - capabilities: ["image-to-image"], - coverImage: undefined, - pageUrl: "https://kie.ai/qwen-image", - }, - // ============ Video Models ============ - { - id: "sora-2-text-to-video", - name: "Sora 2", - description: "OpenAI Sora video generation from text prompts.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pricing: { type: "per-second", amount: 0.015, currency: "USD" }, - pageUrl: "https://kie.ai/sora", - }, - { - id: "sora-2-image-to-video", - name: "Sora 2 Image-to-Video", - description: "OpenAI Sora video generation from images.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pricing: { type: "per-second", amount: 0.015, currency: "USD" }, - pageUrl: "https://kie.ai/sora", - }, - { - id: "sora-2-pro-text-to-video", - name: "Sora 2 Pro", - description: "Premium Sora video generation with higher quality output.", + id: "grok-imagine/text-to-video", + name: "Grok Imagine Video", + description: "Grok Imagine text-to-video generation via Kie.ai.", provider: "kie", capabilities: ["text-to-video"], coverImage: undefined, - pricing: { type: "per-second", amount: 0.10, currency: "USD" }, - pageUrl: "https://kie.ai/sora", + pageUrl: "https://kie.ai/grok-imagine", }, { - id: "sora-2-pro-image-to-video", - name: "Sora 2 Pro Image-to-Video", - description: "Premium Sora video generation from images.", + id: "grok-imagine/image-to-video", + name: "Grok Imagine I2V", + description: "Grok Imagine image-to-video generation via Kie.ai.", provider: "kie", capabilities: ["image-to-video"], coverImage: undefined, - pricing: { type: "per-second", amount: 0.10, currency: "USD" }, - pageUrl: "https://kie.ai/sora", - }, - { - id: "veo3_fast", - name: "Veo 3 Fast", - description: "Google Veo 3 fast video generation. Supports text and image inputs.", - provider: "kie", - capabilities: ["text-to-video", "image-to-video"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.30, currency: "USD" }, - pageUrl: "https://kie.ai/veo3", - }, - { - id: "veo3", - name: "Veo 3", - description: "Google Veo 3 high-quality video generation. Supports text and image inputs.", - provider: "kie", - capabilities: ["text-to-video", "image-to-video"], - coverImage: undefined, - pricing: { type: "per-run", amount: 1.25, currency: "USD" }, - pageUrl: "https://kie.ai/veo3", - }, - { - id: "bytedance/seedance-1.5-pro", - name: "Seedance 1.5 Pro", - description: "ByteDance video generation model. Supports text and image inputs.", - provider: "kie", - capabilities: ["text-to-video", "image-to-video"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.20, currency: "USD" }, - pageUrl: "https://kie.ai/seedance-1-5-pro", + pageUrl: "https://kie.ai/grok-imagine", }, { id: "kling-2.6/text-to-video", @@ -388,155 +198,9 @@ const KIE_MODELS: ProviderModel[] = [ pageUrl: "https://kie.ai/kling-2-6", }, { - id: "wan/2-6-text-to-video", - name: "Wan 2.6", - description: "Wan 2.6 video generation from text.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.90, currency: "USD" }, - pageUrl: "https://kie.ai/wan-2-6", - }, - { - id: "wan/2-6-image-to-video", - name: "Wan 2.6 Image-to-Video", - description: "Wan 2.6 video generation from images.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pricing: { type: "per-run", amount: 0.90, currency: "USD" }, - pageUrl: "https://kie.ai/wan-2-6", - }, - { - id: "runway/gen4", - name: "Runway Gen-4", - description: "Runway Gen-4 video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video", "image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/runway/gen4-turbo", - }, - { - id: "runway/aleph", - name: "Runway Aleph", - description: "Runway Aleph video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video", "image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/runway/gen4-aleph", - }, - { - id: "grok-imagine/text-to-video", - name: "Grok Imagine Video", - description: "Grok Imagine text-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/grok-imagine", - }, - { - id: "grok-imagine/image-to-video", - name: "Grok Imagine I2V", - description: "Grok Imagine image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/grok-imagine", - }, - { - id: "hailuo/2-3-image-to-video-pro", - name: "Hailuo 2.3 Pro", - description: "Hailuo 2.3 Pro image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/hailuo-2-3", - }, - { - id: "hailuo/2-3-image-to-video-standard", - name: "Hailuo 2.3", - description: "Hailuo 2.3 standard image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/hailuo-2-3", - }, - { - id: "hailuo/02-text-to-video-pro", - name: "Hailuo Pro", - description: "Hailuo Pro text-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/hailuo-2-3", - }, - { - id: "hailuo/02-image-to-video-pro", - name: "Hailuo Pro I2V", - description: "Hailuo Pro image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/hailuo-2-3", - }, - { - id: "bytedance/v1-pro-text-to-video", - name: "Seedance Pro", - description: "ByteDance Seedance Pro text-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/seedance-1-5-pro", - }, - { - id: "bytedance/v1-pro-image-to-video", - name: "Seedance Pro I2V", - description: "ByteDance Seedance Pro image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/seedance-1-5-pro", - }, - { - id: "bytedance/v1-pro-fast-image-to-video", - name: "Seedance Pro Fast", - description: "ByteDance Seedance Pro fast image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/seedance-1-5-pro", - }, - { - id: "bytedance/v1-lite-text-to-video", - name: "Seedance Lite", - description: "ByteDance Seedance Lite text-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/seedance-1-5-pro", - }, - { - id: "bytedance/v1-lite-image-to-video", - name: "Seedance Lite I2V", - description: "ByteDance Seedance Lite image-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["image-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/seedance-1-5-pro", - }, - { - id: "kling/v2-1-master-text-to-video", - name: "Kling 2.1 Master", - description: "Kling 2.1 Master text-to-video generation via Kie.ai.", - provider: "kie", - capabilities: ["text-to-video"], - coverImage: undefined, - pageUrl: "https://kie.ai/kling-2-6", - }, - { - id: "kling/v2-1-master-image-to-video", - name: "Kling 2.1 Master I2V", - description: "Kling 2.1 Master image-to-video generation via Kie.ai.", + id: "kling-2.6/motion-control", + name: "Kling 2.6 Motion Control", + description: "Motion transfer from video to static image. Supports 720p and 1080p output.", provider: "kie", capabilities: ["image-to-video"], coverImage: undefined, @@ -561,21 +225,23 @@ const KIE_MODELS: ProviderModel[] = [ pageUrl: "https://kie.ai/kling-2-6", }, { - id: "wan/2-2-a14b-text-to-video-turbo", - name: "Wan 2.2 Turbo", - description: "Wan 2.2 Turbo text-to-video generation via Kie.ai.", + id: "wan/2-6-text-to-video", + name: "Wan 2.6", + description: "Wan 2.6 video generation from text.", provider: "kie", capabilities: ["text-to-video"], coverImage: undefined, + pricing: { type: "per-run", amount: 0.90, currency: "USD" }, pageUrl: "https://kie.ai/wan-2-6", }, { - id: "wan/2-2-a14b-image-to-video-turbo", - name: "Wan 2.2 Turbo I2V", - description: "Wan 2.2 Turbo image-to-video generation via Kie.ai.", + id: "wan/2-6-image-to-video", + name: "Wan 2.6 Image-to-Video", + description: "Wan 2.6 video generation from images.", provider: "kie", capabilities: ["image-to-video"], coverImage: undefined, + pricing: { type: "per-run", amount: 0.90, currency: "USD" }, pageUrl: "https://kie.ai/wan-2-6", }, { @@ -587,6 +253,15 @@ const KIE_MODELS: ProviderModel[] = [ coverImage: undefined, pageUrl: "https://kie.ai/wan-2-6", }, + { + id: "topaz/video-upscale", + name: "Topaz Video Upscale", + description: "AI video upscaling. Supports 1x, 2x, and 4x scaling factors.", + provider: "kie", + capabilities: ["image-to-video"], + coverImage: undefined, + pageUrl: "https://kie.ai/topaz", + }, ]; // Gemini image models (hardcoded - these don't come from an external API)