@picsart/ai-sdk 6.10.2 → 6.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +774 -759
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -2866,327 +2866,623 @@ var { MODELS: MODELS8 } = defineModels("hunyuan", [
|
|
|
2866
2866
|
}
|
|
2867
2867
|
]);
|
|
2868
2868
|
|
|
2869
|
-
// src/vendors/catalog/
|
|
2870
|
-
var
|
|
2871
|
-
prompt: ctx.prompt,
|
|
2872
|
-
...ctx.enhancePrompt !== void 0 ? { prompt_optimizer: ctx.enhancePrompt } : {},
|
|
2873
|
-
...withDuration && ctx.duration ? { duration: ctx.duration } : {}
|
|
2874
|
-
});
|
|
2875
|
-
var buildI2V = (withDuration) => (ctx) => ({
|
|
2869
|
+
// src/vendors/catalog/minimax.ts
|
|
2870
|
+
var buildMinimaxMusicPayload = (ctx) => ({
|
|
2876
2871
|
prompt: ctx.prompt,
|
|
2877
|
-
|
|
2878
|
-
...ctx.
|
|
2879
|
-
...
|
|
2872
|
+
...ctx.lyricsPrompt ? { lyrics: ctx.lyricsPrompt } : {},
|
|
2873
|
+
...ctx.lyricsOptimizer != null ? { lyrics_optimizer: ctx.lyricsOptimizer } : {},
|
|
2874
|
+
...ctx.isInstrumental != null ? { is_instrumental: ctx.isInstrumental } : {},
|
|
2875
|
+
audio_setting: {
|
|
2876
|
+
sample_rate: ctx.sampleRate ?? 44100,
|
|
2877
|
+
bitrate: ctx.bitrate ?? 256e3,
|
|
2878
|
+
format: ctx.format ?? "mp3"
|
|
2879
|
+
}
|
|
2880
2880
|
});
|
|
2881
|
-
var
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2881
|
+
var H3_MAX_PROMPT_MAX = 5e4;
|
|
2882
|
+
var H3_IMAGE_BOUNDS = {
|
|
2883
|
+
minSidePixels: 256,
|
|
2884
|
+
maxSidePixels: 5760,
|
|
2885
|
+
minAspectRatio: 0.4,
|
|
2886
|
+
maxAspectRatio: 2.5
|
|
2887
|
+
};
|
|
2888
|
+
var H3_VIDEO_BOUNDS = {
|
|
2889
|
+
minDurationSec: 2,
|
|
2890
|
+
maxDurationSec: 15,
|
|
2891
|
+
maxFrameRate: 60,
|
|
2892
|
+
maxBytes: 52428800
|
|
2893
|
+
};
|
|
2894
|
+
var H3_AUDIO_BOUNDS = { minDurationSec: 2, maxDurationSec: 15 };
|
|
2895
|
+
var FRAME_REF_EXCLUSIVE = "References and start/end frames cannot be combined.";
|
|
2896
|
+
var AUDIO_NEEDS_VISUAL = "Audio cannot be the only reference \u2014 add an image or video.";
|
|
2897
|
+
var RATIO_FOLLOWS_FRAME = "Aspect ratio follows the frame image.";
|
|
2898
|
+
var ADAPTIVE_NEEDS_REFS = "Adaptive aspect ratio requires reference inputs.";
|
|
2899
|
+
var H3_MAX_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"];
|
|
2900
|
+
var REFERENCE_EXCLUDES_FRAMES = {
|
|
2901
|
+
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2902
|
+
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2895
2903
|
};
|
|
2896
|
-
var
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2904
|
+
var FRAME_EXCLUDES_REFERENCES = {
|
|
2905
|
+
imageUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2906
|
+
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2907
|
+
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2908
|
+
};
|
|
2909
|
+
var h3MaxConstraints = [
|
|
2910
|
+
{ when: { startFrame: { exists: true } }, then: FRAME_EXCLUDES_REFERENCES },
|
|
2911
|
+
{ when: { endFrame: { exists: true } }, then: FRAME_EXCLUDES_REFERENCES },
|
|
2912
|
+
{ when: { imageUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
2913
|
+
{ when: { videoUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
2914
|
+
{ when: { audioUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
2915
|
+
// With a frame the output follows that image, so the ratio is not a choice.
|
|
2916
|
+
// An end frame alone is valid — it generates towards that keyframe.
|
|
2901
2917
|
{ when: { startFrame: { exists: true } }, then: {
|
|
2902
|
-
|
|
2903
|
-
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2904
|
-
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2918
|
+
aspectRatio: { disabled: true, reason: RATIO_FOLLOWS_FRAME }
|
|
2905
2919
|
} },
|
|
2906
2920
|
{ when: { endFrame: { exists: true } }, then: {
|
|
2907
|
-
|
|
2908
|
-
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2909
|
-
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2910
|
-
} },
|
|
2911
|
-
{ when: { imageUrls: { exists: true } }, then: {
|
|
2912
|
-
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2913
|
-
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2914
|
-
} },
|
|
2915
|
-
{ when: { videoUrls: { exists: true } }, then: {
|
|
2916
|
-
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2917
|
-
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2918
|
-
} },
|
|
2919
|
-
{ when: { audioUrls: { exists: true } }, then: {
|
|
2920
|
-
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE },
|
|
2921
|
-
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE }
|
|
2921
|
+
aspectRatio: { disabled: true, reason: RATIO_FOLLOWS_FRAME }
|
|
2922
2922
|
} },
|
|
2923
|
-
//
|
|
2924
|
-
{ when: {
|
|
2925
|
-
|
|
2923
|
+
// 'adaptive' means "follow the references" — no meaning without them.
|
|
2924
|
+
{ when: { imageUrls: { exists: false }, videoUrls: { exists: false }, audioUrls: { exists: false } }, then: {
|
|
2925
|
+
aspectRatio: { allowed: [...H3_MAX_RATIOS], reason: ADAPTIVE_NEEDS_REFS }
|
|
2926
2926
|
} },
|
|
2927
|
-
//
|
|
2927
|
+
// Audio carries no visual signal, so it cannot be the only reference.
|
|
2928
2928
|
{ when: { imageUrls: { exists: false }, videoUrls: { exists: false } }, then: {
|
|
2929
2929
|
audioUrls: { disabled: true, reason: AUDIO_NEEDS_VISUAL }
|
|
2930
2930
|
} }
|
|
2931
2931
|
];
|
|
2932
|
-
var base = {
|
|
2933
|
-
mode: "video"
|
|
2934
|
-
};
|
|
2935
2932
|
var { MODELS: MODELS9 } = defineModels("minimax", [
|
|
2933
|
+
// minimax-02-hd (minimax-tts) was removed in 6.0: its backend workflow was
|
|
2934
|
+
// never deployed anywhere, so no generation ever existed to resolve — nothing
|
|
2935
|
+
// to deprecate. Re-add as a fresh entry if MiniMax TTS ever ships.
|
|
2936
2936
|
{
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
name: "Hailuo 2.3",
|
|
2940
|
-
modelId: "hailuo-2.3",
|
|
2941
|
-
addedAt: "2026-02-06",
|
|
2942
|
-
inputType: "t2v",
|
|
2943
|
-
workflow: "minimax/hailuo-2.3/standard/text-to-video",
|
|
2944
|
-
editWorkflow: "minimax/hailuo-2.3/standard/image-to-video",
|
|
2945
|
-
buildPayload: buildT2V(true),
|
|
2946
|
-
buildEditPayload: buildI2V(true),
|
|
2947
|
-
estimatedTime: 150,
|
|
2948
|
-
description: "Stylized 768p animation with strong character expression and emotion.",
|
|
2949
|
-
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("768p", "resolution"), feat("10 sec", "duration")],
|
|
2950
|
-
paramConfig: {
|
|
2951
|
-
...params.prompt({ maxLength: 2e3 }),
|
|
2952
|
-
...params.enhancePrompt(),
|
|
2953
|
-
...params.duration([6, 10]),
|
|
2954
|
-
...params.imageInput()
|
|
2955
|
-
}
|
|
2956
|
-
},
|
|
2957
|
-
{
|
|
2958
|
-
...base,
|
|
2959
|
-
id: "hailuo-2.3-pro",
|
|
2960
|
-
name: "Hailuo 2.3 Pro",
|
|
2961
|
-
modelId: "hailuo-2.3-pro",
|
|
2937
|
+
id: "minimax-music-v2",
|
|
2938
|
+
name: "MiniMax Music v2",
|
|
2962
2939
|
addedAt: "2026-02-06",
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("1080p", "resolution"), feat("6 sec", "duration")],
|
|
2940
|
+
workflow: "minimax-music/v2",
|
|
2941
|
+
buildPayload: buildMinimaxMusicPayload,
|
|
2942
|
+
estimatedTime: 39,
|
|
2943
|
+
mode: "audio",
|
|
2944
|
+
inputType: "music",
|
|
2945
|
+
description: "Text-to-music with vocals or instrumentals from a style prompt and lyrics prompt.",
|
|
2946
|
+
features: [feat("Music", "characteristic"), feat("Vocals", "characteristic")],
|
|
2971
2947
|
paramConfig: {
|
|
2972
|
-
...params.prompt({ maxLength: 2e3 }),
|
|
2973
|
-
...
|
|
2974
|
-
|
|
2948
|
+
...params.prompt({ maxLength: 2e3, placeholder: "Describe the genre, mood, instruments, tempo, and production style..." }),
|
|
2949
|
+
...p.text("lyricsPrompt", {
|
|
2950
|
+
maxLength: 3500,
|
|
2951
|
+
label: "Lyrics",
|
|
2952
|
+
placeholder: "Write lyrics, or describe the lyrical theme. Optional for instrumental or optimizer-generated lyrics."
|
|
2953
|
+
}),
|
|
2954
|
+
...p.boolean("lyricsOptimizer", false, "Lyrics Optimizer"),
|
|
2955
|
+
...p.boolean("isInstrumental", false, "Instrumental"),
|
|
2956
|
+
...p.enum("sampleRate", [16e3, 24e3, 32e3, 44100], 44100, { label: "Sample Rate" }),
|
|
2957
|
+
...p.enum("bitrate", [32e3, 64e3, 128e3, 256e3], 256e3, { label: "Bitrate" }),
|
|
2958
|
+
...p.enum("format", ["mp3", "wav", "pcm"], "mp3", { label: "Format" })
|
|
2975
2959
|
}
|
|
2976
2960
|
},
|
|
2977
2961
|
{
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
description: "Quick 768p previews with expressive characters for rapid experimentation.",
|
|
2988
|
-
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("768p", "resolution"), feat("10 sec", "duration")],
|
|
2962
|
+
id: "minimax-music-v3",
|
|
2963
|
+
name: "MiniMax Music v3",
|
|
2964
|
+
addedAt: "2026-08-14",
|
|
2965
|
+
workflow: "minimax-music/v3",
|
|
2966
|
+
estimatedTime: 40,
|
|
2967
|
+
mode: "audio",
|
|
2968
|
+
inputType: "music",
|
|
2969
|
+
description: "Text-to-music with vocals or instrumentals from a style prompt and optional lyrics, with configurable audio encoding.",
|
|
2970
|
+
features: [feat("Music", "characteristic"), feat("Vocals", "characteristic")],
|
|
2989
2971
|
paramConfig: {
|
|
2990
|
-
...params.prompt({ maxLength: 2e3 }),
|
|
2991
|
-
...
|
|
2992
|
-
|
|
2993
|
-
|
|
2972
|
+
...params.prompt({ maxLength: 2e3, placeholder: "Describe the genre, mood, instruments, tempo, and production style..." }),
|
|
2973
|
+
...p.text("lyricsPrompt", {
|
|
2974
|
+
maxLength: 3500,
|
|
2975
|
+
label: "Lyrics",
|
|
2976
|
+
placeholder: "Write lyrics; \\n separates lines, [Intro]/[Verse]/[Chorus] tags supported. Optional for instrumental or optimizer-generated lyrics."
|
|
2977
|
+
}),
|
|
2978
|
+
...p.boolean("lyricsOptimizer", false, "Lyrics Optimizer"),
|
|
2979
|
+
...p.boolean("isInstrumental", false, "Instrumental"),
|
|
2980
|
+
...p.enum("sampleRate", [16e3, 24e3, 32e3, 44100], 44100, { label: "Sample Rate" }),
|
|
2981
|
+
...p.enum("bitrate", [32e3, 64e3, 128e3, 256e3], 256e3, { label: "Bitrate" }),
|
|
2982
|
+
...p.enum("format", ["mp3", "wav", "pcm"], "mp3", { label: "Format" })
|
|
2994
2983
|
}
|
|
2995
2984
|
},
|
|
2996
2985
|
{
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
estimatedTime:
|
|
3006
|
-
|
|
3007
|
-
|
|
2986
|
+
// One entry for all three H3 Max modes: the inputs pick it — reference
|
|
2987
|
+
// images, videos or audio generate from references; a start and/or end
|
|
2988
|
+
// frame animates those frames; neither generates from the prompt alone.
|
|
2989
|
+
id: "minimax-h3-max",
|
|
2990
|
+
name: "MiniMax H3 Max",
|
|
2991
|
+
modelId: "fal-ai-h3-max",
|
|
2992
|
+
addedAt: "2026-08-28",
|
|
2993
|
+
workflow: "minimax/h3-max/video-generation",
|
|
2994
|
+
estimatedTime: 5,
|
|
2995
|
+
mode: "video",
|
|
2996
|
+
inputType: "t2v",
|
|
2997
|
+
description: "Top-tier MiniMax H3 Max video from text, a start/end frame, or reference images, videos, and audio \u2014 refer to references in the prompt as Image 1, Video 1, Audio 1, in input order. Up to 15s at 1080p.",
|
|
2998
|
+
features: [
|
|
2999
|
+
feat("Start/End Frame", "frame"),
|
|
3000
|
+
feat("Multi-Image Input", "input"),
|
|
3001
|
+
feat("Video Input", "input"),
|
|
3002
|
+
feat("Audio Input", "input"),
|
|
3003
|
+
feat("1080p", "resolution"),
|
|
3004
|
+
feat("5-15 sec", "duration")
|
|
3005
|
+
],
|
|
3008
3006
|
paramConfig: {
|
|
3009
|
-
...params.prompt({ maxLength:
|
|
3010
|
-
...params.
|
|
3011
|
-
...params.
|
|
3012
|
-
|
|
3007
|
+
...params.prompt({ maxLength: H3_MAX_PROMPT_MAX }),
|
|
3008
|
+
...params.startFrame("Start Frame", false, H3_IMAGE_BOUNDS),
|
|
3009
|
+
...params.endFrame("End Frame", H3_IMAGE_BOUNDS),
|
|
3010
|
+
// Reference slots, reference-to-video route. Per-file limits are
|
|
3011
|
+
// declared; the ≤15s combined cap per modality and the ≤12 files across
|
|
3012
|
+
// images + videos + audios stay backend-enforced.
|
|
3013
|
+
...params.imageInput(9, "Reference Images", false, "reference", H3_IMAGE_BOUNDS),
|
|
3014
|
+
...params.videoInputs(3, "Reference Videos", false, H3_VIDEO_BOUNDS),
|
|
3015
|
+
...params.audioInputs(3, "Reference Audios", false, H3_AUDIO_BOUNDS),
|
|
3016
|
+
// 1080p is a latent refinement of a native 768p generation.
|
|
3017
|
+
...params.resolution(["480p", "768p", "1080p"], "768p"),
|
|
3018
|
+
...params.durationRange(5, 15, 5),
|
|
3019
|
+
// 'adaptive' means "follow the references" — constrained below.
|
|
3020
|
+
...params.aspectRatio(["adaptive", "21:9", "16:9", "4:3", "1:1", "3:4", "9:16"], "16:9"),
|
|
3021
|
+
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
3022
|
+
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
3023
|
+
...p.range("seed", -1, 2147483647, -1),
|
|
3024
|
+
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
3025
|
+
},
|
|
3026
|
+
constraints: h3MaxConstraints
|
|
3013
3027
|
},
|
|
3014
3028
|
{
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3019
|
-
|
|
3029
|
+
// Turbo sibling of minimax-h3-max — same model family, tuned for speed
|
|
3030
|
+
// (faster-than-realtime generation), text and frames only.
|
|
3031
|
+
id: "minimax-h3-max-turbo",
|
|
3032
|
+
name: "MiniMax H3 Max Turbo",
|
|
3033
|
+
modelId: "fal-ai-h3-max-turbo",
|
|
3034
|
+
addedAt: "2026-09-03",
|
|
3035
|
+
workflow: "minimax/h3-max-turbo/text-to-video",
|
|
3036
|
+
editWorkflow: "minimax/h3-max-turbo/image-to-video",
|
|
3037
|
+
estimatedTime: 5,
|
|
3038
|
+
mode: "video",
|
|
3020
3039
|
inputType: "t2v",
|
|
3021
|
-
|
|
3022
|
-
buildPayload: buildMinimaxH3,
|
|
3023
|
-
estimatedTime: 300,
|
|
3024
|
-
description: "MiniMax H3 2K video from text, start/last frame, or image/video/audio references.",
|
|
3040
|
+
description: "Faster-than-realtime MiniMax H3 Max Turbo video from text or a start/end frame, with prompt expansion. Up to 15s at 1080p.",
|
|
3025
3041
|
features: [
|
|
3026
|
-
feat("
|
|
3027
|
-
feat("
|
|
3028
|
-
feat("
|
|
3029
|
-
feat("
|
|
3030
|
-
feat("15 sec", "duration")
|
|
3042
|
+
feat("Fast", "characteristic"),
|
|
3043
|
+
feat("Image Input", "input"),
|
|
3044
|
+
feat("Start/End Frame", "frame"),
|
|
3045
|
+
feat("1080p", "resolution"),
|
|
3046
|
+
feat("5-15 sec", "duration")
|
|
3031
3047
|
],
|
|
3032
3048
|
paramConfig: {
|
|
3033
|
-
...params.prompt({ maxLength:
|
|
3034
|
-
...params.startFrame(),
|
|
3035
|
-
...params.endFrame(),
|
|
3036
|
-
...params.
|
|
3037
|
-
...params.videoInputs(3, "Reference Videos", false),
|
|
3038
|
-
...params.audioInputs(3, "Reference Audios", false),
|
|
3039
|
-
// Backend enum is case-insensitive (['768P','2K','768p','2k']); the
|
|
3040
|
-
// uppercase forms are canonical.
|
|
3041
|
-
...params.resolution(["768P", "2K"], "2K"),
|
|
3049
|
+
...params.prompt({ maxLength: H3_MAX_PROMPT_MAX }),
|
|
3050
|
+
...params.startFrame("Start Frame", false, H3_IMAGE_BOUNDS),
|
|
3051
|
+
...params.endFrame("End Frame", H3_IMAGE_BOUNDS),
|
|
3052
|
+
...params.resolution(["480p", "768p", "1080p"], "768p"),
|
|
3042
3053
|
...params.durationRange(5, 15, 5),
|
|
3043
|
-
...
|
|
3054
|
+
...params.aspectRatio(["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"], "16:9"),
|
|
3055
|
+
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
3056
|
+
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
3057
|
+
...p.range("seed", -1, 2147483647, -1),
|
|
3058
|
+
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
3044
3059
|
},
|
|
3045
|
-
constraints:
|
|
3060
|
+
constraints: [
|
|
3061
|
+
// Either frame routes to image-to-video, which derives the ratio from
|
|
3062
|
+
// the image it was given (no aspect_ratio on that wire). An end frame
|
|
3063
|
+
// alone is valid — fal documents it as end-only keyframe generation.
|
|
3064
|
+
{ when: { startFrame: { exists: true } }, then: {
|
|
3065
|
+
aspectRatio: { disabled: true, reason: "Aspect ratio follows the frame image." }
|
|
3066
|
+
} },
|
|
3067
|
+
{ when: { endFrame: { exists: true } }, then: {
|
|
3068
|
+
aspectRatio: { disabled: true, reason: "Aspect ratio follows the frame image." }
|
|
3069
|
+
} }
|
|
3070
|
+
]
|
|
3071
|
+
},
|
|
3072
|
+
{
|
|
3073
|
+
// Camera-controls sibling of minimax-h3-max: animates a single start
|
|
3074
|
+
// frame along scripted camera keyframes. The prompt is optional — blank
|
|
3075
|
+
// freezes the scene and moves only the camera. No aspect ratio on this
|
|
3076
|
+
// wire; the output follows the frame image.
|
|
3077
|
+
id: "minimax-h3-max-camera-controls",
|
|
3078
|
+
name: "MiniMax H3 Max Camera Controls",
|
|
3079
|
+
modelId: "fal-ai-h3-max-camera-controls",
|
|
3080
|
+
addedAt: "2026-09-14",
|
|
3081
|
+
workflow: "minimax/h3-max/camera-controls",
|
|
3082
|
+
estimatedTime: 5,
|
|
3083
|
+
mode: "video",
|
|
3084
|
+
inputType: "i2v",
|
|
3085
|
+
description: "MiniMax H3 Max video from a start frame with scripted camera motion \u2014 2-12 keyframes set the camera angle, height, and distance over time. Leave the prompt blank to freeze the scene and move only the camera. Up to 15s at 1080p.",
|
|
3086
|
+
features: [
|
|
3087
|
+
feat("Camera Controls", "characteristic"),
|
|
3088
|
+
feat("Image Input", "input"),
|
|
3089
|
+
feat("1080p", "resolution"),
|
|
3090
|
+
feat("5-15 sec", "duration")
|
|
3091
|
+
],
|
|
3092
|
+
paramConfig: {
|
|
3093
|
+
...params.prompt({
|
|
3094
|
+
maxLength: H3_MAX_PROMPT_MAX,
|
|
3095
|
+
required: false,
|
|
3096
|
+
placeholder: "Optional \u2014 leave blank to freeze the scene and move only the camera..."
|
|
3097
|
+
}),
|
|
3098
|
+
...params.startFrame("Start Frame", true, H3_IMAGE_BOUNDS),
|
|
3099
|
+
// Native 480p default here (the siblings default to 768p); 1080p is a
|
|
3100
|
+
// latent refinement of a native 768p generation.
|
|
3101
|
+
...params.resolution(["480p", "768p", "1080p"], "480p"),
|
|
3102
|
+
...params.durationRange(5, 15, 5),
|
|
3103
|
+
// Ordered camera keyframes: the first pose is held before its time and
|
|
3104
|
+
// the final pose for the remainder. Azimuth keeps signed full turns,
|
|
3105
|
+
// capped at ±32 turns of total travel; distance is in normalized scene
|
|
3106
|
+
// units and must stay above zero (the wire has no upper bound).
|
|
3107
|
+
cameraTrajectory: {
|
|
3108
|
+
label: "Camera Trajectory",
|
|
3109
|
+
descriptor: {
|
|
3110
|
+
kind: "object",
|
|
3111
|
+
array: { min: 2, max: 12 },
|
|
3112
|
+
fields: {
|
|
3113
|
+
time: { kind: "range", min: 0, max: 1, step: 0.01, default: 0 },
|
|
3114
|
+
azimuth: { kind: "range", min: -11520, max: 11520, default: 0 },
|
|
3115
|
+
elevation: { kind: "range", min: -90, max: 90, default: 0 },
|
|
3116
|
+
distance: { kind: "range", min: 0.01, max: 100, default: 1 }
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
},
|
|
3120
|
+
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
3121
|
+
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
3122
|
+
...p.range("seed", -1, 2147483647, -1),
|
|
3123
|
+
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
3124
|
+
}
|
|
3125
|
+
},
|
|
3126
|
+
{
|
|
3127
|
+
// Lip-sync sibling of minimax-h3-max: animates a portrait to a supplied
|
|
3128
|
+
// soundtrack. No prompt and no duration on this wire — the audio drives
|
|
3129
|
+
// both: the vendor requires at least 5s, clips anything past 14.8s, and
|
|
3130
|
+
// the output matches the clipped track. The output follows the image, so
|
|
3131
|
+
// there is no aspect ratio either.
|
|
3132
|
+
id: "minimax-h3-max-lip-sync",
|
|
3133
|
+
name: "MiniMax H3 Max Lip Sync",
|
|
3134
|
+
modelId: "fal-ai-h3-max-lip-sync",
|
|
3135
|
+
addedAt: "2026-09-22",
|
|
3136
|
+
workflow: "minimax/h3-max/lip-sync/image-to-video",
|
|
3137
|
+
estimatedTime: 120,
|
|
3138
|
+
mode: "video",
|
|
3139
|
+
inputType: "i2v",
|
|
3140
|
+
description: "MiniMax H3 Max lip-synced video from a portrait and an audio track \u2014 mouth movements follow the soundtrack, optionally guided by a transcript. 5-14.8s of audio, up to 2K.",
|
|
3141
|
+
features: [
|
|
3142
|
+
feat("Lip Sync", "characteristic"),
|
|
3143
|
+
feat("Image Input", "input"),
|
|
3144
|
+
feat("Audio Input", "audio"),
|
|
3145
|
+
feat("2K", "resolution"),
|
|
3146
|
+
feat("5-15 sec", "duration")
|
|
3147
|
+
],
|
|
3148
|
+
paramConfig: {
|
|
3149
|
+
...params.startFrame("Portrait Image", true),
|
|
3150
|
+
...params.audioInput("Audio Track", true),
|
|
3151
|
+
// Unlike the siblings this one also offers 2K; 1080p and 2K are latent
|
|
3152
|
+
// refinements of a native 768p generation.
|
|
3153
|
+
...params.resolution(["480p", "768p", "1080p", "2k"], "768p"),
|
|
3154
|
+
// Transcribes the audio to guide the sync; off follows the waveform alone.
|
|
3155
|
+
...p.boolean("enableTranscription", false, "Transcription"),
|
|
3156
|
+
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
3157
|
+
...p.range("seed", -1, 2147483647, -1),
|
|
3158
|
+
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
3159
|
+
}
|
|
3046
3160
|
}
|
|
3047
3161
|
]);
|
|
3048
3162
|
|
|
3049
|
-
// src/vendors/catalog/
|
|
3050
|
-
var
|
|
3051
|
-
prompt: ctx.prompt,
|
|
3052
|
-
resolution: ctx.resolution ?? "720p",
|
|
3053
|
-
duration: ctx.duration ?? 5,
|
|
3054
|
-
...ctx.startFrame ? { image_url: ctx.startFrame } : {},
|
|
3055
|
-
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3056
|
-
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {}
|
|
3057
|
-
});
|
|
3058
|
-
var buildWanI2VPayload = (ctx) => ({
|
|
3059
|
-
prompt: ctx.prompt,
|
|
3060
|
-
image_url: ctx.startFrame,
|
|
3061
|
-
resolution: ctx.resolution === "1080p" ? "1080p" : "720p",
|
|
3062
|
-
duration: String(ctx.duration ?? 5),
|
|
3063
|
-
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {}
|
|
3064
|
-
});
|
|
3065
|
-
var buildWanR2VPayload = (ctx) => ({
|
|
3066
|
-
prompt: ctx.prompt,
|
|
3067
|
-
video_urls: [ctx.videoUrl],
|
|
3068
|
-
resolution: ctx.resolution === "1080p" ? "1080p" : "720p",
|
|
3069
|
-
duration: String(ctx.duration ?? 5)
|
|
3070
|
-
});
|
|
3071
|
-
var buildWanImagePayload = (ctx) => ({
|
|
3163
|
+
// src/vendors/catalog/hailuo.ts
|
|
3164
|
+
var buildT2V = (withDuration) => (ctx) => ({
|
|
3072
3165
|
prompt: ctx.prompt,
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
...ctx.negativePrompt ? { modelOptions: { negative_prompt: ctx.negativePrompt } } : {}
|
|
3166
|
+
...ctx.enhancePrompt !== void 0 ? { prompt_optimizer: ctx.enhancePrompt } : {},
|
|
3167
|
+
...withDuration && ctx.duration ? { duration: ctx.duration } : {}
|
|
3076
3168
|
});
|
|
3077
|
-
var
|
|
3169
|
+
var buildI2V = (withDuration) => (ctx) => ({
|
|
3078
3170
|
prompt: ctx.prompt,
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
duration: ctx.duration
|
|
3082
|
-
prompt_extend: ctx.enhancePrompt ?? true,
|
|
3083
|
-
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3084
|
-
...ctx.audioUrl ? { audio_url: ctx.audioUrl } : {},
|
|
3085
|
-
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3171
|
+
image_url: ctx.imageUrls?.[0],
|
|
3172
|
+
...ctx.enhancePrompt !== void 0 ? { prompt_optimizer: ctx.enhancePrompt } : {},
|
|
3173
|
+
...withDuration && ctx.duration ? { duration: ctx.duration } : {}
|
|
3086
3174
|
});
|
|
3087
|
-
var
|
|
3088
|
-
const
|
|
3089
|
-
|
|
3090
|
-
if (
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
media,
|
|
3095
|
-
resolution: ctx.resolution ?? "720P",
|
|
3096
|
-
duration: ctx.duration ?? 5,
|
|
3097
|
-
prompt_extend: ctx.enhancePrompt ?? true,
|
|
3098
|
-
...ctx.prompt ? { prompt: ctx.prompt } : {},
|
|
3099
|
-
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3100
|
-
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3101
|
-
};
|
|
3102
|
-
};
|
|
3103
|
-
var buildWan27R2VPayload = (ctx) => {
|
|
3104
|
-
const media = [];
|
|
3105
|
-
if (ctx.imageUrls?.length) {
|
|
3106
|
-
for (const url of ctx.imageUrls) media.push({ type: "reference_image", url });
|
|
3107
|
-
}
|
|
3108
|
-
if (ctx.videoUrl) media.push({ type: "reference_video", url: ctx.videoUrl });
|
|
3109
|
-
if (media.length > 5) {
|
|
3110
|
-
throw new ApiError("Wan 2.7 R2V accepts at most 5 reference items (images + video combined).", {
|
|
3111
|
-
status: 400,
|
|
3112
|
-
code: "validation_error"
|
|
3113
|
-
});
|
|
3114
|
-
}
|
|
3175
|
+
var buildMinimaxH3 = (ctx) => {
|
|
3176
|
+
const content = [{ type: "text", text: ctx.prompt }];
|
|
3177
|
+
if (ctx.startFrame) content.push({ type: "image_url", image_url: { url: ctx.startFrame }, role: "first_frame" });
|
|
3178
|
+
if (ctx.endFrame) content.push({ type: "image_url", image_url: { url: ctx.endFrame }, role: "last_frame" });
|
|
3179
|
+
for (const url of ctx.imageUrls ?? []) content.push({ type: "image_url", image_url: { url }, role: "reference_image" });
|
|
3180
|
+
for (const url of ctx.videoUrls ?? []) content.push({ type: "video_url", video_url: { url }, role: "reference_video" });
|
|
3181
|
+
for (const url of ctx.audioUrls ?? []) content.push({ type: "audio_url", audio_url: { url }, role: "reference_audio" });
|
|
3115
3182
|
return {
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
resolution: ctx.resolution ?? "
|
|
3119
|
-
ratio: ctx.aspectRatio ?? "16:9",
|
|
3183
|
+
model: "MiniMax-H3",
|
|
3184
|
+
content,
|
|
3185
|
+
resolution: ctx.resolution ?? "2K",
|
|
3120
3186
|
duration: ctx.duration ?? 5,
|
|
3121
|
-
...ctx.
|
|
3122
|
-
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3123
|
-
};
|
|
3124
|
-
};
|
|
3125
|
-
var buildWan27VideoEditPayload = (ctx) => {
|
|
3126
|
-
const media = [];
|
|
3127
|
-
if (ctx.videoUrl) media.push({ type: "video", url: ctx.videoUrl });
|
|
3128
|
-
if (ctx.imageUrls?.length) {
|
|
3129
|
-
for (const url of ctx.imageUrls.slice(0, 4)) media.push({ type: "reference_image", url });
|
|
3130
|
-
}
|
|
3131
|
-
return {
|
|
3132
|
-
media,
|
|
3133
|
-
resolution: ctx.resolution ?? "720P",
|
|
3134
|
-
...ctx.prompt ? { prompt: ctx.prompt } : {},
|
|
3135
|
-
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3136
|
-
...ctx.aspectRatio ? { ratio: ctx.aspectRatio } : {},
|
|
3137
|
-
// duration is truncation-only: unset (vendor default 0) keeps the input length.
|
|
3138
|
-
...ctx.duration ? { duration: ctx.duration } : {},
|
|
3139
|
-
...ctx.audioSetting ? { audio_setting: ctx.audioSetting } : {},
|
|
3140
|
-
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3187
|
+
...ctx.aspectRatio ? { ratio: ctx.aspectRatio } : {}
|
|
3141
3188
|
};
|
|
3142
3189
|
};
|
|
3143
|
-
var
|
|
3144
|
-
var
|
|
3145
|
-
var
|
|
3146
|
-
var
|
|
3147
|
-
//
|
|
3190
|
+
var FRAME_REF_EXCLUSIVE2 = "First/last frame and reference inputs cannot be combined.";
|
|
3191
|
+
var LAST_NEEDS_FIRST = "An end frame requires a start frame.";
|
|
3192
|
+
var AUDIO_NEEDS_VISUAL2 = "Reference audio needs a reference image or video.";
|
|
3193
|
+
var minimaxH3Constraints = [
|
|
3194
|
+
// Frame roles ⊥ reference roles (declared both ways so either input disables the other).
|
|
3195
|
+
{ when: { startFrame: { exists: true } }, then: {
|
|
3196
|
+
imageUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3197
|
+
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3198
|
+
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
3199
|
+
} },
|
|
3200
|
+
{ when: { endFrame: { exists: true } }, then: {
|
|
3201
|
+
imageUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3202
|
+
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3203
|
+
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
3204
|
+
} },
|
|
3148
3205
|
{ when: { imageUrls: { exists: true } }, then: {
|
|
3149
|
-
startFrame: { disabled: true, reason:
|
|
3150
|
-
endFrame: { disabled: true, reason:
|
|
3206
|
+
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3207
|
+
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
3151
3208
|
} },
|
|
3152
3209
|
{ when: { videoUrls: { exists: true } }, then: {
|
|
3153
|
-
startFrame: { disabled: true, reason:
|
|
3154
|
-
endFrame: { disabled: true, reason:
|
|
3210
|
+
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3211
|
+
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
3155
3212
|
} },
|
|
3156
3213
|
{ when: { audioUrls: { exists: true } }, then: {
|
|
3157
|
-
startFrame: { disabled: true, reason:
|
|
3158
|
-
endFrame: { disabled: true, reason:
|
|
3214
|
+
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
3215
|
+
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
3159
3216
|
} },
|
|
3160
|
-
//
|
|
3161
|
-
{ when: { startFrame: { exists:
|
|
3162
|
-
|
|
3163
|
-
videoUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3164
|
-
audioUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3217
|
+
// last_frame requires first_frame.
|
|
3218
|
+
{ when: { startFrame: { exists: false } }, then: {
|
|
3219
|
+
endFrame: { disabled: true, reason: LAST_NEEDS_FIRST }
|
|
3165
3220
|
} },
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
audioUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3221
|
+
// reference_audio cannot be the only reference input.
|
|
3222
|
+
{ when: { imageUrls: { exists: false }, videoUrls: { exists: false } }, then: {
|
|
3223
|
+
audioUrls: { disabled: true, reason: AUDIO_NEEDS_VISUAL2 }
|
|
3170
3224
|
} }
|
|
3171
3225
|
];
|
|
3172
|
-
var
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3226
|
+
var base = {
|
|
3227
|
+
mode: "video"
|
|
3228
|
+
};
|
|
3229
|
+
var { MODELS: MODELS10 } = defineModels("minimax", [
|
|
3230
|
+
{
|
|
3231
|
+
...base,
|
|
3232
|
+
id: "hailuo-2.3",
|
|
3233
|
+
name: "Hailuo 2.3",
|
|
3234
|
+
modelId: "hailuo-2.3",
|
|
3235
|
+
addedAt: "2026-02-06",
|
|
3236
|
+
inputType: "t2v",
|
|
3237
|
+
workflow: "minimax/hailuo-2.3/standard/text-to-video",
|
|
3238
|
+
editWorkflow: "minimax/hailuo-2.3/standard/image-to-video",
|
|
3239
|
+
buildPayload: buildT2V(true),
|
|
3240
|
+
buildEditPayload: buildI2V(true),
|
|
3241
|
+
estimatedTime: 150,
|
|
3242
|
+
description: "Stylized 768p animation with strong character expression and emotion.",
|
|
3243
|
+
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("768p", "resolution"), feat("10 sec", "duration")],
|
|
3244
|
+
paramConfig: {
|
|
3245
|
+
...params.prompt({ maxLength: 2e3 }),
|
|
3246
|
+
...params.enhancePrompt(),
|
|
3247
|
+
...params.duration([6, 10]),
|
|
3248
|
+
...params.imageInput()
|
|
3249
|
+
}
|
|
3250
|
+
},
|
|
3251
|
+
{
|
|
3252
|
+
...base,
|
|
3253
|
+
id: "hailuo-2.3-pro",
|
|
3254
|
+
name: "Hailuo 2.3 Pro",
|
|
3255
|
+
modelId: "hailuo-2.3-pro",
|
|
3256
|
+
addedAt: "2026-02-06",
|
|
3257
|
+
inputType: "t2v",
|
|
3258
|
+
workflow: "minimax/hailuo-2.3/pro/text-to-video",
|
|
3259
|
+
editWorkflow: "minimax/hailuo-2.3/pro/image-to-video",
|
|
3260
|
+
buildPayload: buildT2V(false),
|
|
3261
|
+
buildEditPayload: buildI2V(false),
|
|
3262
|
+
estimatedTime: 165,
|
|
3263
|
+
description: "1080p output focused on detailed scenes and polished short-form content.",
|
|
3264
|
+
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("1080p", "resolution"), feat("6 sec", "duration")],
|
|
3265
|
+
paramConfig: {
|
|
3266
|
+
...params.prompt({ maxLength: 2e3 }),
|
|
3267
|
+
...params.enhancePrompt(),
|
|
3268
|
+
...params.imageInput()
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3271
|
+
{
|
|
3272
|
+
...base,
|
|
3273
|
+
id: "hailuo-2.3-fast",
|
|
3274
|
+
name: "Hailuo 2.3 Fast",
|
|
3275
|
+
modelId: "hailuo-2.3-fast",
|
|
3276
|
+
addedAt: "2026-02-06",
|
|
3277
|
+
inputType: "i2v",
|
|
3278
|
+
workflow: "minimax/hailuo-2.3-fast/standard/image-to-video",
|
|
3279
|
+
buildPayload: buildI2V(true),
|
|
3280
|
+
estimatedTime: 173,
|
|
3281
|
+
description: "Quick 768p previews with expressive characters for rapid experimentation.",
|
|
3282
|
+
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("768p", "resolution"), feat("10 sec", "duration")],
|
|
3283
|
+
paramConfig: {
|
|
3284
|
+
...params.prompt({ maxLength: 2e3 }),
|
|
3285
|
+
...params.enhancePrompt(),
|
|
3286
|
+
...params.duration([6, 10]),
|
|
3287
|
+
...params.imageInput(1, "Start Image", true)
|
|
3288
|
+
}
|
|
3289
|
+
},
|
|
3290
|
+
{
|
|
3291
|
+
...base,
|
|
3292
|
+
id: "hailuo-2.3-fast-pro",
|
|
3293
|
+
name: "Hailuo 2.3 Fast Pro",
|
|
3294
|
+
modelId: "hailuo-2.3-fast-pro",
|
|
3295
|
+
addedAt: "2026-02-06",
|
|
3296
|
+
inputType: "i2v",
|
|
3297
|
+
workflow: "minimax/hailuo-2.3-fast/pro/image-to-video",
|
|
3298
|
+
buildPayload: buildI2V(false),
|
|
3299
|
+
estimatedTime: 162,
|
|
3300
|
+
description: "Fast 1080p output for short, polished clips with varied styles.",
|
|
3301
|
+
features: [feat("Image Input", "input"), feat("Start Frame", "frame"), feat("1080p", "resolution"), feat("6 sec", "duration")],
|
|
3302
|
+
paramConfig: {
|
|
3303
|
+
...params.prompt({ maxLength: 2e3 }),
|
|
3304
|
+
...params.enhancePrompt(),
|
|
3305
|
+
...params.imageInput(1, "Start Image", true)
|
|
3306
|
+
}
|
|
3307
|
+
},
|
|
3308
|
+
{
|
|
3309
|
+
...base,
|
|
3310
|
+
id: "minimax-h3",
|
|
3311
|
+
name: "MiniMax H3",
|
|
3312
|
+
modelId: "minimax-h3",
|
|
3313
|
+
addedAt: "2026-07-30",
|
|
3314
|
+
inputType: "t2v",
|
|
3315
|
+
workflow: "minimax/v2/video-generation",
|
|
3316
|
+
buildPayload: buildMinimaxH3,
|
|
3317
|
+
estimatedTime: 300,
|
|
3318
|
+
description: "MiniMax H3 2K video from text, start/last frame, or image/video/audio references.",
|
|
3319
|
+
features: [
|
|
3320
|
+
feat("Start Frame", "frame"),
|
|
3321
|
+
feat("End Frame", "frame"),
|
|
3322
|
+
feat("Reference Video", "input"),
|
|
3323
|
+
feat("2K", "resolution"),
|
|
3324
|
+
feat("15 sec", "duration")
|
|
3325
|
+
],
|
|
3326
|
+
paramConfig: {
|
|
3327
|
+
...params.prompt({ maxLength: 7e3 }),
|
|
3328
|
+
// Same per-file limits as H3 Max (minimax.ts): the vendor prints the
|
|
3329
|
+
// same numbers on this endpoint.
|
|
3330
|
+
...params.startFrame("Start Frame", false, H3_IMAGE_BOUNDS),
|
|
3331
|
+
...params.endFrame("End Frame", H3_IMAGE_BOUNDS),
|
|
3332
|
+
...params.imageInput(9, "Reference Images", false, "reference", H3_IMAGE_BOUNDS),
|
|
3333
|
+
...params.videoInputs(3, "Reference Videos", false, H3_VIDEO_BOUNDS),
|
|
3334
|
+
...params.audioInputs(3, "Reference Audios", false, H3_AUDIO_BOUNDS),
|
|
3335
|
+
// Backend enum is case-insensitive (['768P','2K','768p','2k']); the
|
|
3336
|
+
// uppercase forms are canonical.
|
|
3337
|
+
...params.resolution(["768P", "2K"], "2K"),
|
|
3338
|
+
...params.durationRange(5, 15, 5),
|
|
3339
|
+
...p.aspectRatio(["adaptive", "21:9", "16:9", "4:3", "1:1", "3:4", "9:16"], "adaptive")
|
|
3340
|
+
},
|
|
3341
|
+
constraints: minimaxH3Constraints
|
|
3342
|
+
}
|
|
3343
|
+
]);
|
|
3344
|
+
|
|
3345
|
+
// src/vendors/catalog/wan.ts
|
|
3346
|
+
var buildWanT2VPayload = (ctx) => ({
|
|
3347
|
+
prompt: ctx.prompt,
|
|
3348
|
+
resolution: ctx.resolution ?? "720p",
|
|
3349
|
+
duration: ctx.duration ?? 5,
|
|
3350
|
+
...ctx.startFrame ? { image_url: ctx.startFrame } : {},
|
|
3351
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3352
|
+
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {}
|
|
3353
|
+
});
|
|
3354
|
+
var buildWanI2VPayload = (ctx) => ({
|
|
3355
|
+
prompt: ctx.prompt,
|
|
3356
|
+
image_url: ctx.startFrame,
|
|
3357
|
+
resolution: ctx.resolution === "1080p" ? "1080p" : "720p",
|
|
3358
|
+
duration: String(ctx.duration ?? 5),
|
|
3359
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {}
|
|
3360
|
+
});
|
|
3361
|
+
var buildWanR2VPayload = (ctx) => ({
|
|
3362
|
+
prompt: ctx.prompt,
|
|
3363
|
+
video_urls: [ctx.videoUrl],
|
|
3364
|
+
resolution: ctx.resolution === "1080p" ? "1080p" : "720p",
|
|
3365
|
+
duration: String(ctx.duration ?? 5)
|
|
3366
|
+
});
|
|
3367
|
+
var buildWanImagePayload = (ctx) => ({
|
|
3368
|
+
prompt: ctx.prompt,
|
|
3369
|
+
model: "wan-2.6",
|
|
3370
|
+
count: ctx.count ?? 1,
|
|
3371
|
+
...ctx.negativePrompt ? { modelOptions: { negative_prompt: ctx.negativePrompt } } : {}
|
|
3372
|
+
});
|
|
3373
|
+
var buildWan27T2VPayload = (ctx) => ({
|
|
3374
|
+
prompt: ctx.prompt,
|
|
3375
|
+
resolution: ctx.resolution ?? "720P",
|
|
3376
|
+
ratio: ctx.aspectRatio ?? "16:9",
|
|
3377
|
+
duration: ctx.duration ?? 5,
|
|
3378
|
+
prompt_extend: ctx.enhancePrompt ?? true,
|
|
3379
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3380
|
+
...ctx.audioUrl ? { audio_url: ctx.audioUrl } : {},
|
|
3381
|
+
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3382
|
+
});
|
|
3383
|
+
var buildWan27I2VPayload = (ctx) => {
|
|
3384
|
+
const firstFrameUrl = ctx.startFrame ?? ctx.imageUrls?.[0];
|
|
3385
|
+
const media = [];
|
|
3386
|
+
if (firstFrameUrl) media.push({ type: "first_frame", url: firstFrameUrl });
|
|
3387
|
+
if (ctx.endFrame) media.push({ type: "last_frame", url: ctx.endFrame });
|
|
3388
|
+
if (ctx.audioUrl) media.push({ type: "driving_audio", url: ctx.audioUrl });
|
|
3389
|
+
return {
|
|
3390
|
+
media,
|
|
3391
|
+
resolution: ctx.resolution ?? "720P",
|
|
3392
|
+
duration: ctx.duration ?? 5,
|
|
3393
|
+
prompt_extend: ctx.enhancePrompt ?? true,
|
|
3394
|
+
...ctx.prompt ? { prompt: ctx.prompt } : {},
|
|
3395
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3396
|
+
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3397
|
+
};
|
|
3398
|
+
};
|
|
3399
|
+
var buildWan27R2VPayload = (ctx) => {
|
|
3400
|
+
const media = [];
|
|
3401
|
+
if (ctx.imageUrls?.length) {
|
|
3402
|
+
for (const url of ctx.imageUrls) media.push({ type: "reference_image", url });
|
|
3403
|
+
}
|
|
3404
|
+
if (ctx.videoUrl) media.push({ type: "reference_video", url: ctx.videoUrl });
|
|
3405
|
+
if (media.length > 5) {
|
|
3406
|
+
throw new ApiError("Wan 2.7 R2V accepts at most 5 reference items (images + video combined).", {
|
|
3407
|
+
status: 400,
|
|
3408
|
+
code: "validation_error"
|
|
3409
|
+
});
|
|
3410
|
+
}
|
|
3411
|
+
return {
|
|
3412
|
+
prompt: ctx.prompt,
|
|
3413
|
+
media,
|
|
3414
|
+
resolution: ctx.resolution ?? "720P",
|
|
3415
|
+
ratio: ctx.aspectRatio ?? "16:9",
|
|
3416
|
+
duration: ctx.duration ?? 5,
|
|
3417
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3418
|
+
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3419
|
+
};
|
|
3420
|
+
};
|
|
3421
|
+
var buildWan27VideoEditPayload = (ctx) => {
|
|
3422
|
+
const media = [];
|
|
3423
|
+
if (ctx.videoUrl) media.push({ type: "video", url: ctx.videoUrl });
|
|
3424
|
+
if (ctx.imageUrls?.length) {
|
|
3425
|
+
for (const url of ctx.imageUrls.slice(0, 4)) media.push({ type: "reference_image", url });
|
|
3426
|
+
}
|
|
3427
|
+
return {
|
|
3428
|
+
media,
|
|
3429
|
+
resolution: ctx.resolution ?? "720P",
|
|
3430
|
+
...ctx.prompt ? { prompt: ctx.prompt } : {},
|
|
3431
|
+
...ctx.negativePrompt ? { negative_prompt: ctx.negativePrompt } : {},
|
|
3432
|
+
...ctx.aspectRatio ? { ratio: ctx.aspectRatio } : {},
|
|
3433
|
+
// duration is truncation-only: unset (vendor default 0) keeps the input length.
|
|
3434
|
+
...ctx.duration ? { duration: ctx.duration } : {},
|
|
3435
|
+
...ctx.audioSetting ? { audio_setting: ctx.audioSetting } : {},
|
|
3436
|
+
...ctx.seed != null ? { seed: ctx.seed } : {}
|
|
3437
|
+
};
|
|
3438
|
+
};
|
|
3439
|
+
var WAN27_AR = ["16:9", "9:16", "1:1", "4:3", "3:4"];
|
|
3440
|
+
var WAN27_RES = ["720P", "1080P"];
|
|
3441
|
+
var WAN_V3_FRAME_REF_REASON = "Start/End frames cannot be combined with reference images, videos, or audios";
|
|
3442
|
+
var wanV3Constraints = [
|
|
3443
|
+
// any reference input active → disable frame slots
|
|
3444
|
+
{ when: { imageUrls: { exists: true } }, then: {
|
|
3445
|
+
startFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3446
|
+
endFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3447
|
+
} },
|
|
3448
|
+
{ when: { videoUrls: { exists: true } }, then: {
|
|
3449
|
+
startFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3450
|
+
endFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3451
|
+
} },
|
|
3452
|
+
{ when: { audioUrls: { exists: true } }, then: {
|
|
3453
|
+
startFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3454
|
+
endFrame: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3455
|
+
} },
|
|
3456
|
+
// any frame slot active → disable reference inputs (mirror, blocks inverse order)
|
|
3457
|
+
{ when: { startFrame: { exists: true } }, then: {
|
|
3458
|
+
imageUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3459
|
+
videoUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3460
|
+
audioUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3461
|
+
} },
|
|
3462
|
+
{ when: { endFrame: { exists: true } }, then: {
|
|
3463
|
+
imageUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3464
|
+
videoUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON },
|
|
3465
|
+
audioUrls: { disabled: true, reason: WAN_V3_FRAME_REF_REASON }
|
|
3466
|
+
} }
|
|
3467
|
+
];
|
|
3468
|
+
var wanV3Features = [feat("Image Input", "input"), feat("Video Input", "input"), feat("Audio", "audio"), feat("Start/End Frame", "frame"), feat("1080P", "resolution"), feat("Adaptive Ratio", "resolution")];
|
|
3469
|
+
var wanV3ParamConfig = {
|
|
3470
|
+
// Vendor: 'either prompt or media' — the builder enforces the cross-field rule.
|
|
3471
|
+
...params.prompt({ required: false, maxLength: 5e3 }),
|
|
3472
|
+
// Vendor: integer 2-30, or -1 = Smart duration mode (model picks the length).
|
|
3473
|
+
duration: {
|
|
3474
|
+
label: "Duration (s)",
|
|
3475
|
+
descriptor: {
|
|
3476
|
+
kind: "enum",
|
|
3477
|
+
valueType: "number",
|
|
3478
|
+
options: [{ id: -1, label: "Auto" }, { id: 5 }, { id: 10 }, { id: 15 }, { id: 30 }],
|
|
3479
|
+
default: 5
|
|
3480
|
+
}
|
|
3481
|
+
},
|
|
3482
|
+
...params.resolution(["480P", "720P", "1080P"], "1080P"),
|
|
3483
|
+
// Vendor default is 'adaptive' (model chooses from intent and input media).
|
|
3484
|
+
...params.aspectRatio(["16:9", "9:16", "1:1", "4:3", "3:4", "adaptive"], "adaptive"),
|
|
3485
|
+
...params.generateAudio(true),
|
|
3190
3486
|
...params.startFrame(),
|
|
3191
3487
|
...params.endFrame(),
|
|
3192
3488
|
...params.imageInput(10, "Reference Images"),
|
|
@@ -3197,7 +3493,7 @@ var wanV3ParamConfig = {
|
|
|
3197
3493
|
// No default: a materialized seed would pin every generation to one value.
|
|
3198
3494
|
...params.seed()
|
|
3199
3495
|
};
|
|
3200
|
-
var { MODELS:
|
|
3496
|
+
var { MODELS: MODELS11 } = defineModels("wan", [
|
|
3201
3497
|
// ── Video ─────────────────────────────────────────
|
|
3202
3498
|
{
|
|
3203
3499
|
id: "wan-2.6-t2v",
|
|
@@ -3448,7 +3744,7 @@ var makeWanV3VideoPayload = (model) => (input) => {
|
|
|
3448
3744
|
...input.seed != null ? { seed: input.seed } : {}
|
|
3449
3745
|
};
|
|
3450
3746
|
};
|
|
3451
|
-
registerPayloads(
|
|
3747
|
+
registerPayloads(MODELS11, {
|
|
3452
3748
|
"wan-3.0-video": makeWanV3VideoPayload("wan3.0-video"),
|
|
3453
3749
|
"wan-3.0-video-prime": makeWanV3VideoPayload("wan3.0-video-prime")
|
|
3454
3750
|
});
|
|
@@ -3597,7 +3893,7 @@ var ray32EditConstraints = [
|
|
|
3597
3893
|
exrExport: { disabled: true, reason: HDR_540P }
|
|
3598
3894
|
} }
|
|
3599
3895
|
];
|
|
3600
|
-
var { MODELS:
|
|
3896
|
+
var { MODELS: MODELS12 } = defineModels("luma", [
|
|
3601
3897
|
{
|
|
3602
3898
|
id: "luma-ray-2",
|
|
3603
3899
|
name: "Luma Ray 2",
|
|
@@ -3807,7 +4103,7 @@ var buildRay32ReframePayload = (input) => ({
|
|
|
3807
4103
|
resolution: input.resolution ?? "720p"
|
|
3808
4104
|
}
|
|
3809
4105
|
});
|
|
3810
|
-
registerPayloads(
|
|
4106
|
+
registerPayloads(MODELS12, {
|
|
3811
4107
|
"luma-ray-3.2": buildRay32VideoPayload,
|
|
3812
4108
|
"luma-ray-3.2-edit": buildRay32EditPayload,
|
|
3813
4109
|
"luma-ray-3.2-reframe-video": buildRay32ReframePayload
|
|
@@ -4196,7 +4492,7 @@ var seedance25DraftTaskParam = {
|
|
|
4196
4492
|
}
|
|
4197
4493
|
}
|
|
4198
4494
|
};
|
|
4199
|
-
var { MODELS:
|
|
4495
|
+
var { MODELS: MODELS13 } = defineModels("seedance", [
|
|
4200
4496
|
{
|
|
4201
4497
|
id: "seedance-2.5",
|
|
4202
4498
|
name: "Seedance 2.5",
|
|
@@ -4781,7 +5077,7 @@ var seedreamV2Params = {
|
|
|
4781
5077
|
...params.imageInput(2, "Source Images"),
|
|
4782
5078
|
...params.negativePrompt()
|
|
4783
5079
|
};
|
|
4784
|
-
var { MODELS:
|
|
5080
|
+
var { MODELS: MODELS14 } = defineModels("seedream", [
|
|
4785
5081
|
{
|
|
4786
5082
|
id: "seedream-5.0-pro",
|
|
4787
5083
|
name: "Seedream 5.0 Pro",
|
|
@@ -4925,7 +5221,7 @@ var refMutexConstraints = [
|
|
|
4925
5221
|
imageUrls: { disabled: true, reason: REF_MUTEX_REASON }
|
|
4926
5222
|
} }
|
|
4927
5223
|
];
|
|
4928
|
-
var { MODELS:
|
|
5224
|
+
var { MODELS: MODELS15 } = defineModels("seedaudio", [
|
|
4929
5225
|
{
|
|
4930
5226
|
id: "seed-audio-1.0-multilingual",
|
|
4931
5227
|
name: "Seed Audio Multilingual",
|
|
@@ -4991,7 +5287,7 @@ var buildSeedAudioPayload = (model) => (input) => {
|
|
|
4991
5287
|
...references ? { references } : {}
|
|
4992
5288
|
};
|
|
4993
5289
|
};
|
|
4994
|
-
registerPayloads(
|
|
5290
|
+
registerPayloads(MODELS15, {
|
|
4995
5291
|
"seed-audio-1.0": buildSeedAudioPayload("seed-audio-1.0"),
|
|
4996
5292
|
"seed-audio-1.0-multilingual": buildSeedAudioPayload("seed-audio-1.0-multilingual")
|
|
4997
5293
|
});
|
|
@@ -5007,7 +5303,7 @@ var buildRevePayload = (ctx) => {
|
|
|
5007
5303
|
...hasImages ? { image_url: ctx.imageUrls[0] } : {}
|
|
5008
5304
|
};
|
|
5009
5305
|
};
|
|
5010
|
-
var { MODELS:
|
|
5306
|
+
var { MODELS: MODELS16 } = defineModels("reve", [
|
|
5011
5307
|
{
|
|
5012
5308
|
id: "reve",
|
|
5013
5309
|
name: "Reve",
|
|
@@ -5103,7 +5399,7 @@ var GROK_DURATIONS = [3, 5, 6, 8, 10, 12, 15];
|
|
|
5103
5399
|
var GROK_VIDEO_RESOLUTIONS = ["480p", "720p"];
|
|
5104
5400
|
var GROK_VIDEO_RESOLUTIONS_15 = ["480p", "720p", "1080p"];
|
|
5105
5401
|
var GROK_IMAGE_RESOLUTIONS = ["1k", "2k"];
|
|
5106
|
-
var { MODELS:
|
|
5402
|
+
var { MODELS: MODELS17 } = defineModels("grok", [
|
|
5107
5403
|
// ── Video ─────────────────────────────────────────
|
|
5108
5404
|
{
|
|
5109
5405
|
id: "grok-imagine-video",
|
|
@@ -5292,10 +5588,10 @@ var buildGrokImage2EditPayload = (input) => {
|
|
|
5292
5588
|
...imagePart2
|
|
5293
5589
|
};
|
|
5294
5590
|
};
|
|
5295
|
-
registerPayloads(
|
|
5591
|
+
registerPayloads(MODELS17, {
|
|
5296
5592
|
"grok-imagine-image-2.0": buildGrokImage2Payload
|
|
5297
5593
|
});
|
|
5298
|
-
registerEditPayloads(
|
|
5594
|
+
registerEditPayloads(MODELS17, {
|
|
5299
5595
|
"grok-imagine-image-2.0": buildGrokImage2EditPayload
|
|
5300
5596
|
});
|
|
5301
5597
|
|
|
@@ -5333,7 +5629,7 @@ var buildPikaFramesPayload = (ctx) => ({
|
|
|
5333
5629
|
var PIKA_DURATIONS = [5, 10];
|
|
5334
5630
|
var PIKA_AR = ["16:9", "9:16", "1:1", "4:5", "5:4", "3:2", "2:3"];
|
|
5335
5631
|
var PIKA_RESOLUTIONS = ["720p", "1080p"];
|
|
5336
|
-
var { MODELS:
|
|
5632
|
+
var { MODELS: MODELS18 } = defineModels("pika", [
|
|
5337
5633
|
{
|
|
5338
5634
|
id: "pika-2.2",
|
|
5339
5635
|
name: "Pika",
|
|
@@ -5462,7 +5758,7 @@ var veoLiteParamConfig = {
|
|
|
5462
5758
|
var veoLiteConstraints = [
|
|
5463
5759
|
{ when: { resolution: { is: "1080p" } }, then: { duration: { allowed: [8], reason: "1080p supports 8s only" } } }
|
|
5464
5760
|
];
|
|
5465
|
-
var { MODELS:
|
|
5761
|
+
var { MODELS: MODELS19 } = defineModels("google", [
|
|
5466
5762
|
{
|
|
5467
5763
|
id: "veo-3.1",
|
|
5468
5764
|
name: "Veo 3.1",
|
|
@@ -5598,7 +5894,7 @@ var buildRunwayGen3aTurboPayload = (ctx) => ({
|
|
|
5598
5894
|
ratio: RUNWAY_GEN3A_RATIO_MAP[ctx.aspectRatio ?? "16:9"] ?? "1280:768",
|
|
5599
5895
|
duration: ctx.duration ?? 5
|
|
5600
5896
|
});
|
|
5601
|
-
var { MODELS:
|
|
5897
|
+
var { MODELS: MODELS20 } = defineModels("runway", [
|
|
5602
5898
|
{
|
|
5603
5899
|
id: "runway-avatar-video",
|
|
5604
5900
|
name: "Runway Avatar",
|
|
@@ -5793,7 +6089,7 @@ var flux3VideoConstraints = [
|
|
|
5793
6089
|
resolution: { allowed: ["hd"], reason: "Draft mode only supports HD resolution." }
|
|
5794
6090
|
} }
|
|
5795
6091
|
];
|
|
5796
|
-
var { MODELS:
|
|
6092
|
+
var { MODELS: MODELS21 } = defineModels("flux", [
|
|
5797
6093
|
{
|
|
5798
6094
|
...fluxV2Base,
|
|
5799
6095
|
id: "flux-2-pro",
|
|
@@ -6042,7 +6338,7 @@ var buildFlux3VideoPayload = (input) => {
|
|
|
6042
6338
|
...input.draft ? { draft: input.draft } : {}
|
|
6043
6339
|
};
|
|
6044
6340
|
};
|
|
6045
|
-
registerPayloads(
|
|
6341
|
+
registerPayloads(MODELS21, {
|
|
6046
6342
|
"flux-3-video": buildFlux3VideoPayload
|
|
6047
6343
|
});
|
|
6048
6344
|
|
|
@@ -6124,7 +6420,7 @@ var thinkingBudgetParam = {
|
|
|
6124
6420
|
descriptor: { kind: "range", min: 128, max: 24576, step: 128, default: 128 }
|
|
6125
6421
|
}
|
|
6126
6422
|
};
|
|
6127
|
-
var { MODELS:
|
|
6423
|
+
var { MODELS: MODELS22 } = defineModels("google", [
|
|
6128
6424
|
// ── Image ─────────────────────────────────────────────────────────
|
|
6129
6425
|
{
|
|
6130
6426
|
id: "gemini-3.1-flash-image",
|
|
@@ -6322,7 +6618,7 @@ var buildOmniFlash11Payload = (input) => ({
|
|
|
6322
6618
|
...input.videoUrl ? { video: { url: input.videoUrl } } : {},
|
|
6323
6619
|
...input.videoUrls?.length ? { referenceVideos: input.videoUrls.map((url) => ({ url })) } : {}
|
|
6324
6620
|
});
|
|
6325
|
-
registerPayloads(
|
|
6621
|
+
registerPayloads(MODELS22, {
|
|
6326
6622
|
"gemini-omni-1.1-flash-preview": buildOmniFlash11Payload
|
|
6327
6623
|
});
|
|
6328
6624
|
|
|
@@ -6428,7 +6724,7 @@ var gptImageBgConstraints = [
|
|
|
6428
6724
|
then: { outputFormat: { allowed: ["png", "webp"], reason: "Transparent background needs PNG or WEBP \u2014 JPEG has no alpha channel." } }
|
|
6429
6725
|
}
|
|
6430
6726
|
];
|
|
6431
|
-
var { MODELS:
|
|
6727
|
+
var { MODELS: MODELS23 } = defineModels("openai", [
|
|
6432
6728
|
// ── Image ─────────────────────────────────────────
|
|
6433
6729
|
{
|
|
6434
6730
|
id: "gpt-image-2.5-sunburst",
|
|
@@ -6575,11 +6871,11 @@ var editFor = (model) => (input) => ({
|
|
|
6575
6871
|
...input.background ? { background: input.background } : {},
|
|
6576
6872
|
...input.outputFormat ? { output_format: input.outputFormat } : {}
|
|
6577
6873
|
});
|
|
6578
|
-
registerPayloads(
|
|
6874
|
+
registerPayloads(MODELS23, {
|
|
6579
6875
|
"gpt-image-2.5-flare": generateFor("gpt-image-2.5-flare"),
|
|
6580
6876
|
"gpt-image-2.5-sunburst": generateFor("gpt-image-2.5-sunburst")
|
|
6581
6877
|
});
|
|
6582
|
-
registerEditPayloads(
|
|
6878
|
+
registerEditPayloads(MODELS23, {
|
|
6583
6879
|
"gpt-image-2.5-flare": editFor("gpt-image-2.5-flare"),
|
|
6584
6880
|
"gpt-image-2.5-sunburst": editFor("gpt-image-2.5-sunburst")
|
|
6585
6881
|
});
|
|
@@ -6643,7 +6939,7 @@ var ttsParamConfig = (promptMaxLength, withLanguage) => ({
|
|
|
6643
6939
|
...params.voiceId([], DEFAULT_VOICE_ID, { catalog: VOICE_CATALOG }),
|
|
6644
6940
|
...voiceSettingsParams(true)
|
|
6645
6941
|
});
|
|
6646
|
-
var { MODELS:
|
|
6942
|
+
var { MODELS: MODELS24 } = defineModels("elevenlabs", [
|
|
6647
6943
|
// ── TTS ───────────────────────────────────────────────────────────
|
|
6648
6944
|
{
|
|
6649
6945
|
id: "eleven-v3",
|
|
@@ -6854,485 +7150,204 @@ var { MODELS: MODELS23 } = defineModels("elevenlabs", [
|
|
|
6854
7150
|
features: [feat("Voice Design", "characteristic"), feat("Remix", "characteristic")],
|
|
6855
7151
|
paramConfig: {
|
|
6856
7152
|
// Vendor: "Only your own custom voices can be remixed" — the premade
|
|
6857
|
-
// voices catalog cannot serve this model, so voiceId is a plain id input.
|
|
6858
|
-
voiceId: {
|
|
6859
|
-
label: "Voice ID (a custom voice from your workspace)",
|
|
6860
|
-
required: true,
|
|
6861
|
-
descriptor: { kind: "text", placeholder: "Premade/catalog voices are rejected by ElevenLabs" }
|
|
6862
|
-
},
|
|
6863
|
-
...params.prompt({ minLength: 5, maxLength: 1e3 })
|
|
6864
|
-
}
|
|
6865
|
-
},
|
|
6866
|
-
{
|
|
6867
|
-
id: "eleven-voice-design-v3",
|
|
6868
|
-
name: "Eleven Voice Design v3",
|
|
6869
|
-
addedAt: "2026-03-24",
|
|
6870
|
-
modelId: "eleven_ttv_v3",
|
|
6871
|
-
workflow: "elevenlabs/v1/voice-design",
|
|
6872
|
-
buildPayload: buildElevenLabsVoiceDesignPayload("eleven_ttv_v3"),
|
|
6873
|
-
estimatedTime: 15,
|
|
6874
|
-
mode: "audio",
|
|
6875
|
-
inputType: "tts",
|
|
6876
|
-
description: "Design a new voice from a text description using v3 engine.",
|
|
6877
|
-
features: [feat("Voice Design", "characteristic"), feat("Preview", "characteristic")],
|
|
6878
|
-
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
6879
|
-
},
|
|
6880
|
-
{
|
|
6881
|
-
id: "eleven-voice-design-v2",
|
|
6882
|
-
name: "Eleven Voice Design Multilingual v2",
|
|
6883
|
-
addedAt: "2026-03-24",
|
|
6884
|
-
modelId: "eleven_multilingual_ttv_v2",
|
|
6885
|
-
workflow: "elevenlabs/v1/voice-design",
|
|
6886
|
-
buildPayload: buildElevenLabsVoiceDesignPayload("eleven_multilingual_ttv_v2"),
|
|
6887
|
-
estimatedTime: 15,
|
|
6888
|
-
mode: "audio",
|
|
6889
|
-
inputType: "tts",
|
|
6890
|
-
description: "Design a new voice from a text description with multilingual support.",
|
|
6891
|
-
features: [feat("Voice Design", "characteristic"), feat("Multilingual", "characteristic"), feat("Preview", "characteristic")],
|
|
6892
|
-
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
6893
|
-
},
|
|
6894
|
-
{
|
|
6895
|
-
id: "eleven-voice-create",
|
|
6896
|
-
name: "Eleven Voice Previews",
|
|
6897
|
-
// Pricing registers this operation as `eleven-voice-create-previews`, which
|
|
6898
|
-
// does not match the model id — without the hint the credits lookup misses.
|
|
6899
|
-
modelId: "eleven-voice-create-previews",
|
|
6900
|
-
addedAt: "2026-03-24",
|
|
6901
|
-
workflow: "elevenlabs/v1/voice-create-previews",
|
|
6902
|
-
buildPayload: buildElevenLabsVoicePreviewsPayload,
|
|
6903
|
-
estimatedTime: 15,
|
|
6904
|
-
mode: "audio",
|
|
6905
|
-
inputType: "tts",
|
|
6906
|
-
description: "Generate voice previews from a description to audition before committing.",
|
|
6907
|
-
features: [feat("Voice Design", "characteristic"), feat("Preview", "characteristic")],
|
|
6908
|
-
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
6909
|
-
}
|
|
6910
|
-
]);
|
|
6911
|
-
|
|
6912
|
-
// src/vendors/catalog/elevenlabs.payloads.ts
|
|
6913
|
-
var buildElevenLabsMusicPayload = (input) => ({
|
|
6914
|
-
prompt: input.prompt,
|
|
6915
|
-
music_length_seconds: input.duration ?? 30,
|
|
6916
|
-
model_id: "music_v2",
|
|
6917
|
-
force_instrumental: input.isInstrumental ?? false
|
|
6918
|
-
});
|
|
6919
|
-
var voiceSettings = (input) => {
|
|
6920
|
-
const settings = {
|
|
6921
|
-
...input.stability != null ? { stability: input.stability } : {},
|
|
6922
|
-
...input.similarityBoost != null ? { similarity_boost: input.similarityBoost } : {},
|
|
6923
|
-
...input.styleExaggeration != null ? { style: input.styleExaggeration } : {},
|
|
6924
|
-
...input.speed != null ? { speed: input.speed } : {},
|
|
6925
|
-
...input.useSpeakerBoost != null ? { use_speaker_boost: input.useSpeakerBoost } : {}
|
|
6926
|
-
};
|
|
6927
|
-
return Object.keys(settings).length > 0 ? { voice_settings: settings } : {};
|
|
6928
|
-
};
|
|
6929
|
-
var buildElevenLabsTTSPayload = (modelId) => (input) => ({
|
|
6930
|
-
text: input.prompt,
|
|
6931
|
-
voice_id: input.voiceId ?? DEFAULT_VOICE_ID,
|
|
6932
|
-
model_id: modelId,
|
|
6933
|
-
...input.language ? { language_code: input.language } : {},
|
|
6934
|
-
...voiceSettings(input)
|
|
6935
|
-
});
|
|
6936
|
-
var buildElevenLabsSTSPayload = (modelId) => (input) => ({
|
|
6937
|
-
audio_url: input.audioUrl,
|
|
6938
|
-
voice_id: input.voiceId ?? DEFAULT_VOICE_ID,
|
|
6939
|
-
model_id: modelId,
|
|
6940
|
-
remove_background_noise: input.removeBackgroundNoise ?? false,
|
|
6941
|
-
...voiceSettings(input)
|
|
6942
|
-
});
|
|
6943
|
-
var buildElevenLabsDialoguePayload = (input) => ({
|
|
6944
|
-
conversation: input.dialogue.map((line) => ({
|
|
6945
|
-
voice_id: line.voiceId,
|
|
6946
|
-
text: line.text
|
|
6947
|
-
})),
|
|
6948
|
-
model_id: "eleven_v3",
|
|
6949
|
-
...input.stability != null ? { settings: { stability: input.stability } } : {},
|
|
6950
|
-
...input.language ? { language_code: input.language } : {},
|
|
6951
|
-
...input.seed != null ? { seed: input.seed } : {}
|
|
6952
|
-
});
|
|
6953
|
-
registerPayloads(MODELS23, {
|
|
6954
|
-
"elevenlabs-music-v2": buildElevenLabsMusicPayload,
|
|
6955
|
-
"eleven-v3": buildElevenLabsTTSPayload("eleven_v3"),
|
|
6956
|
-
"eleven-multilingual-v2": buildElevenLabsTTSPayload("eleven_multilingual_v2"),
|
|
6957
|
-
"eleven-sts-v2": buildElevenLabsSTSPayload("eleven_english_sts_v2"),
|
|
6958
|
-
"eleven-multilingual-sts-v2": buildElevenLabsSTSPayload("eleven_multilingual_sts_v2"),
|
|
6959
|
-
"eleven-text-to-dialogue": buildElevenLabsDialoguePayload
|
|
6960
|
-
});
|
|
6961
|
-
|
|
6962
|
-
// src/vendors/catalog/heygen.ts
|
|
6963
|
-
var buildHeyGenPhotoAvatarPayload = (ctx) => ({
|
|
6964
|
-
image_url: ctx.imageUrls?.[0],
|
|
6965
|
-
script: ctx.prompt,
|
|
6966
|
-
voice_id: ctx.voiceId || void 0,
|
|
6967
|
-
...ctx.resolution ? { resolution: ctx.resolution } : {},
|
|
6968
|
-
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {}
|
|
6969
|
-
});
|
|
6970
|
-
var buildHeyGenVideoAvatarPayload = (ctx) => {
|
|
6971
|
-
const c = ctx;
|
|
6972
|
-
return {
|
|
6973
|
-
avatar_id: ctx.videoId || void 0,
|
|
6974
|
-
script: ctx.prompt,
|
|
6975
|
-
voice_id: ctx.voiceId || void 0,
|
|
6976
|
-
...ctx.resolution ? { resolution: ctx.resolution } : {},
|
|
6977
|
-
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {},
|
|
6978
|
-
...c.engine ? { engine: c.engine } : {}
|
|
6979
|
-
};
|
|
6980
|
-
};
|
|
6981
|
-
var engineParam = {
|
|
6982
|
-
engine: {
|
|
6983
|
-
label: "Engine",
|
|
6984
|
-
required: false,
|
|
6985
|
-
descriptor: {
|
|
6986
|
-
kind: "enum",
|
|
6987
|
-
valueType: "string",
|
|
6988
|
-
options: [
|
|
6989
|
-
{ id: "avatar_iv", label: "Avatar IV" },
|
|
6990
|
-
{ id: "avatar_v", label: "Avatar V" }
|
|
6991
|
-
],
|
|
6992
|
-
default: "avatar_iv"
|
|
6993
|
-
}
|
|
6994
|
-
}
|
|
6995
|
-
};
|
|
6996
|
-
var dynamicVoiceConfig = {
|
|
6997
|
-
...params.voiceId([], "", {
|
|
6998
|
-
required: true,
|
|
6999
|
-
catalog: { workflow: "heygen/v1/catalog/voices" }
|
|
7000
|
-
})
|
|
7001
|
-
};
|
|
7002
|
-
var { MODELS: MODELS24 } = defineModels("heygen", [
|
|
7003
|
-
// ── Photo Avatar (i2v) ────────────────────────────────────────────
|
|
7004
|
-
{
|
|
7005
|
-
id: "heygen-talking-photo",
|
|
7006
|
-
modelId: "heygen-avatar-iv",
|
|
7007
|
-
addedAt: "2026-03-17",
|
|
7008
|
-
name: "HeyGen Talking Photo",
|
|
7009
|
-
workflow: "heygen/v1/video/generate",
|
|
7010
|
-
buildPayload: buildHeyGenPhotoAvatarPayload,
|
|
7011
|
-
estimatedTime: 120,
|
|
7012
|
-
mode: "video",
|
|
7013
|
-
inputType: "i2v",
|
|
7014
|
-
description: "Animate any photo into a speaking avatar with natural lip-sync.",
|
|
7015
|
-
features: [
|
|
7016
|
-
feat("Image Input", "input"),
|
|
7017
|
-
feat("Voice Selection", "audio"),
|
|
7018
|
-
feat("Lip Sync", "characteristic")
|
|
7019
|
-
],
|
|
7020
|
-
paramConfig: {
|
|
7021
|
-
...params.imageInput(1, "Portrait Image", true),
|
|
7022
|
-
...params.resolution(["4k", "1080p", "720p"], "720p"),
|
|
7023
|
-
...params.aspectRatio(["16:9", "9:16", "4:5", "5:4", "1:1", "auto"]),
|
|
7024
|
-
...dynamicVoiceConfig,
|
|
7025
|
-
...params.prompt({ minLength: 20, maxLength: 5e3, placeholder: "Write the script your avatar will speak (at least 20 characters)..." })
|
|
7026
|
-
}
|
|
7027
|
-
},
|
|
7028
|
-
// ── Video Avatar (t2v) ────────────────────────────────────────────
|
|
7029
|
-
{
|
|
7030
|
-
id: "heygen-video-avatar",
|
|
7031
|
-
modelId: "heygen-avatar-iv",
|
|
7032
|
-
addedAt: "2026-03-17",
|
|
7033
|
-
name: "HeyGen Video Avatar",
|
|
7034
|
-
workflow: "heygen/v1/video/generate",
|
|
7035
|
-
buildPayload: buildHeyGenVideoAvatarPayload,
|
|
7036
|
-
estimatedTime: 90,
|
|
7037
|
-
mode: "video",
|
|
7038
|
-
inputType: "t2v",
|
|
7039
|
-
description: "Generate a speaking avatar video from a stock avatar and text script.",
|
|
7040
|
-
features: [
|
|
7041
|
-
feat("Avatar Selection", "characteristic"),
|
|
7042
|
-
feat("Voice Selection", "audio"),
|
|
7043
|
-
feat("Lip Sync", "characteristic")
|
|
7044
|
-
],
|
|
7045
|
-
paramConfig: {
|
|
7046
|
-
...params.videoId([], "", {
|
|
7047
|
-
required: true,
|
|
7048
|
-
catalog: { workflow: "heygen/v1/catalog/avatars" }
|
|
7049
|
-
}),
|
|
7050
|
-
...engineParam,
|
|
7051
|
-
...params.resolution(["4k", "1080p", "720p"], "720p"),
|
|
7052
|
-
...params.aspectRatio(["16:9", "9:16", "4:5", "5:4", "1:1", "auto"]),
|
|
7053
|
-
...dynamicVoiceConfig,
|
|
7054
|
-
...params.prompt({ minLength: 20, maxLength: 5e3, placeholder: "Write the script your avatar will speak (at least 20 characters)..." })
|
|
7055
|
-
}
|
|
7056
|
-
}
|
|
7057
|
-
]);
|
|
7058
|
-
|
|
7059
|
-
// src/vendors/catalog/minimax.ts
|
|
7060
|
-
var buildMinimaxMusicPayload = (ctx) => ({
|
|
7061
|
-
prompt: ctx.prompt,
|
|
7062
|
-
...ctx.lyricsPrompt ? { lyrics: ctx.lyricsPrompt } : {},
|
|
7063
|
-
...ctx.lyricsOptimizer != null ? { lyrics_optimizer: ctx.lyricsOptimizer } : {},
|
|
7064
|
-
...ctx.isInstrumental != null ? { is_instrumental: ctx.isInstrumental } : {},
|
|
7065
|
-
audio_setting: {
|
|
7066
|
-
sample_rate: ctx.sampleRate ?? 44100,
|
|
7067
|
-
bitrate: ctx.bitrate ?? 256e3,
|
|
7068
|
-
format: ctx.format ?? "mp3"
|
|
7069
|
-
}
|
|
7070
|
-
});
|
|
7071
|
-
var H3_MAX_PROMPT_MAX = 5e4;
|
|
7072
|
-
var FRAME_REF_EXCLUSIVE2 = "References and start/end frames cannot be combined.";
|
|
7073
|
-
var AUDIO_NEEDS_VISUAL2 = "Audio cannot be the only reference \u2014 add an image or video.";
|
|
7074
|
-
var RATIO_FOLLOWS_FRAME = "Aspect ratio follows the frame image.";
|
|
7075
|
-
var ADAPTIVE_NEEDS_REFS = "Adaptive aspect ratio requires reference inputs.";
|
|
7076
|
-
var H3_MAX_RATIOS = ["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"];
|
|
7077
|
-
var REFERENCE_EXCLUDES_FRAMES = {
|
|
7078
|
-
startFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
7079
|
-
endFrame: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
7080
|
-
};
|
|
7081
|
-
var FRAME_EXCLUDES_REFERENCES = {
|
|
7082
|
-
imageUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
7083
|
-
videoUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 },
|
|
7084
|
-
audioUrls: { disabled: true, reason: FRAME_REF_EXCLUSIVE2 }
|
|
7085
|
-
};
|
|
7086
|
-
var h3MaxConstraints = [
|
|
7087
|
-
{ when: { startFrame: { exists: true } }, then: FRAME_EXCLUDES_REFERENCES },
|
|
7088
|
-
{ when: { endFrame: { exists: true } }, then: FRAME_EXCLUDES_REFERENCES },
|
|
7089
|
-
{ when: { imageUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
7090
|
-
{ when: { videoUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
7091
|
-
{ when: { audioUrls: { exists: true } }, then: REFERENCE_EXCLUDES_FRAMES },
|
|
7092
|
-
// With a frame the output follows that image, so the ratio is not a choice.
|
|
7093
|
-
// An end frame alone is valid — it generates towards that keyframe.
|
|
7094
|
-
{ when: { startFrame: { exists: true } }, then: {
|
|
7095
|
-
aspectRatio: { disabled: true, reason: RATIO_FOLLOWS_FRAME }
|
|
7096
|
-
} },
|
|
7097
|
-
{ when: { endFrame: { exists: true } }, then: {
|
|
7098
|
-
aspectRatio: { disabled: true, reason: RATIO_FOLLOWS_FRAME }
|
|
7099
|
-
} },
|
|
7100
|
-
// 'adaptive' means "follow the references" — no meaning without them.
|
|
7101
|
-
{ when: { imageUrls: { exists: false }, videoUrls: { exists: false }, audioUrls: { exists: false } }, then: {
|
|
7102
|
-
aspectRatio: { allowed: [...H3_MAX_RATIOS], reason: ADAPTIVE_NEEDS_REFS }
|
|
7103
|
-
} },
|
|
7104
|
-
// Audio carries no visual signal, so it cannot be the only reference.
|
|
7105
|
-
{ when: { imageUrls: { exists: false }, videoUrls: { exists: false } }, then: {
|
|
7106
|
-
audioUrls: { disabled: true, reason: AUDIO_NEEDS_VISUAL2 }
|
|
7107
|
-
} }
|
|
7108
|
-
];
|
|
7109
|
-
var { MODELS: MODELS25 } = defineModels("minimax", [
|
|
7110
|
-
// minimax-02-hd (minimax-tts) was removed in 6.0: its backend workflow was
|
|
7111
|
-
// never deployed anywhere, so no generation ever existed to resolve — nothing
|
|
7112
|
-
// to deprecate. Re-add as a fresh entry if MiniMax TTS ever ships.
|
|
7113
|
-
{
|
|
7114
|
-
id: "minimax-music-v2",
|
|
7115
|
-
name: "MiniMax Music v2",
|
|
7116
|
-
addedAt: "2026-02-06",
|
|
7117
|
-
workflow: "minimax-music/v2",
|
|
7118
|
-
buildPayload: buildMinimaxMusicPayload,
|
|
7119
|
-
estimatedTime: 39,
|
|
7120
|
-
mode: "audio",
|
|
7121
|
-
inputType: "music",
|
|
7122
|
-
description: "Text-to-music with vocals or instrumentals from a style prompt and lyrics prompt.",
|
|
7123
|
-
features: [feat("Music", "characteristic"), feat("Vocals", "characteristic")],
|
|
7124
|
-
paramConfig: {
|
|
7125
|
-
...params.prompt({ maxLength: 2e3, placeholder: "Describe the genre, mood, instruments, tempo, and production style..." }),
|
|
7126
|
-
...p.text("lyricsPrompt", {
|
|
7127
|
-
maxLength: 3500,
|
|
7128
|
-
label: "Lyrics",
|
|
7129
|
-
placeholder: "Write lyrics, or describe the lyrical theme. Optional for instrumental or optimizer-generated lyrics."
|
|
7130
|
-
}),
|
|
7131
|
-
...p.boolean("lyricsOptimizer", false, "Lyrics Optimizer"),
|
|
7132
|
-
...p.boolean("isInstrumental", false, "Instrumental"),
|
|
7133
|
-
...p.enum("sampleRate", [16e3, 24e3, 32e3, 44100], 44100, { label: "Sample Rate" }),
|
|
7134
|
-
...p.enum("bitrate", [32e3, 64e3, 128e3, 256e3], 256e3, { label: "Bitrate" }),
|
|
7135
|
-
...p.enum("format", ["mp3", "wav", "pcm"], "mp3", { label: "Format" })
|
|
7136
|
-
}
|
|
7137
|
-
},
|
|
7138
|
-
{
|
|
7139
|
-
id: "minimax-music-v3",
|
|
7140
|
-
name: "MiniMax Music v3",
|
|
7141
|
-
addedAt: "2026-08-14",
|
|
7142
|
-
workflow: "minimax-music/v3",
|
|
7143
|
-
estimatedTime: 40,
|
|
7144
|
-
mode: "audio",
|
|
7145
|
-
inputType: "music",
|
|
7146
|
-
description: "Text-to-music with vocals or instrumentals from a style prompt and optional lyrics, with configurable audio encoding.",
|
|
7147
|
-
features: [feat("Music", "characteristic"), feat("Vocals", "characteristic")],
|
|
7148
|
-
paramConfig: {
|
|
7149
|
-
...params.prompt({ maxLength: 2e3, placeholder: "Describe the genre, mood, instruments, tempo, and production style..." }),
|
|
7150
|
-
...p.text("lyricsPrompt", {
|
|
7151
|
-
maxLength: 3500,
|
|
7152
|
-
label: "Lyrics",
|
|
7153
|
-
placeholder: "Write lyrics; \\n separates lines, [Intro]/[Verse]/[Chorus] tags supported. Optional for instrumental or optimizer-generated lyrics."
|
|
7154
|
-
}),
|
|
7155
|
-
...p.boolean("lyricsOptimizer", false, "Lyrics Optimizer"),
|
|
7156
|
-
...p.boolean("isInstrumental", false, "Instrumental"),
|
|
7157
|
-
...p.enum("sampleRate", [16e3, 24e3, 32e3, 44100], 44100, { label: "Sample Rate" }),
|
|
7158
|
-
...p.enum("bitrate", [32e3, 64e3, 128e3, 256e3], 256e3, { label: "Bitrate" }),
|
|
7159
|
-
...p.enum("format", ["mp3", "wav", "pcm"], "mp3", { label: "Format" })
|
|
7160
|
-
}
|
|
7161
|
-
},
|
|
7162
|
-
{
|
|
7163
|
-
// One entry for all three H3 Max modes: the inputs pick it — reference
|
|
7164
|
-
// images, videos or audio generate from references; a start and/or end
|
|
7165
|
-
// frame animates those frames; neither generates from the prompt alone.
|
|
7166
|
-
id: "minimax-h3-max",
|
|
7167
|
-
name: "MiniMax H3 Max",
|
|
7168
|
-
modelId: "fal-ai-h3-max",
|
|
7169
|
-
addedAt: "2026-08-28",
|
|
7170
|
-
workflow: "minimax/h3-max/video-generation",
|
|
7171
|
-
estimatedTime: 5,
|
|
7172
|
-
mode: "video",
|
|
7173
|
-
inputType: "t2v",
|
|
7174
|
-
description: "Top-tier MiniMax H3 Max video from text, a start/end frame, or reference images, videos, and audio \u2014 refer to references in the prompt as Image 1, Video 1, Audio 1, in input order. Up to 15s at 1080p.",
|
|
7175
|
-
features: [
|
|
7176
|
-
feat("Start/End Frame", "frame"),
|
|
7177
|
-
feat("Multi-Image Input", "input"),
|
|
7178
|
-
feat("Video Input", "input"),
|
|
7179
|
-
feat("Audio Input", "input"),
|
|
7180
|
-
feat("1080p", "resolution"),
|
|
7181
|
-
feat("5-15 sec", "duration")
|
|
7182
|
-
],
|
|
7183
|
-
paramConfig: {
|
|
7184
|
-
...params.prompt({ maxLength: H3_MAX_PROMPT_MAX }),
|
|
7185
|
-
...params.startFrame(),
|
|
7186
|
-
...params.endFrame(),
|
|
7187
|
-
// Reference slots — reference-to-video route. Clips are 2-15s each
|
|
7188
|
-
// (≤15s combined per modality) and images + videos + audios must add up
|
|
7189
|
-
// to ≤12 files — backend-enforced; only the per-array maxima live here.
|
|
7190
|
-
...params.imageInput(9, "Reference Images"),
|
|
7191
|
-
...params.videoInputs(3, "Reference Videos"),
|
|
7192
|
-
...params.audioInputs(3, "Reference Audios"),
|
|
7193
|
-
// 1080p is a latent refinement of a native 768p generation.
|
|
7194
|
-
...params.resolution(["480p", "768p", "1080p"], "768p"),
|
|
7195
|
-
...params.durationRange(5, 15, 5),
|
|
7196
|
-
// 'adaptive' means "follow the references" — constrained below.
|
|
7197
|
-
...params.aspectRatio(["adaptive", "21:9", "16:9", "4:3", "1:1", "3:4", "9:16"], "16:9"),
|
|
7198
|
-
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
7199
|
-
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
7200
|
-
...p.range("seed", -1, 2147483647, -1),
|
|
7201
|
-
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
7202
|
-
},
|
|
7203
|
-
constraints: h3MaxConstraints
|
|
7204
|
-
},
|
|
7205
|
-
{
|
|
7206
|
-
// Turbo sibling of minimax-h3-max — same model family, tuned for speed
|
|
7207
|
-
// (faster-than-realtime generation), text and frames only.
|
|
7208
|
-
id: "minimax-h3-max-turbo",
|
|
7209
|
-
name: "MiniMax H3 Max Turbo",
|
|
7210
|
-
modelId: "fal-ai-h3-max-turbo",
|
|
7211
|
-
addedAt: "2026-09-03",
|
|
7212
|
-
workflow: "minimax/h3-max-turbo/text-to-video",
|
|
7213
|
-
editWorkflow: "minimax/h3-max-turbo/image-to-video",
|
|
7214
|
-
estimatedTime: 5,
|
|
7215
|
-
mode: "video",
|
|
7216
|
-
inputType: "t2v",
|
|
7217
|
-
description: "Faster-than-realtime MiniMax H3 Max Turbo video from text or a start/end frame, with prompt expansion. Up to 15s at 1080p.",
|
|
7218
|
-
features: [
|
|
7219
|
-
feat("Fast", "characteristic"),
|
|
7220
|
-
feat("Image Input", "input"),
|
|
7221
|
-
feat("Start/End Frame", "frame"),
|
|
7222
|
-
feat("1080p", "resolution"),
|
|
7223
|
-
feat("5-15 sec", "duration")
|
|
7224
|
-
],
|
|
7225
|
-
paramConfig: {
|
|
7226
|
-
...params.prompt({ maxLength: H3_MAX_PROMPT_MAX }),
|
|
7227
|
-
...params.startFrame(),
|
|
7228
|
-
...params.endFrame(),
|
|
7229
|
-
...params.resolution(["480p", "768p", "1080p"], "768p"),
|
|
7230
|
-
...params.durationRange(5, 15, 5),
|
|
7231
|
-
...params.aspectRatio(["21:9", "16:9", "4:3", "1:1", "3:4", "9:16"], "16:9"),
|
|
7232
|
-
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
7233
|
-
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
7234
|
-
...p.range("seed", -1, 2147483647, -1),
|
|
7235
|
-
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
7236
|
-
},
|
|
7237
|
-
constraints: [
|
|
7238
|
-
// Either frame routes to image-to-video, which derives the ratio from
|
|
7239
|
-
// the image it was given (no aspect_ratio on that wire). An end frame
|
|
7240
|
-
// alone is valid — fal documents it as end-only keyframe generation.
|
|
7241
|
-
{ when: { startFrame: { exists: true } }, then: {
|
|
7242
|
-
aspectRatio: { disabled: true, reason: "Aspect ratio follows the frame image." }
|
|
7243
|
-
} },
|
|
7244
|
-
{ when: { endFrame: { exists: true } }, then: {
|
|
7245
|
-
aspectRatio: { disabled: true, reason: "Aspect ratio follows the frame image." }
|
|
7246
|
-
} }
|
|
7247
|
-
]
|
|
7153
|
+
// voices catalog cannot serve this model, so voiceId is a plain id input.
|
|
7154
|
+
voiceId: {
|
|
7155
|
+
label: "Voice ID (a custom voice from your workspace)",
|
|
7156
|
+
required: true,
|
|
7157
|
+
descriptor: { kind: "text", placeholder: "Premade/catalog voices are rejected by ElevenLabs" }
|
|
7158
|
+
},
|
|
7159
|
+
...params.prompt({ minLength: 5, maxLength: 1e3 })
|
|
7160
|
+
}
|
|
7248
7161
|
},
|
|
7249
7162
|
{
|
|
7250
|
-
|
|
7251
|
-
|
|
7252
|
-
|
|
7253
|
-
|
|
7254
|
-
|
|
7255
|
-
|
|
7256
|
-
|
|
7257
|
-
|
|
7258
|
-
|
|
7259
|
-
|
|
7163
|
+
id: "eleven-voice-design-v3",
|
|
7164
|
+
name: "Eleven Voice Design v3",
|
|
7165
|
+
addedAt: "2026-03-24",
|
|
7166
|
+
modelId: "eleven_ttv_v3",
|
|
7167
|
+
workflow: "elevenlabs/v1/voice-design",
|
|
7168
|
+
buildPayload: buildElevenLabsVoiceDesignPayload("eleven_ttv_v3"),
|
|
7169
|
+
estimatedTime: 15,
|
|
7170
|
+
mode: "audio",
|
|
7171
|
+
inputType: "tts",
|
|
7172
|
+
description: "Design a new voice from a text description using v3 engine.",
|
|
7173
|
+
features: [feat("Voice Design", "characteristic"), feat("Preview", "characteristic")],
|
|
7174
|
+
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
7175
|
+
},
|
|
7176
|
+
{
|
|
7177
|
+
id: "eleven-voice-design-v2",
|
|
7178
|
+
name: "Eleven Voice Design Multilingual v2",
|
|
7179
|
+
addedAt: "2026-03-24",
|
|
7180
|
+
modelId: "eleven_multilingual_ttv_v2",
|
|
7181
|
+
workflow: "elevenlabs/v1/voice-design",
|
|
7182
|
+
buildPayload: buildElevenLabsVoiceDesignPayload("eleven_multilingual_ttv_v2"),
|
|
7183
|
+
estimatedTime: 15,
|
|
7184
|
+
mode: "audio",
|
|
7185
|
+
inputType: "tts",
|
|
7186
|
+
description: "Design a new voice from a text description with multilingual support.",
|
|
7187
|
+
features: [feat("Voice Design", "characteristic"), feat("Multilingual", "characteristic"), feat("Preview", "characteristic")],
|
|
7188
|
+
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
7189
|
+
},
|
|
7190
|
+
{
|
|
7191
|
+
id: "eleven-voice-create",
|
|
7192
|
+
name: "Eleven Voice Previews",
|
|
7193
|
+
// Pricing registers this operation as `eleven-voice-create-previews`, which
|
|
7194
|
+
// does not match the model id — without the hint the credits lookup misses.
|
|
7195
|
+
modelId: "eleven-voice-create-previews",
|
|
7196
|
+
addedAt: "2026-03-24",
|
|
7197
|
+
workflow: "elevenlabs/v1/voice-create-previews",
|
|
7198
|
+
buildPayload: buildElevenLabsVoicePreviewsPayload,
|
|
7199
|
+
estimatedTime: 15,
|
|
7200
|
+
mode: "audio",
|
|
7201
|
+
inputType: "tts",
|
|
7202
|
+
description: "Generate voice previews from a description to audition before committing.",
|
|
7203
|
+
features: [feat("Voice Design", "characteristic"), feat("Preview", "characteristic")],
|
|
7204
|
+
paramConfig: { ...params.prompt({ minLength: 20, maxLength: 1e3 }) }
|
|
7205
|
+
}
|
|
7206
|
+
]);
|
|
7207
|
+
|
|
7208
|
+
// src/vendors/catalog/elevenlabs.payloads.ts
|
|
7209
|
+
var buildElevenLabsMusicPayload = (input) => ({
|
|
7210
|
+
prompt: input.prompt,
|
|
7211
|
+
music_length_seconds: input.duration ?? 30,
|
|
7212
|
+
model_id: "music_v2",
|
|
7213
|
+
force_instrumental: input.isInstrumental ?? false
|
|
7214
|
+
});
|
|
7215
|
+
var voiceSettings = (input) => {
|
|
7216
|
+
const settings = {
|
|
7217
|
+
...input.stability != null ? { stability: input.stability } : {},
|
|
7218
|
+
...input.similarityBoost != null ? { similarity_boost: input.similarityBoost } : {},
|
|
7219
|
+
...input.styleExaggeration != null ? { style: input.styleExaggeration } : {},
|
|
7220
|
+
...input.speed != null ? { speed: input.speed } : {},
|
|
7221
|
+
...input.useSpeakerBoost != null ? { use_speaker_boost: input.useSpeakerBoost } : {}
|
|
7222
|
+
};
|
|
7223
|
+
return Object.keys(settings).length > 0 ? { voice_settings: settings } : {};
|
|
7224
|
+
};
|
|
7225
|
+
var buildElevenLabsTTSPayload = (modelId) => (input) => ({
|
|
7226
|
+
text: input.prompt,
|
|
7227
|
+
voice_id: input.voiceId ?? DEFAULT_VOICE_ID,
|
|
7228
|
+
model_id: modelId,
|
|
7229
|
+
...input.language ? { language_code: input.language } : {},
|
|
7230
|
+
...voiceSettings(input)
|
|
7231
|
+
});
|
|
7232
|
+
var buildElevenLabsSTSPayload = (modelId) => (input) => ({
|
|
7233
|
+
audio_url: input.audioUrl,
|
|
7234
|
+
voice_id: input.voiceId ?? DEFAULT_VOICE_ID,
|
|
7235
|
+
model_id: modelId,
|
|
7236
|
+
remove_background_noise: input.removeBackgroundNoise ?? false,
|
|
7237
|
+
...voiceSettings(input)
|
|
7238
|
+
});
|
|
7239
|
+
var buildElevenLabsDialoguePayload = (input) => ({
|
|
7240
|
+
conversation: input.dialogue.map((line) => ({
|
|
7241
|
+
voice_id: line.voiceId,
|
|
7242
|
+
text: line.text
|
|
7243
|
+
})),
|
|
7244
|
+
model_id: "eleven_v3",
|
|
7245
|
+
...input.stability != null ? { settings: { stability: input.stability } } : {},
|
|
7246
|
+
...input.language ? { language_code: input.language } : {},
|
|
7247
|
+
...input.seed != null ? { seed: input.seed } : {}
|
|
7248
|
+
});
|
|
7249
|
+
registerPayloads(MODELS24, {
|
|
7250
|
+
"elevenlabs-music-v2": buildElevenLabsMusicPayload,
|
|
7251
|
+
"eleven-v3": buildElevenLabsTTSPayload("eleven_v3"),
|
|
7252
|
+
"eleven-multilingual-v2": buildElevenLabsTTSPayload("eleven_multilingual_v2"),
|
|
7253
|
+
"eleven-sts-v2": buildElevenLabsSTSPayload("eleven_english_sts_v2"),
|
|
7254
|
+
"eleven-multilingual-sts-v2": buildElevenLabsSTSPayload("eleven_multilingual_sts_v2"),
|
|
7255
|
+
"eleven-text-to-dialogue": buildElevenLabsDialoguePayload
|
|
7256
|
+
});
|
|
7257
|
+
|
|
7258
|
+
// src/vendors/catalog/heygen.ts
|
|
7259
|
+
var buildHeyGenPhotoAvatarPayload = (ctx) => ({
|
|
7260
|
+
image_url: ctx.imageUrls?.[0],
|
|
7261
|
+
script: ctx.prompt,
|
|
7262
|
+
voice_id: ctx.voiceId || void 0,
|
|
7263
|
+
...ctx.resolution ? { resolution: ctx.resolution } : {},
|
|
7264
|
+
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {}
|
|
7265
|
+
});
|
|
7266
|
+
var buildHeyGenVideoAvatarPayload = (ctx) => {
|
|
7267
|
+
const c = ctx;
|
|
7268
|
+
return {
|
|
7269
|
+
avatar_id: ctx.videoId || void 0,
|
|
7270
|
+
script: ctx.prompt,
|
|
7271
|
+
voice_id: ctx.voiceId || void 0,
|
|
7272
|
+
...ctx.resolution ? { resolution: ctx.resolution } : {},
|
|
7273
|
+
...ctx.aspectRatio ? { aspect_ratio: ctx.aspectRatio } : {},
|
|
7274
|
+
...c.engine ? { engine: c.engine } : {}
|
|
7275
|
+
};
|
|
7276
|
+
};
|
|
7277
|
+
var engineParam = {
|
|
7278
|
+
engine: {
|
|
7279
|
+
label: "Engine",
|
|
7280
|
+
required: false,
|
|
7281
|
+
descriptor: {
|
|
7282
|
+
kind: "enum",
|
|
7283
|
+
valueType: "string",
|
|
7284
|
+
options: [
|
|
7285
|
+
{ id: "avatar_iv", label: "Avatar IV" },
|
|
7286
|
+
{ id: "avatar_v", label: "Avatar V" }
|
|
7287
|
+
],
|
|
7288
|
+
default: "avatar_iv"
|
|
7289
|
+
}
|
|
7290
|
+
}
|
|
7291
|
+
};
|
|
7292
|
+
var dynamicVoiceConfig = {
|
|
7293
|
+
...params.voiceId([], "", {
|
|
7294
|
+
required: true,
|
|
7295
|
+
catalog: { workflow: "heygen/v1/catalog/voices" }
|
|
7296
|
+
})
|
|
7297
|
+
};
|
|
7298
|
+
var { MODELS: MODELS25 } = defineModels("heygen", [
|
|
7299
|
+
// ── Photo Avatar (i2v) ────────────────────────────────────────────
|
|
7300
|
+
{
|
|
7301
|
+
id: "heygen-talking-photo",
|
|
7302
|
+
modelId: "heygen-avatar-iv",
|
|
7303
|
+
addedAt: "2026-03-17",
|
|
7304
|
+
name: "HeyGen Talking Photo",
|
|
7305
|
+
workflow: "heygen/v1/video/generate",
|
|
7306
|
+
buildPayload: buildHeyGenPhotoAvatarPayload,
|
|
7307
|
+
estimatedTime: 120,
|
|
7260
7308
|
mode: "video",
|
|
7261
7309
|
inputType: "i2v",
|
|
7262
|
-
description: "
|
|
7310
|
+
description: "Animate any photo into a speaking avatar with natural lip-sync.",
|
|
7263
7311
|
features: [
|
|
7264
|
-
feat("Camera Controls", "characteristic"),
|
|
7265
7312
|
feat("Image Input", "input"),
|
|
7266
|
-
feat("
|
|
7267
|
-
feat("
|
|
7313
|
+
feat("Voice Selection", "audio"),
|
|
7314
|
+
feat("Lip Sync", "characteristic")
|
|
7268
7315
|
],
|
|
7269
7316
|
paramConfig: {
|
|
7270
|
-
...params.
|
|
7271
|
-
|
|
7272
|
-
|
|
7273
|
-
|
|
7274
|
-
})
|
|
7275
|
-
...params.startFrame("Start Frame", true),
|
|
7276
|
-
// Native 480p default here (the siblings default to 768p); 1080p is a
|
|
7277
|
-
// latent refinement of a native 768p generation.
|
|
7278
|
-
...params.resolution(["480p", "768p", "1080p"], "480p"),
|
|
7279
|
-
...params.durationRange(5, 15, 5),
|
|
7280
|
-
// Ordered camera keyframes: the first pose is held before its time and
|
|
7281
|
-
// the final pose for the remainder. Azimuth keeps signed full turns,
|
|
7282
|
-
// capped at ±32 turns of total travel; distance is in normalized scene
|
|
7283
|
-
// units and must stay above zero (the wire has no upper bound).
|
|
7284
|
-
cameraTrajectory: {
|
|
7285
|
-
label: "Camera Trajectory",
|
|
7286
|
-
descriptor: {
|
|
7287
|
-
kind: "object",
|
|
7288
|
-
array: { min: 2, max: 12 },
|
|
7289
|
-
fields: {
|
|
7290
|
-
time: { kind: "range", min: 0, max: 1, step: 0.01, default: 0 },
|
|
7291
|
-
azimuth: { kind: "range", min: -11520, max: 11520, default: 0 },
|
|
7292
|
-
elevation: { kind: "range", min: -90, max: 90, default: 0 },
|
|
7293
|
-
distance: { kind: "range", min: 0.01, max: 100, default: 1 }
|
|
7294
|
-
}
|
|
7295
|
-
}
|
|
7296
|
-
},
|
|
7297
|
-
...p.enum("promptExpansionMode", ["balanced", "quality"], "balanced", { label: "Prompt Expansion" }),
|
|
7298
|
-
// -1 (sentinel) means "pick a random seed"; the builder drops it.
|
|
7299
|
-
...p.range("seed", -1, 2147483647, -1),
|
|
7300
|
-
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
7317
|
+
...params.imageInput(1, "Portrait Image", true),
|
|
7318
|
+
...params.resolution(["4k", "1080p", "720p"], "720p"),
|
|
7319
|
+
...params.aspectRatio(["16:9", "9:16", "4:5", "5:4", "1:1", "auto"]),
|
|
7320
|
+
...dynamicVoiceConfig,
|
|
7321
|
+
...params.prompt({ minLength: 20, maxLength: 5e3, placeholder: "Write the script your avatar will speak (at least 20 characters)..." })
|
|
7301
7322
|
}
|
|
7302
7323
|
},
|
|
7324
|
+
// ── Video Avatar (t2v) ────────────────────────────────────────────
|
|
7303
7325
|
{
|
|
7304
|
-
|
|
7305
|
-
|
|
7306
|
-
|
|
7307
|
-
|
|
7308
|
-
|
|
7309
|
-
|
|
7310
|
-
|
|
7311
|
-
modelId: "fal-ai-h3-max-lip-sync",
|
|
7312
|
-
addedAt: "2026-09-22",
|
|
7313
|
-
workflow: "minimax/h3-max/lip-sync/image-to-video",
|
|
7314
|
-
estimatedTime: 120,
|
|
7326
|
+
id: "heygen-video-avatar",
|
|
7327
|
+
modelId: "heygen-avatar-iv",
|
|
7328
|
+
addedAt: "2026-03-17",
|
|
7329
|
+
name: "HeyGen Video Avatar",
|
|
7330
|
+
workflow: "heygen/v1/video/generate",
|
|
7331
|
+
buildPayload: buildHeyGenVideoAvatarPayload,
|
|
7332
|
+
estimatedTime: 90,
|
|
7315
7333
|
mode: "video",
|
|
7316
|
-
inputType: "
|
|
7317
|
-
description: "
|
|
7334
|
+
inputType: "t2v",
|
|
7335
|
+
description: "Generate a speaking avatar video from a stock avatar and text script.",
|
|
7318
7336
|
features: [
|
|
7319
|
-
feat("
|
|
7320
|
-
feat("
|
|
7321
|
-
feat("
|
|
7322
|
-
feat("2K", "resolution"),
|
|
7323
|
-
feat("5-15 sec", "duration")
|
|
7337
|
+
feat("Avatar Selection", "characteristic"),
|
|
7338
|
+
feat("Voice Selection", "audio"),
|
|
7339
|
+
feat("Lip Sync", "characteristic")
|
|
7324
7340
|
],
|
|
7325
7341
|
paramConfig: {
|
|
7326
|
-
...params.
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
...
|
|
7331
|
-
|
|
7332
|
-
...
|
|
7333
|
-
|
|
7334
|
-
...
|
|
7335
|
-
...p.boolean("enableSafetyChecker", true, "Safety Checker")
|
|
7342
|
+
...params.videoId([], "", {
|
|
7343
|
+
required: true,
|
|
7344
|
+
catalog: { workflow: "heygen/v1/catalog/avatars" }
|
|
7345
|
+
}),
|
|
7346
|
+
...engineParam,
|
|
7347
|
+
...params.resolution(["4k", "1080p", "720p"], "720p"),
|
|
7348
|
+
...params.aspectRatio(["16:9", "9:16", "4:5", "5:4", "1:1", "auto"]),
|
|
7349
|
+
...dynamicVoiceConfig,
|
|
7350
|
+
...params.prompt({ minLength: 20, maxLength: 5e3, placeholder: "Write the script your avatar will speak (at least 20 characters)..." })
|
|
7336
7351
|
}
|
|
7337
7352
|
}
|
|
7338
7353
|
]);
|
|
@@ -7417,14 +7432,14 @@ var buildMinimaxH3MaxLipSyncPayload = (input) => ({
|
|
|
7417
7432
|
...input.seed != null && input.seed !== -1 ? { seed: input.seed } : {},
|
|
7418
7433
|
enable_safety_checker: input.enableSafetyChecker ?? true
|
|
7419
7434
|
});
|
|
7420
|
-
registerPayloads(
|
|
7435
|
+
registerPayloads(MODELS9, {
|
|
7421
7436
|
"minimax-music-v3": buildMinimaxMusicV3Payload,
|
|
7422
7437
|
"minimax-h3-max": buildMinimaxH3MaxPayload,
|
|
7423
7438
|
"minimax-h3-max-turbo": buildMinimaxH3MaxTurboPayload,
|
|
7424
7439
|
"minimax-h3-max-camera-controls": buildMinimaxH3MaxCameraControlsPayload,
|
|
7425
7440
|
"minimax-h3-max-lip-sync": buildMinimaxH3MaxLipSyncPayload
|
|
7426
7441
|
});
|
|
7427
|
-
registerEditPayloads(
|
|
7442
|
+
registerEditPayloads(MODELS9, {
|
|
7428
7443
|
"minimax-h3-max-turbo": buildMinimaxH3MaxTurboPayload
|
|
7429
7444
|
});
|
|
7430
7445
|
|
|
@@ -9994,7 +10009,6 @@ var ALL_MODELS = [
|
|
|
9994
10009
|
...MODELS6,
|
|
9995
10010
|
...MODELS7,
|
|
9996
10011
|
...MODELS8,
|
|
9997
|
-
...MODELS9,
|
|
9998
10012
|
...MODELS10,
|
|
9999
10013
|
...MODELS11,
|
|
10000
10014
|
...MODELS12,
|
|
@@ -10011,6 +10025,7 @@ var ALL_MODELS = [
|
|
|
10011
10025
|
...MODELS23,
|
|
10012
10026
|
...MODELS24,
|
|
10013
10027
|
...MODELS25,
|
|
10028
|
+
...MODELS9,
|
|
10014
10029
|
...MODELS26,
|
|
10015
10030
|
...MODELS31,
|
|
10016
10031
|
...MODELS27,
|