@vibeframe/cli 0.105.2 → 0.106.2
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/dist/commands/_shared/edit/silence-cut.d.ts +1 -1
- package/dist/commands/_shared/render-inspect.d.ts +1 -1
- package/dist/commands/_shared/scene-html-emit.d.ts +24 -0
- package/dist/commands/ai-analyze.d.ts +2 -2
- package/dist/commands/ai-motion.d.ts +1 -1
- package/dist/commands/ai-review.d.ts +1 -1
- package/dist/commands/ai-video.d.ts +1 -1
- package/dist/commands/generate/video-status.d.ts +2 -2
- package/dist/commands/generate.d.ts +1 -1
- package/dist/commands/scene.d.ts +4 -1
- package/dist/index.js +398 -96
- package/dist/tools/manifest/edit.d.ts +11 -11
- package/dist/tools/manifest/generate.d.ts +9 -6
- package/dist/tools/manifest/index.js +380 -88
- package/dist/tools/manifest/inspect.d.ts +12 -12
- package/package.json +3 -3
|
@@ -14543,6 +14543,39 @@ var init_whisper = __esm({
|
|
|
14543
14543
|
}
|
|
14544
14544
|
});
|
|
14545
14545
|
|
|
14546
|
+
// ../ai-providers/dist/gemini/gemini-models.js
|
|
14547
|
+
function isGeminiTextModelAlias(model) {
|
|
14548
|
+
return Object.prototype.hasOwnProperty.call(GEMINI_TEXT_MODEL_ALIASES, model);
|
|
14549
|
+
}
|
|
14550
|
+
function resolveGeminiTextModel(model) {
|
|
14551
|
+
const trimmed = model?.trim();
|
|
14552
|
+
if (!trimmed)
|
|
14553
|
+
return GEMINI_DEFAULT_TEXT_MODEL;
|
|
14554
|
+
if (isGeminiTextModelAlias(trimmed))
|
|
14555
|
+
return GEMINI_TEXT_MODEL_ALIASES[trimmed];
|
|
14556
|
+
if (trimmed.startsWith("gemini-"))
|
|
14557
|
+
return trimmed;
|
|
14558
|
+
return GEMINI_DEFAULT_TEXT_MODEL;
|
|
14559
|
+
}
|
|
14560
|
+
var GEMINI_DEFAULT_TEXT_MODEL, GEMINI_AGENT_DEFAULT_TEXT_MODEL, GEMINI_TEXT_MODEL_ALIASES, GEMINI_TEXT_MODEL_HELP;
|
|
14561
|
+
var init_gemini_models = __esm({
|
|
14562
|
+
"../ai-providers/dist/gemini/gemini-models.js"() {
|
|
14563
|
+
"use strict";
|
|
14564
|
+
GEMINI_DEFAULT_TEXT_MODEL = "gemini-3.5-flash";
|
|
14565
|
+
GEMINI_AGENT_DEFAULT_TEXT_MODEL = "gemini-2.5-flash";
|
|
14566
|
+
GEMINI_TEXT_MODEL_ALIASES = {
|
|
14567
|
+
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
14568
|
+
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
14569
|
+
"flash-3.5": GEMINI_DEFAULT_TEXT_MODEL,
|
|
14570
|
+
"flash-3": "gemini-3-flash-preview",
|
|
14571
|
+
"flash-2.5": "gemini-2.5-flash",
|
|
14572
|
+
pro: "gemini-2.5-pro",
|
|
14573
|
+
"pro-3.1": "gemini-3.1-pro-preview"
|
|
14574
|
+
};
|
|
14575
|
+
GEMINI_TEXT_MODEL_HELP = "flash/latest (Gemini 3.5 Flash), flash-3.5, flash-3, flash-2.5, pro, pro-3.1, or a full gemini-* model ID";
|
|
14576
|
+
}
|
|
14577
|
+
});
|
|
14578
|
+
|
|
14546
14579
|
// ../ai-providers/dist/gemini/gemini-motion.js
|
|
14547
14580
|
function buildMotionSystemPrompt(width, height, fps, duration, durationInFrames, stylePreset) {
|
|
14548
14581
|
return `You are a world-class broadcast motion graphics designer (like Apple Keynote, Netflix intros, ESPN graphics). Create STUNNING, jaw-dropping overlays that make viewers go "wow".
|
|
@@ -14696,7 +14729,7 @@ async function generateMotion(api, description, options = {}) {
|
|
|
14696
14729
|
const duration = options.duration || 5;
|
|
14697
14730
|
const durationInFrames = Math.round(duration * fps);
|
|
14698
14731
|
const stylePreset = options.style || "modern and clean";
|
|
14699
|
-
const modelId = options.model
|
|
14732
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
14700
14733
|
let systemPrompt = buildMotionSystemPrompt(width, height, fps, duration, durationInFrames, stylePreset);
|
|
14701
14734
|
if (options.videoContext) {
|
|
14702
14735
|
const sourceLabel = options.sourceType === "image" ? "IMAGE" : "VIDEO";
|
|
@@ -14777,7 +14810,7 @@ async function refineMotion(api, existingCode, instructions, options = {}) {
|
|
|
14777
14810
|
const fps = options.fps || 30;
|
|
14778
14811
|
const duration = options.duration || 5;
|
|
14779
14812
|
const durationInFrames = Math.round(duration * fps);
|
|
14780
|
-
const modelId = options.model
|
|
14813
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
14781
14814
|
const systemPrompt = `You are a world-class broadcast motion graphics designer. Modify the provided Remotion component based on instructions.
|
|
14782
14815
|
|
|
14783
14816
|
CANVAS: ${width}\xD7${height}px | ${fps}fps | ${durationInFrames} frames (${duration}s)
|
|
@@ -14872,9 +14905,18 @@ var GEMINI_MOTION_MODELS, STYLE_USER_INSTRUCTIONS;
|
|
|
14872
14905
|
var init_gemini_motion = __esm({
|
|
14873
14906
|
"../ai-providers/dist/gemini/gemini-motion.js"() {
|
|
14874
14907
|
"use strict";
|
|
14908
|
+
init_gemini_models();
|
|
14875
14909
|
GEMINI_MOTION_MODELS = {
|
|
14910
|
+
gemini: GEMINI_DEFAULT_TEXT_MODEL,
|
|
14911
|
+
flash: GEMINI_DEFAULT_TEXT_MODEL,
|
|
14912
|
+
latest: GEMINI_DEFAULT_TEXT_MODEL,
|
|
14913
|
+
"flash-3.5": GEMINI_DEFAULT_TEXT_MODEL,
|
|
14914
|
+
"flash-3": "gemini-3-flash-preview",
|
|
14915
|
+
"flash-2.5": "gemini-2.5-flash",
|
|
14876
14916
|
pro: "gemini-2.5-pro",
|
|
14877
|
-
"
|
|
14917
|
+
"2.5-pro": "gemini-2.5-pro",
|
|
14918
|
+
"3.1-pro": "gemini-3.1-pro-preview",
|
|
14919
|
+
"pro-3.1": "gemini-3.1-pro-preview"
|
|
14878
14920
|
};
|
|
14879
14921
|
STYLE_USER_INSTRUCTIONS = {
|
|
14880
14922
|
minimal: "CENTER-ALIGNED pure typography. Thin lines + large title + subtitle. NO glass panels, NO bokeh, NO dark bars. Breathing pulse during hold.",
|
|
@@ -14997,7 +15039,7 @@ async function analyzeContent(api, content, targetDuration, options) {
|
|
|
14997
15039
|
maxOutputTokens: 4096
|
|
14998
15040
|
}
|
|
14999
15041
|
};
|
|
15000
|
-
const response = await fetch(`${api.baseUrl}/models
|
|
15042
|
+
const response = await fetch(`${api.baseUrl}/models/${GEMINI_DEFAULT_TEXT_MODEL}:generateContent?key=${api.apiKey}`, {
|
|
15001
15043
|
method: "POST",
|
|
15002
15044
|
headers: { "Content-Type": "application/json" },
|
|
15003
15045
|
body: JSON.stringify(payload)
|
|
@@ -15030,6 +15072,7 @@ var init_gemini_storyboard = __esm({
|
|
|
15030
15072
|
"../ai-providers/dist/gemini/gemini-storyboard.js"() {
|
|
15031
15073
|
"use strict";
|
|
15032
15074
|
init_storyboard_prompt();
|
|
15075
|
+
init_gemini_models();
|
|
15033
15076
|
}
|
|
15034
15077
|
});
|
|
15035
15078
|
|
|
@@ -15068,6 +15111,7 @@ var init_GeminiProvider = __esm({
|
|
|
15068
15111
|
"../ai-providers/dist/gemini/GeminiProvider.js"() {
|
|
15069
15112
|
"use strict";
|
|
15070
15113
|
init_gemini_motion();
|
|
15114
|
+
init_gemini_models();
|
|
15071
15115
|
init_gemini_storyboard();
|
|
15072
15116
|
init_http();
|
|
15073
15117
|
MODEL_MAP = {
|
|
@@ -15576,7 +15620,7 @@ var init_GeminiProvider = __esm({
|
|
|
15576
15620
|
error: "Google API key not configured"
|
|
15577
15621
|
};
|
|
15578
15622
|
}
|
|
15579
|
-
const modelId = options.model
|
|
15623
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
15580
15624
|
try {
|
|
15581
15625
|
let videoPart;
|
|
15582
15626
|
if (typeof videoData === "string") {
|
|
@@ -15683,7 +15727,7 @@ var init_GeminiProvider = __esm({
|
|
|
15683
15727
|
error: "Google API key not configured"
|
|
15684
15728
|
};
|
|
15685
15729
|
}
|
|
15686
|
-
const modelId = options.model
|
|
15730
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
15687
15731
|
try {
|
|
15688
15732
|
const buffers = Array.isArray(imageData) ? imageData : [imageData];
|
|
15689
15733
|
const imageParts = buffers.map((buf) => ({
|
|
@@ -15785,7 +15829,7 @@ Example response:
|
|
|
15785
15829
|
[{"type":"trim","description":"Trim intro to 3 seconds","clipIds":["clip-1"],"params":{"newDuration":3},"confidence":0.9}]
|
|
15786
15830
|
|
|
15787
15831
|
Respond with ONLY the JSON array, no other text.`;
|
|
15788
|
-
const response = await fetch(`${this.baseUrl}/models
|
|
15832
|
+
const response = await fetch(`${this.baseUrl}/models/${GEMINI_DEFAULT_TEXT_MODEL}:generateContent?key=${this.apiKey}`, {
|
|
15789
15833
|
method: "POST",
|
|
15790
15834
|
headers: {
|
|
15791
15835
|
"Content-Type": "application/json"
|
|
@@ -15907,6 +15951,7 @@ var init_gemini = __esm({
|
|
|
15907
15951
|
"use strict";
|
|
15908
15952
|
init_GeminiProvider();
|
|
15909
15953
|
init_gemini_motion();
|
|
15954
|
+
init_gemini_models();
|
|
15910
15955
|
init_define_provider();
|
|
15911
15956
|
defineProvider({
|
|
15912
15957
|
id: "gemini",
|
|
@@ -25270,6 +25315,10 @@ __export(dist_exports2, {
|
|
|
25270
25315
|
ClaudeProvider: () => ClaudeProvider,
|
|
25271
25316
|
ElevenLabsProvider: () => ElevenLabsProvider,
|
|
25272
25317
|
FalProvider: () => FalProvider,
|
|
25318
|
+
GEMINI_AGENT_DEFAULT_TEXT_MODEL: () => GEMINI_AGENT_DEFAULT_TEXT_MODEL,
|
|
25319
|
+
GEMINI_DEFAULT_TEXT_MODEL: () => GEMINI_DEFAULT_TEXT_MODEL,
|
|
25320
|
+
GEMINI_TEXT_MODEL_ALIASES: () => GEMINI_TEXT_MODEL_ALIASES,
|
|
25321
|
+
GEMINI_TEXT_MODEL_HELP: () => GEMINI_TEXT_MODEL_HELP,
|
|
25273
25322
|
GeminiProvider: () => GeminiProvider,
|
|
25274
25323
|
GrokProvider: () => GrokProvider,
|
|
25275
25324
|
KNOWN_VOICES: () => KNOWN_VOICES,
|
|
@@ -25300,6 +25349,7 @@ __export(dist_exports2, {
|
|
|
25300
25349
|
getProvidersFor: () => getProvidersFor,
|
|
25301
25350
|
getSetupProviders: () => getSetupProviders,
|
|
25302
25351
|
grokProvider: () => grokProvider,
|
|
25352
|
+
isGeminiTextModelAlias: () => isGeminiTextModelAlias,
|
|
25303
25353
|
klingProvider: () => klingProvider,
|
|
25304
25354
|
kokoroProvider: () => kokoroProvider,
|
|
25305
25355
|
ollamaProvider: () => ollamaProvider,
|
|
@@ -25307,6 +25357,7 @@ __export(dist_exports2, {
|
|
|
25307
25357
|
openaiProvider: () => openaiProvider,
|
|
25308
25358
|
providerRegistry: () => providerRegistry,
|
|
25309
25359
|
replicateProvider: () => replicateProvider,
|
|
25360
|
+
resolveGeminiTextModel: () => resolveGeminiTextModel,
|
|
25310
25361
|
resolveVoiceId: () => resolveVoiceId,
|
|
25311
25362
|
runwayProvider: () => runwayProvider,
|
|
25312
25363
|
whisperProvider: () => whisperProvider
|
|
@@ -28479,6 +28530,7 @@ var MODEL_SETTINGS_BY_PROVIDER, ComposeBeatError, defaultCallLLM, CONFIG_PROVIDE
|
|
|
28479
28530
|
var init_compose_scenes_skills = __esm({
|
|
28480
28531
|
"src/commands/_shared/compose-scenes-skills.ts"() {
|
|
28481
28532
|
"use strict";
|
|
28533
|
+
init_dist2();
|
|
28482
28534
|
init_config();
|
|
28483
28535
|
init_bundle();
|
|
28484
28536
|
init_scene_lint();
|
|
@@ -28500,12 +28552,12 @@ var init_compose_scenes_skills = __esm({
|
|
|
28500
28552
|
medium: { model: "gpt-5", maxTokens: 6e3, costPerMTokIn: 1.25, costPerMTokOut: 10 },
|
|
28501
28553
|
high: { model: "gpt-5", maxTokens: 8e3, costPerMTokIn: 1.25, costPerMTokOut: 10 }
|
|
28502
28554
|
},
|
|
28503
|
-
// Google Gemini
|
|
28504
|
-
//
|
|
28555
|
+
// Google Gemini 3.5 Flash — current one-shot Gemini default for
|
|
28556
|
+
// analysis/composition. Keep agent loops on their explicit 2.5 Flash default.
|
|
28505
28557
|
gemini: {
|
|
28506
|
-
low: { model:
|
|
28507
|
-
medium: { model:
|
|
28508
|
-
high: { model:
|
|
28558
|
+
low: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 4e3, costPerMTokIn: 1.5, costPerMTokOut: 9 },
|
|
28559
|
+
medium: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 6e3, costPerMTokIn: 1.5, costPerMTokOut: 9 },
|
|
28560
|
+
high: { model: GEMINI_DEFAULT_TEXT_MODEL, maxTokens: 8e3, costPerMTokIn: 1.5, costPerMTokOut: 9 }
|
|
28509
28561
|
}
|
|
28510
28562
|
};
|
|
28511
28563
|
ComposeBeatError = class extends Error {
|
|
@@ -31670,12 +31722,37 @@ async function executeVideoStatus(options) {
|
|
|
31670
31722
|
} = options;
|
|
31671
31723
|
try {
|
|
31672
31724
|
const envKeyMap = {
|
|
31725
|
+
grok: "XAI_API_KEY",
|
|
31673
31726
|
runway: "RUNWAY_API_SECRET",
|
|
31674
|
-
kling: "KLING_API_KEY"
|
|
31727
|
+
kling: "KLING_API_KEY",
|
|
31728
|
+
veo: "GOOGLE_API_KEY"
|
|
31675
31729
|
};
|
|
31676
31730
|
const key = apiKey || process.env[envKeyMap[provider] || ""];
|
|
31677
31731
|
if (!key) return { success: false, error: `${envKeyMap[provider]} required` };
|
|
31678
|
-
if (provider === "
|
|
31732
|
+
if (provider === "grok") {
|
|
31733
|
+
const grok = new GrokProvider();
|
|
31734
|
+
await grok.initialize({ apiKey: key });
|
|
31735
|
+
let result = await grok.getGenerationStatus(taskId);
|
|
31736
|
+
if (wait && result.status !== "completed" && result.status !== "failed") {
|
|
31737
|
+
result = await grok.waitForCompletion(taskId, () => {
|
|
31738
|
+
});
|
|
31739
|
+
}
|
|
31740
|
+
let outputPath;
|
|
31741
|
+
if (output && result.videoUrl) {
|
|
31742
|
+
const buffer = await downloadVideo(result.videoUrl);
|
|
31743
|
+
outputPath = resolve19(process.cwd(), output);
|
|
31744
|
+
await writeFile14(outputPath, buffer);
|
|
31745
|
+
}
|
|
31746
|
+
return {
|
|
31747
|
+
success: true,
|
|
31748
|
+
taskId,
|
|
31749
|
+
status: result.status,
|
|
31750
|
+
progress: result.progress,
|
|
31751
|
+
videoUrl: result.videoUrl,
|
|
31752
|
+
outputPath,
|
|
31753
|
+
error: result.error
|
|
31754
|
+
};
|
|
31755
|
+
} else if (provider === "runway") {
|
|
31679
31756
|
const runway = new RunwayProvider();
|
|
31680
31757
|
await runway.initialize({ apiKey: key });
|
|
31681
31758
|
let result = await runway.getGenerationStatus(taskId);
|
|
@@ -31717,7 +31794,31 @@ async function executeVideoStatus(options) {
|
|
|
31717
31794
|
status: result.status,
|
|
31718
31795
|
videoUrl: result.videoUrl,
|
|
31719
31796
|
duration: result.duration,
|
|
31720
|
-
outputPath
|
|
31797
|
+
outputPath,
|
|
31798
|
+
error: result.error
|
|
31799
|
+
};
|
|
31800
|
+
} else if (provider === "veo") {
|
|
31801
|
+
const gemini = new GeminiProvider();
|
|
31802
|
+
await gemini.initialize({ apiKey: key });
|
|
31803
|
+
let result = await gemini.getGenerationStatus(taskId);
|
|
31804
|
+
if (wait && result.status !== "completed" && result.status !== "failed" && result.status !== "cancelled") {
|
|
31805
|
+
result = await gemini.waitForVideoCompletion(taskId, () => {
|
|
31806
|
+
});
|
|
31807
|
+
}
|
|
31808
|
+
let outputPath;
|
|
31809
|
+
if (output && result.videoUrl) {
|
|
31810
|
+
const buffer = await downloadVideo(result.videoUrl, key);
|
|
31811
|
+
outputPath = resolve19(process.cwd(), output);
|
|
31812
|
+
await writeFile14(outputPath, buffer);
|
|
31813
|
+
}
|
|
31814
|
+
return {
|
|
31815
|
+
success: true,
|
|
31816
|
+
taskId,
|
|
31817
|
+
status: result.status,
|
|
31818
|
+
progress: result.progress,
|
|
31819
|
+
videoUrl: result.videoUrl,
|
|
31820
|
+
outputPath,
|
|
31821
|
+
error: result.error
|
|
31721
31822
|
};
|
|
31722
31823
|
}
|
|
31723
31824
|
return { success: false, error: `Unsupported provider: ${provider}` };
|
|
@@ -32295,7 +32396,7 @@ function resolveRefreshOutput(record, opts) {
|
|
|
32295
32396
|
return record.outputPath ? resolve21(record.outputPath) : void 0;
|
|
32296
32397
|
}
|
|
32297
32398
|
function liveSupport(record) {
|
|
32298
|
-
if (record.jobType === "generate-video" && (record.provider === "runway" || record.provider === "kling")) {
|
|
32399
|
+
if (record.jobType === "generate-video" && (record.provider === "grok" || record.provider === "runway" || record.provider === "kling" || record.provider === "veo")) {
|
|
32299
32400
|
return { supported: true };
|
|
32300
32401
|
}
|
|
32301
32402
|
if (record.jobType === "generate-music" && record.provider === "replicate") {
|
|
@@ -32677,7 +32778,9 @@ function isActiveStatus(status) {
|
|
|
32677
32778
|
}
|
|
32678
32779
|
function providerStatusCommand(record) {
|
|
32679
32780
|
if (record.jobType === "generate-video") {
|
|
32680
|
-
if (record.provider !== "runway" && record.provider !== "kling"
|
|
32781
|
+
if (record.provider !== "grok" && record.provider !== "runway" && record.provider !== "kling" && record.provider !== "veo") {
|
|
32782
|
+
return void 0;
|
|
32783
|
+
}
|
|
32681
32784
|
const type = record.provider === "kling" && record.providerTaskType ? ` --type ${record.providerTaskType}` : "";
|
|
32682
32785
|
return `vibe generate video-status ${record.providerTaskId} -p ${record.provider}${type} --json`;
|
|
32683
32786
|
}
|
|
@@ -35178,12 +35281,7 @@ async function detectSilencePeriodsWithGemini(videoPath, minDuration, options) {
|
|
|
35178
35281
|
const gemini = new GeminiProvider();
|
|
35179
35282
|
await gemini.initialize({ apiKey: geminiApiKey });
|
|
35180
35283
|
const videoBuffer = await readFile18(videoPath);
|
|
35181
|
-
const
|
|
35182
|
-
flash: "gemini-3-flash-preview",
|
|
35183
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
35184
|
-
pro: "gemini-2.5-pro"
|
|
35185
|
-
};
|
|
35186
|
-
const modelId = options.model ? modelMap[options.model] || modelMap.flash : void 0;
|
|
35284
|
+
const modelId = options.model ? resolveGeminiTextModel(options.model) : void 0;
|
|
35187
35285
|
const prompt3 = `Analyze this video and identify all silent or dead segments where there is NO meaningful content.
|
|
35188
35286
|
|
|
35189
35287
|
Detect these as silent/dead segments:
|
|
@@ -38635,7 +38733,7 @@ Use this image analysis to inform the color palette, typography placement, and o
|
|
|
38635
38733
|
6. Recommended animation timing and entrance/exit style
|
|
38636
38734
|
7. Any moments where overlays should pause, fade, or stay minimal`;
|
|
38637
38735
|
const analysisResult = await gemini.analyzeVideo(videoBuffer, analysisPrompt, {
|
|
38638
|
-
model:
|
|
38736
|
+
model: GEMINI_DEFAULT_TEXT_MODEL,
|
|
38639
38737
|
fps: 1,
|
|
38640
38738
|
lowResolution: true
|
|
38641
38739
|
});
|
|
@@ -38804,7 +38902,7 @@ function registerMotionCommand(aiCommand) {
|
|
|
38804
38902
|
"auto"
|
|
38805
38903
|
).option("--understanding-prompt <text>", "Custom prompt for --video understanding").option("--from-tsx <path>", "Refine an existing TSX file instead of generating from scratch").option(
|
|
38806
38904
|
"-m, --model <alias>",
|
|
38807
|
-
"LLM model: sonnet (default), opus, gemini, gemini-3.1-pro",
|
|
38905
|
+
"LLM model: sonnet (default), opus, gemini, gemini-2.5-pro, gemini-3.1-pro",
|
|
38808
38906
|
"sonnet"
|
|
38809
38907
|
).option("--dry-run", "Preview parameters without executing").action(async (description, options) => {
|
|
38810
38908
|
const startedAt = Date.now();
|
|
@@ -38948,7 +39046,8 @@ var init_ai_motion = __esm({
|
|
|
38948
39046
|
sonnet: { provider: "claude", modelId: "claude-sonnet-4-6" },
|
|
38949
39047
|
opus: { provider: "claude", modelId: "claude-opus-4-7" },
|
|
38950
39048
|
"opus-4-6": { provider: "claude", modelId: "claude-opus-4-6" },
|
|
38951
|
-
gemini: { provider: "gemini", modelId:
|
|
39049
|
+
gemini: { provider: "gemini", modelId: GEMINI_DEFAULT_TEXT_MODEL },
|
|
39050
|
+
"gemini-2.5-pro": { provider: "gemini", modelId: "gemini-2.5-pro" },
|
|
38952
39051
|
"gemini-3.1-pro": { provider: "gemini", modelId: "gemini-3.1-pro-preview" }
|
|
38953
39052
|
};
|
|
38954
39053
|
}
|
|
@@ -39529,7 +39628,7 @@ async function executeMotionOverlay(options) {
|
|
|
39529
39628
|
};
|
|
39530
39629
|
}
|
|
39531
39630
|
function registerMotionOverlayCommand(parent) {
|
|
39532
|
-
parent.command("motion-overlay").description("Apply designed motion graphics overlays to an existing video").argument("<video>", "Video file path").argument("[description]", "Motion overlay description (omit when using --asset)").option("--asset <path>", "User-provided .json/.lottie animation to overlay").option("-o, --output <path>", "Output video file path").option("-d, --duration <sec>", "Overlay/render duration in seconds").option("--start <sec>", "Overlay start time in seconds", "0").option("--style <style>", "Style preset for generated overlays: minimal, corporate, playful, cinematic").option("-m, --model <alias>", "LLM model for generated overlays: sonnet, opus, gemini, gemini-3.1-pro", "sonnet").option("--understand <mode>", "Analyze video before generated overlay: auto, off, required", "auto").option("--understanding-prompt <text>", "Custom prompt for video understanding").option("--position <position>", "Lottie position: full, center, top-left, top-right, bottom-left, bottom-right", "full").option("--scale <number>", "Lottie overlay scale (0.01-2)").option("--opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--loop", "Loop Lottie overlay", true).option("--no-loop", "Do not loop Lottie overlay").option("--dry-run", "Preview parameters without executing").action(async (videoPath, description, options) => {
|
|
39631
|
+
parent.command("motion-overlay").description("Apply designed motion graphics overlays to an existing video").argument("<video>", "Video file path").argument("[description]", "Motion overlay description (omit when using --asset)").option("--asset <path>", "User-provided .json/.lottie animation to overlay").option("-o, --output <path>", "Output video file path").option("-d, --duration <sec>", "Overlay/render duration in seconds").option("--start <sec>", "Overlay start time in seconds", "0").option("--style <style>", "Style preset for generated overlays: minimal, corporate, playful, cinematic").option("-m, --model <alias>", "LLM model for generated overlays: sonnet, opus, gemini, gemini-2.5-pro, gemini-3.1-pro", "sonnet").option("--understand <mode>", "Analyze video before generated overlay: auto, off, required", "auto").option("--understanding-prompt <text>", "Custom prompt for video understanding").option("--position <position>", "Lottie position: full, center, top-left, top-right, bottom-left, bottom-right", "full").option("--scale <number>", "Lottie overlay scale (0.01-2)").option("--opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--loop", "Loop Lottie overlay", true).option("--no-loop", "Do not loop Lottie overlay").option("--dry-run", "Preview parameters without executing").action(async (videoPath, description, options) => {
|
|
39533
39632
|
const startedAt = Date.now();
|
|
39534
39633
|
try {
|
|
39535
39634
|
if (options.output) validateOutputPath(options.output);
|
|
@@ -40818,13 +40917,7 @@ async function executeThumbnailBestFrame(options) {
|
|
|
40818
40917
|
await gemini.initialize({ apiKey: googleKey });
|
|
40819
40918
|
const videoData = await readFile25(videoPath);
|
|
40820
40919
|
const analysisPrompt = prompt3 || 'Analyze this video and find the single best frame for a thumbnail. Look for frames that are visually striking, well-composed, emotionally engaging, and representative of the video content. Avoid blurry frames, transitions, or dark scenes. Return ONLY a JSON object: {"timestamp": <seconds as number>, "reason": "<brief explanation>"}';
|
|
40821
|
-
const
|
|
40822
|
-
flash: "gemini-3-flash-preview",
|
|
40823
|
-
latest: "gemini-2.5-flash",
|
|
40824
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
40825
|
-
pro: "gemini-2.5-pro"
|
|
40826
|
-
};
|
|
40827
|
-
const modelId = modelMap[model] || "gemini-3-flash-preview";
|
|
40920
|
+
const modelId = resolveGeminiTextModel(model);
|
|
40828
40921
|
const result = await gemini.analyzeVideo(videoData, analysisPrompt, {
|
|
40829
40922
|
model: modelId,
|
|
40830
40923
|
fps: 1
|
|
@@ -40884,12 +40977,7 @@ async function executeGeminiVideo(options) {
|
|
|
40884
40977
|
return { success: false, error: "Google API key required. Run 'vibe setup' or set GOOGLE_API_KEY in .env" };
|
|
40885
40978
|
}
|
|
40886
40979
|
const isYouTube = options.source.includes("youtube.com") || options.source.includes("youtu.be");
|
|
40887
|
-
const
|
|
40888
|
-
flash: "gemini-3-flash-preview",
|
|
40889
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
40890
|
-
pro: "gemini-2.5-pro"
|
|
40891
|
-
};
|
|
40892
|
-
const modelId = modelMap[options.model || "flash"] || modelMap.flash;
|
|
40980
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
40893
40981
|
let videoData;
|
|
40894
40982
|
if (isYouTube) {
|
|
40895
40983
|
videoData = options.source;
|
|
@@ -40950,12 +41038,7 @@ async function executeAnalyze(options) {
|
|
|
40950
41038
|
error: "Cannot detect source type. Supported: images (.png/.jpg/.webp/.gif), videos (.mp4/.mov/.webm), YouTube URLs, image URLs."
|
|
40951
41039
|
};
|
|
40952
41040
|
}
|
|
40953
|
-
const
|
|
40954
|
-
flash: "gemini-3-flash-preview",
|
|
40955
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
40956
|
-
pro: "gemini-2.5-pro"
|
|
40957
|
-
};
|
|
40958
|
-
const modelId = modelMap[options.model || "flash"] || modelMap.flash;
|
|
41041
|
+
const modelId = resolveGeminiTextModel(options.model);
|
|
40959
41042
|
const gemini = new GeminiProvider();
|
|
40960
41043
|
await gemini.initialize({ apiKey });
|
|
40961
41044
|
if (isImage) {
|
|
@@ -41035,7 +41118,7 @@ async function executeAnalyze(options) {
|
|
|
41035
41118
|
}
|
|
41036
41119
|
}
|
|
41037
41120
|
function registerAnalyzeCommands(aiCommand) {
|
|
41038
|
-
aiCommand.command("gemini-video").description("Analyze video using Gemini (summarize, Q&A, extract info)").argument("<source>", "Video file path or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>",
|
|
41121
|
+
aiCommand.command("gemini-video").description("Analyze video using Gemini (summarize, Q&A, extract info)").argument("<source>", "Video file path or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>", `Model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("--fps <number>", "Frames per second (default: 1, higher for action)").option("--start <seconds>", "Start offset in seconds (for clipping)").option("--end <seconds>", "End offset in seconds (for clipping)").option("--low-res", "Use low resolution mode (fewer tokens, longer videos)").option("-v, --verbose", "Show token usage").action(async (source, prompt3, options) => {
|
|
41039
41122
|
try {
|
|
41040
41123
|
if (options.apiKey) {
|
|
41041
41124
|
process.env.GOOGLE_API_KEY = options.apiKey;
|
|
@@ -41078,7 +41161,7 @@ function registerAnalyzeCommands(aiCommand) {
|
|
|
41078
41161
|
exitWithError(apiError(`Video analysis failed: ${error instanceof Error ? error.message : String(error)}`, true));
|
|
41079
41162
|
}
|
|
41080
41163
|
});
|
|
41081
|
-
aiCommand.command("analyze").description("Analyze any media: images, videos, or YouTube URLs using Gemini").argument("<source>", "Image/video file path, image URL, or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Describe this image', 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>",
|
|
41164
|
+
aiCommand.command("analyze").description("Analyze any media: images, videos, or YouTube URLs using Gemini").argument("<source>", "Image/video file path, image URL, or YouTube URL").argument("<prompt>", "Analysis prompt (e.g., 'Describe this image', 'Summarize this video')").option("-k, --api-key <key>", "Google API key (or set GOOGLE_API_KEY env)").option("-m, --model <model>", `Model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("--fps <number>", "Frames per second for video (default: 1)").option("--start <seconds>", "Start offset in seconds (video only)").option("--end <seconds>", "End offset in seconds (video only)").option("--low-res", "Use low resolution mode (fewer tokens)").option("-v, --verbose", "Show token usage").action(async (source, prompt3, options) => {
|
|
41082
41165
|
try {
|
|
41083
41166
|
if (options.apiKey) {
|
|
41084
41167
|
process.env.GOOGLE_API_KEY = options.apiKey;
|
|
@@ -41199,12 +41282,7 @@ ${content}`;
|
|
|
41199
41282
|
|
|
41200
41283
|
Project context for beat-aware review:
|
|
41201
41284
|
${projectContext}` : "";
|
|
41202
|
-
const
|
|
41203
|
-
flash: "gemini-3-flash-preview",
|
|
41204
|
-
"flash-2.5": "gemini-2.5-flash",
|
|
41205
|
-
pro: "gemini-2.5-pro"
|
|
41206
|
-
};
|
|
41207
|
-
const modelId = modelMap[model] || modelMap.flash;
|
|
41285
|
+
const modelId = resolveGeminiTextModel(model);
|
|
41208
41286
|
const reviewPrompt = `You are a professional video editor reviewing this video for quality. Analyze the video and return a JSON review with the following structure. Return ONLY valid JSON, no extra text.
|
|
41209
41287
|
|
|
41210
41288
|
{
|
|
@@ -41311,7 +41389,7 @@ Score each category 1-10. Prefer beatIssues when you can map a problem to a stor
|
|
|
41311
41389
|
return result;
|
|
41312
41390
|
}
|
|
41313
41391
|
function registerReviewCommand(aiCommand) {
|
|
41314
|
-
aiCommand.command("review", { hidden: true }).description("Review video quality using Gemini AI and optionally auto-fix issues").argument("<source>", "Video file path").option("--storyboard <path>", "Storyboard JSON file for context").option("--auto-apply", "Automatically apply fixable corrections").option("--verify", "Run verification pass after applying fixes").option("-m, --model <model>",
|
|
41392
|
+
aiCommand.command("review", { hidden: true }).description("Review video quality using Gemini AI and optionally auto-fix issues").argument("<source>", "Video file path").option("--storyboard <path>", "Storyboard JSON file for context").option("--auto-apply", "Automatically apply fixable corrections").option("--verify", "Run verification pass after applying fixes").option("-m, --model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").option("-o, --output <path>", "Output video file path (for auto-apply)").option("--dry-run", "Preview parameters without executing").action(async (videoPath, options) => {
|
|
41315
41393
|
const startedAt = Date.now();
|
|
41316
41394
|
try {
|
|
41317
41395
|
if (options.output) {
|
|
@@ -42198,7 +42276,7 @@ import { resolve as resolve46, dirname as dirname19, basename as basename13, ext
|
|
|
42198
42276
|
import { existsSync as existsSync38 } from "node:fs";
|
|
42199
42277
|
import { writeFile as writeFile34, mkdir as mkdir20 } from "node:fs/promises";
|
|
42200
42278
|
function registerThumbnailCommand(parent) {
|
|
42201
|
-
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>",
|
|
42279
|
+
parent.command("thumbnail").description("Generate video thumbnail (DALL-E) or extract best frame from video (Gemini)").argument("[description]", "Thumbnail description (for DALL-E generation)").option("-k, --api-key <key>", "API key (OpenAI for generation, Google for best-frame)").option("-o, --output <path>", "Output file path").option("--style <style>", "Platform style: youtube, instagram, tiktok, twitter").option("--best-frame <video>", "Extract best thumbnail frame from video using Gemini AI").option("--prompt <prompt>", "Custom prompt for best-frame analysis").option("--model <model>", `Gemini model: ${GEMINI_TEXT_MODEL_HELP}`, "flash").action(async (description, options) => {
|
|
42202
42280
|
const startedAt = Date.now();
|
|
42203
42281
|
try {
|
|
42204
42282
|
if (description) rejectControlChars(description);
|
|
@@ -42364,7 +42442,10 @@ function getStatusColor(status) {
|
|
|
42364
42442
|
}
|
|
42365
42443
|
}
|
|
42366
42444
|
function registerVideoStatusCommand(parent) {
|
|
42367
|
-
parent.command("video-status", { hidden: true }).description("Check video generation status (Grok, Runway, or
|
|
42445
|
+
parent.command("video-status", { hidden: true }).description("Check video generation status (Grok, Runway, Kling, or Veo)").argument("<task-id>", "Task ID from video generation").option("-p, --provider <provider>", "Provider: grok, runway, kling, veo", "grok").option(
|
|
42446
|
+
"-k, --api-key <key>",
|
|
42447
|
+
"API key (or set XAI_API_KEY / RUNWAY_API_SECRET / KLING_API_KEY / GOOGLE_API_KEY env)"
|
|
42448
|
+
).option("--type <type>", "Task type: text2video or image2video (Kling only)", "text2video").option("--wait", "Wait for completion").option("-o, --output <path>", "Download video when complete").action(async (taskId, options) => {
|
|
42368
42449
|
const startedAt = Date.now();
|
|
42369
42450
|
try {
|
|
42370
42451
|
const provider = (options.provider || "grok").toLowerCase();
|
|
@@ -42424,18 +42505,12 @@ function registerVideoStatusCommand(parent) {
|
|
|
42424
42505
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
42425
42506
|
} catch (err) {
|
|
42426
42507
|
downloadSpinner.fail(
|
|
42427
|
-
source_default.red(
|
|
42428
|
-
`Failed to download video: ${err instanceof Error ? err.message : err}`
|
|
42429
|
-
)
|
|
42508
|
+
source_default.red(`Failed to download video: ${err instanceof Error ? err.message : err}`)
|
|
42430
42509
|
);
|
|
42431
42510
|
}
|
|
42432
42511
|
}
|
|
42433
42512
|
} else if (provider === "runway") {
|
|
42434
|
-
const apiKey = await requireApiKey(
|
|
42435
|
-
"RUNWAY_API_SECRET",
|
|
42436
|
-
"Runway",
|
|
42437
|
-
options.apiKey
|
|
42438
|
-
);
|
|
42513
|
+
const apiKey = await requireApiKey("RUNWAY_API_SECRET", "Runway", options.apiKey);
|
|
42439
42514
|
const spinner2 = ora("Checking status...").start();
|
|
42440
42515
|
const runway = new RunwayProvider();
|
|
42441
42516
|
await runway.initialize({ apiKey });
|
|
@@ -42496,9 +42571,7 @@ function registerVideoStatusCommand(parent) {
|
|
|
42496
42571
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
42497
42572
|
} catch (err) {
|
|
42498
42573
|
downloadSpinner.fail(
|
|
42499
|
-
source_default.red(
|
|
42500
|
-
`Failed to download video: ${err instanceof Error ? err.message : err}`
|
|
42501
|
-
)
|
|
42574
|
+
source_default.red(`Failed to download video: ${err instanceof Error ? err.message : err}`)
|
|
42502
42575
|
);
|
|
42503
42576
|
}
|
|
42504
42577
|
}
|
|
@@ -42564,15 +42637,77 @@ function registerVideoStatusCommand(parent) {
|
|
|
42564
42637
|
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
42565
42638
|
} catch (err) {
|
|
42566
42639
|
downloadSpinner.fail(
|
|
42567
|
-
source_default.red(
|
|
42568
|
-
|
|
42569
|
-
|
|
42640
|
+
source_default.red(`Failed to download video: ${err instanceof Error ? err.message : err}`)
|
|
42641
|
+
);
|
|
42642
|
+
}
|
|
42643
|
+
}
|
|
42644
|
+
} else if (provider === "veo") {
|
|
42645
|
+
const apiKey = await requireApiKey("GOOGLE_API_KEY", "Google", options.apiKey);
|
|
42646
|
+
const spinner2 = ora("Checking status...").start();
|
|
42647
|
+
const gemini = new GeminiProvider();
|
|
42648
|
+
await gemini.initialize({ apiKey });
|
|
42649
|
+
let result = await gemini.getGenerationStatus(taskId);
|
|
42650
|
+
if (options.wait && result.status !== "completed" && result.status !== "failed" && result.status !== "cancelled") {
|
|
42651
|
+
spinner2.text = "Waiting for completion...";
|
|
42652
|
+
result = await gemini.waitForVideoCompletion(taskId, (status) => {
|
|
42653
|
+
spinner2.text = status.progress !== void 0 ? `Generating... ${status.progress}%` : `Generating... ${status.status}`;
|
|
42654
|
+
});
|
|
42655
|
+
}
|
|
42656
|
+
spinner2.stop();
|
|
42657
|
+
if (isJsonMode()) {
|
|
42658
|
+
let outputPath;
|
|
42659
|
+
if (options.output && result.videoUrl) {
|
|
42660
|
+
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
42661
|
+
outputPath = resolve47(process.cwd(), options.output);
|
|
42662
|
+
await writeFile35(outputPath, buffer);
|
|
42663
|
+
}
|
|
42664
|
+
outputSuccess({
|
|
42665
|
+
command: "generate video-status",
|
|
42666
|
+
startedAt,
|
|
42667
|
+
data: {
|
|
42668
|
+
taskId,
|
|
42669
|
+
provider: "veo",
|
|
42670
|
+
status: result.status,
|
|
42671
|
+
videoUrl: result.videoUrl,
|
|
42672
|
+
progress: result.progress,
|
|
42673
|
+
error: result.error,
|
|
42674
|
+
outputPath
|
|
42675
|
+
}
|
|
42676
|
+
});
|
|
42677
|
+
return;
|
|
42678
|
+
}
|
|
42679
|
+
console.log();
|
|
42680
|
+
console.log(source_default.bold.cyan("Generation Status"));
|
|
42681
|
+
console.log(source_default.dim("\u2500".repeat(60)));
|
|
42682
|
+
console.log(`Task ID: ${taskId}`);
|
|
42683
|
+
console.log(`Provider: Veo`);
|
|
42684
|
+
console.log(`Status: ${getStatusColor(result.status)}`);
|
|
42685
|
+
if (result.progress !== void 0) {
|
|
42686
|
+
console.log(`Progress: ${result.progress}%`);
|
|
42687
|
+
}
|
|
42688
|
+
if (result.videoUrl) {
|
|
42689
|
+
console.log(`Video URL: ${result.videoUrl}`);
|
|
42690
|
+
}
|
|
42691
|
+
if (result.error) {
|
|
42692
|
+
console.log(`Error: ${source_default.red(result.error)}`);
|
|
42693
|
+
}
|
|
42694
|
+
console.log();
|
|
42695
|
+
if (options.output && result.videoUrl) {
|
|
42696
|
+
const downloadSpinner = ora("Downloading video...").start();
|
|
42697
|
+
try {
|
|
42698
|
+
const buffer = await downloadVideo(result.videoUrl, apiKey);
|
|
42699
|
+
const outputPath = resolve47(process.cwd(), options.output);
|
|
42700
|
+
await writeFile35(outputPath, buffer);
|
|
42701
|
+
downloadSpinner.succeed(source_default.green(`Saved to: ${outputPath}`));
|
|
42702
|
+
} catch (err) {
|
|
42703
|
+
downloadSpinner.fail(
|
|
42704
|
+
source_default.red(`Failed to download video: ${err instanceof Error ? err.message : err}`)
|
|
42570
42705
|
);
|
|
42571
42706
|
}
|
|
42572
42707
|
}
|
|
42573
42708
|
} else {
|
|
42574
42709
|
exitWithError(
|
|
42575
|
-
usageError(`Invalid provider: ${provider}. Use grok, runway, or
|
|
42710
|
+
usageError(`Invalid provider: ${provider}. Use grok, runway, kling, or veo.`)
|
|
42576
42711
|
);
|
|
42577
42712
|
}
|
|
42578
42713
|
} catch (error) {
|
|
@@ -44353,7 +44488,7 @@ function registerVideoCommand(parent) {
|
|
|
44353
44488
|
"--seedance-model <model>",
|
|
44354
44489
|
"Seedance variant: quality or fast (fal.ai only)",
|
|
44355
44490
|
"quality"
|
|
44356
|
-
).option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 720p, 1080p, 4k
|
|
44491
|
+
).option("--negative <prompt>", "Negative prompt - what to avoid (Kling/Veo)").option("--resolution <res>", "Video resolution: 480p, 720p, 1080p, or 4k depending on provider").option("--last-frame <path>", "Last frame image for frame interpolation (Veo) or Seedance end frame").option("--end-image <path>", "Ending frame image for Seedance image-to-video").option(
|
|
44357
44492
|
"--ref-images <paths...>",
|
|
44358
44493
|
"Reference images for Seedance reference-to-video or Veo character consistency"
|
|
44359
44494
|
).option("--ref-videos <paths...>", "Reference videos for Seedance reference-to-video").option("--ref-audio <paths...>", "Reference audio for Seedance reference-to-video").option("--no-generate-audio", "Disable native audio when the provider supports it").option("--person <mode>", "Person generation: allow_all, allow_adult (Veo only)").option("--veo-model <model>", "Veo model: 3.0, 3.1, 3.1-fast (default: 3.1-fast)", "3.1-fast").option(
|
|
@@ -44814,6 +44949,30 @@ Examples:
|
|
|
44814
44949
|
exitWithError(apiError(message, true));
|
|
44815
44950
|
}
|
|
44816
44951
|
}
|
|
44952
|
+
let seedanceEndImage;
|
|
44953
|
+
const seedanceEndImagePath = options.endImage ?? options.lastFrame;
|
|
44954
|
+
if (seedanceEndImagePath && seedanceReferences.length === 0) {
|
|
44955
|
+
try {
|
|
44956
|
+
const absEndImagePath = resolve50(process.cwd(), seedanceEndImagePath);
|
|
44957
|
+
const endImageBuffer = await readFile32(absEndImagePath);
|
|
44958
|
+
const ext = seedanceEndImagePath.toLowerCase().split(".").pop();
|
|
44959
|
+
const mimeType = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : `image/${ext || "png"}`;
|
|
44960
|
+
const uploadHost = await resolveUploadHost();
|
|
44961
|
+
spinner2.text = `Uploading end image via ${uploadHost.provider} for Seedance...`;
|
|
44962
|
+
const upload = await uploadHost.uploadImage(endImageBuffer, {
|
|
44963
|
+
filename: seedanceEndImagePath,
|
|
44964
|
+
mimeType
|
|
44965
|
+
});
|
|
44966
|
+
seedanceEndImage = upload.url;
|
|
44967
|
+
} catch (err) {
|
|
44968
|
+
spinner2.fail("End image upload failed");
|
|
44969
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
44970
|
+
if (message.includes("IMGBB_API_KEY")) {
|
|
44971
|
+
exitWithError(authError("IMGBB_API_KEY", "ImgBB"));
|
|
44972
|
+
}
|
|
44973
|
+
exitWithError(apiError(message, true));
|
|
44974
|
+
}
|
|
44975
|
+
}
|
|
44817
44976
|
spinner2.text = "Generating video with fal.ai Seedance 2.0 (this may take 1-3 minutes)...";
|
|
44818
44977
|
const seedanceModel = String(options.seedanceModel ?? "quality").toLowerCase();
|
|
44819
44978
|
const falModel = seedanceModel === "fast" || seedanceModel === "seedance-2.0-fast" ? "seedance-2.0-fast" : "seedance-2.0";
|
|
@@ -44826,7 +44985,8 @@ Examples:
|
|
|
44826
44985
|
negativePrompt: options.negative,
|
|
44827
44986
|
model: falModel,
|
|
44828
44987
|
resolution: options.resolution,
|
|
44829
|
-
generateAudio: options.generateAudio
|
|
44988
|
+
generateAudio: options.generateAudio,
|
|
44989
|
+
lastFrame: seedanceEndImage
|
|
44830
44990
|
});
|
|
44831
44991
|
finalResult = result;
|
|
44832
44992
|
}
|
|
@@ -50718,6 +50878,14 @@ var SCENE_PRESETS = [
|
|
|
50718
50878
|
"kinetic-type",
|
|
50719
50879
|
"product-shot"
|
|
50720
50880
|
];
|
|
50881
|
+
var LOTTIE_POSITIONS = [
|
|
50882
|
+
"full",
|
|
50883
|
+
"center",
|
|
50884
|
+
"top-left",
|
|
50885
|
+
"top-right",
|
|
50886
|
+
"bottom-left",
|
|
50887
|
+
"bottom-right"
|
|
50888
|
+
];
|
|
50721
50889
|
var GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js";
|
|
50722
50890
|
function esc(text) {
|
|
50723
50891
|
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -50998,6 +51166,56 @@ function buildPreset(input) {
|
|
|
50998
51166
|
}
|
|
50999
51167
|
}
|
|
51000
51168
|
}
|
|
51169
|
+
var DOTLOTTIE_WC_VERSION = "0.9.12";
|
|
51170
|
+
var DOTLOTTIE_WEB_VERSION = "0.71.0";
|
|
51171
|
+
var DOTLOTTIE_WC_CDN = `https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-wc@${DOTLOTTIE_WC_VERSION}/dist/index.js`;
|
|
51172
|
+
var DOTLOTTIE_WASM_CDN = `https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web@${DOTLOTTIE_WEB_VERSION}/dist/dotlottie-player.wasm`;
|
|
51173
|
+
function lottieOverlayStyle(input) {
|
|
51174
|
+
const pos = input.position ?? "full";
|
|
51175
|
+
const rawScale = input.scale ?? (pos === "full" ? 1 : 0.25);
|
|
51176
|
+
const scale = Math.max(0.01, Math.min(2, rawScale));
|
|
51177
|
+
const opacity = Math.max(0, Math.min(1, input.opacity ?? 1));
|
|
51178
|
+
const base = [
|
|
51179
|
+
"position:absolute",
|
|
51180
|
+
"pointer-events:none",
|
|
51181
|
+
`opacity:${opacity}`
|
|
51182
|
+
];
|
|
51183
|
+
if (pos === "full") {
|
|
51184
|
+
base.push("inset:0", "width:100%", "height:100%");
|
|
51185
|
+
} else {
|
|
51186
|
+
const pct = scale * 100;
|
|
51187
|
+
base.push(`width:${pct}%`, `height:${pct}%`);
|
|
51188
|
+
switch (pos) {
|
|
51189
|
+
case "center":
|
|
51190
|
+
base.push("top:50%", "left:50%", "transform:translate(-50%,-50%)");
|
|
51191
|
+
break;
|
|
51192
|
+
case "top-left":
|
|
51193
|
+
base.push("top:4%", "left:4%");
|
|
51194
|
+
break;
|
|
51195
|
+
case "top-right":
|
|
51196
|
+
base.push("top:4%", "right:4%");
|
|
51197
|
+
break;
|
|
51198
|
+
case "bottom-left":
|
|
51199
|
+
base.push("bottom:4%", "left:4%");
|
|
51200
|
+
break;
|
|
51201
|
+
case "bottom-right":
|
|
51202
|
+
base.push("bottom:4%", "right:4%");
|
|
51203
|
+
break;
|
|
51204
|
+
}
|
|
51205
|
+
}
|
|
51206
|
+
return base.join(";");
|
|
51207
|
+
}
|
|
51208
|
+
function buildLottieOverlay(input, sceneId) {
|
|
51209
|
+
const loop = input.loop ?? true ? " loop" : "";
|
|
51210
|
+
const style = lottieOverlayStyle(input);
|
|
51211
|
+
const overlayId = `lottie-overlay-${sceneId}`;
|
|
51212
|
+
const markup = `<dotlottie-wc id="${overlayId}" src="${esc(input.src)}" autoplay${loop} style="${style}"></dotlottie-wc>`;
|
|
51213
|
+
const script = `<script type="module">
|
|
51214
|
+
import { setWasmUrl } from "${DOTLOTTIE_WC_CDN}";
|
|
51215
|
+
setWasmUrl("${DOTLOTTIE_WASM_CDN}");
|
|
51216
|
+
</script>`;
|
|
51217
|
+
return { markup, script };
|
|
51218
|
+
}
|
|
51001
51219
|
function emitSceneHtml(input) {
|
|
51002
51220
|
if (input.duration <= 0) {
|
|
51003
51221
|
throw new Error(`Scene duration must be > 0, got ${input.duration}`);
|
|
@@ -51018,15 +51236,20 @@ function emitSceneHtml(input) {
|
|
|
51018
51236
|
data-volume="1"
|
|
51019
51237
|
></audio>
|
|
51020
51238
|
` : "";
|
|
51239
|
+
const lottieLayer = input.lottie ? buildLottieOverlay(input.lottie, id) : null;
|
|
51240
|
+
const lottieMarkup = lottieLayer ? `
|
|
51241
|
+
${lottieLayer.markup}` : "";
|
|
51242
|
+
const lottieScript = lottieLayer ? `
|
|
51243
|
+
${lottieLayer.script}` : "";
|
|
51021
51244
|
return `<template id="scene-${id}-template">
|
|
51022
51245
|
<div data-composition-id="${id}" data-start="0" data-duration="${dur}" data-width="${input.width}" data-height="${input.height}">
|
|
51023
51246
|
<style>
|
|
51024
51247
|
${parts.css}
|
|
51025
51248
|
</style>
|
|
51026
51249
|
|
|
51027
|
-
${parts.body}
|
|
51250
|
+
${parts.body}${lottieMarkup}
|
|
51028
51251
|
${audioBlock}
|
|
51029
|
-
<script src="${GSAP_CDN}"></script
|
|
51252
|
+
<script src="${GSAP_CDN}"></script>${lottieScript}
|
|
51030
51253
|
<script>
|
|
51031
51254
|
window.__timelines = window.__timelines || {};
|
|
51032
51255
|
const tl = gsap.timeline({ paused: true });
|
|
@@ -51450,9 +51673,40 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
51450
51673
|
).option("--no-image", "Skip image generation even when --visuals is provided").option(
|
|
51451
51674
|
"--no-transcribe",
|
|
51452
51675
|
"Skip Whisper word-level transcribe step (no transcript-<id>.json emitted)"
|
|
51453
|
-
).option("--transcribe-language <code>", "BCP-47 language code passed to Whisper (e.g. en, ko)").option("--force", "Overwrite an existing compositions/scene-<id>.html").option("--
|
|
51676
|
+
).option("--transcribe-language <code>", "BCP-47 language code passed to Whisper (e.g. en, ko)").option("--force", "Overwrite an existing compositions/scene-<id>.html").option("--lottie <path>", "Lottie animation file (.json/.lottie) to overlay on the scene").option(
|
|
51677
|
+
"--lottie-position <position>",
|
|
51678
|
+
`Lottie position: ${LOTTIE_POSITIONS.join(", ")}`,
|
|
51679
|
+
"full"
|
|
51680
|
+
).option("--lottie-scale <number>", "Lottie overlay scale (0.01-2)").option("--lottie-opacity <number>", "Lottie overlay opacity (0-1)", "1").option("--lottie-no-loop", "Do not loop the Lottie animation").option("--dry-run", "Preview parameters without writing files or calling APIs").action(async (name, options) => {
|
|
51454
51681
|
const startedAt = Date.now();
|
|
51455
51682
|
if (options.style) options.style = validatePreset(options.style);
|
|
51683
|
+
if (options.lottiePosition) {
|
|
51684
|
+
if (!LOTTIE_POSITIONS.includes(options.lottiePosition)) {
|
|
51685
|
+
exitWithError(
|
|
51686
|
+
usageError(
|
|
51687
|
+
`Invalid --lottie-position "${options.lottiePosition}". Valid: ${LOTTIE_POSITIONS.join(", ")}`
|
|
51688
|
+
)
|
|
51689
|
+
);
|
|
51690
|
+
}
|
|
51691
|
+
}
|
|
51692
|
+
let lottieScale;
|
|
51693
|
+
if (options.lottieScale !== void 0) {
|
|
51694
|
+
lottieScale = Number(options.lottieScale);
|
|
51695
|
+
if (!Number.isFinite(lottieScale) || lottieScale < 0.01 || lottieScale > 2) {
|
|
51696
|
+
exitWithError(
|
|
51697
|
+
usageError(`Invalid --lottie-scale "${options.lottieScale}". Must be between 0.01 and 2.`)
|
|
51698
|
+
);
|
|
51699
|
+
}
|
|
51700
|
+
}
|
|
51701
|
+
let lottieOpacity = 1;
|
|
51702
|
+
if (options.lottieOpacity !== void 0) {
|
|
51703
|
+
lottieOpacity = Number(options.lottieOpacity);
|
|
51704
|
+
if (!Number.isFinite(lottieOpacity) || lottieOpacity < 0 || lottieOpacity > 1) {
|
|
51705
|
+
exitWithError(
|
|
51706
|
+
usageError(`Invalid --lottie-opacity "${options.lottieOpacity}". Must be between 0 and 1.`)
|
|
51707
|
+
);
|
|
51708
|
+
}
|
|
51709
|
+
}
|
|
51456
51710
|
if (options.duration !== void 0) options.duration = validateDuration(options.duration);
|
|
51457
51711
|
let tts;
|
|
51458
51712
|
try {
|
|
@@ -51481,7 +51735,11 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
51481
51735
|
imageProvider: options.imageProvider,
|
|
51482
51736
|
tts,
|
|
51483
51737
|
audio: options.audio,
|
|
51484
|
-
|
|
51738
|
+
lottie: options.lottie ?? null,
|
|
51739
|
+
lottiePosition: options.lottiePosition,
|
|
51740
|
+
lottieScale: lottieScale ?? null,
|
|
51741
|
+
lottieOpacity: options.lottieOpacity !== void 0 ? lottieOpacity : null,
|
|
51742
|
+
lottieLoop: !options.lottieNoLoop,
|
|
51485
51743
|
image: options.image
|
|
51486
51744
|
}
|
|
51487
51745
|
}
|
|
@@ -51509,6 +51767,13 @@ sceneCommand.command("add").description("Add a new scene to a project: AI narrat
|
|
|
51509
51767
|
skipTranscribe: options.transcribe === false,
|
|
51510
51768
|
transcribeLanguage: options.transcribeLanguage,
|
|
51511
51769
|
force: !!options.force,
|
|
51770
|
+
lottie: options.lottie ? {
|
|
51771
|
+
src: options.lottie,
|
|
51772
|
+
position: options.lottiePosition ?? "full",
|
|
51773
|
+
scale: lottieScale,
|
|
51774
|
+
opacity: options.lottieOpacity !== void 0 ? lottieOpacity : 1,
|
|
51775
|
+
loop: !options.lottieNoLoop
|
|
51776
|
+
} : void 0,
|
|
51512
51777
|
onProgress: (msg) => {
|
|
51513
51778
|
if (spinner2) spinner2.text = msg;
|
|
51514
51779
|
}
|
|
@@ -51784,6 +52049,30 @@ async function executeSceneAdd(opts) {
|
|
|
51784
52049
|
await writeFile10(imageAbsPath, buffer);
|
|
51785
52050
|
}
|
|
51786
52051
|
}
|
|
52052
|
+
let lottieRelPath;
|
|
52053
|
+
let lottieAbsPath;
|
|
52054
|
+
let lottieInput;
|
|
52055
|
+
if (opts.lottie) {
|
|
52056
|
+
const sourceAbs = resolve12(opts.lottie.src);
|
|
52057
|
+
if (!await pathExists2(sourceAbs)) {
|
|
52058
|
+
return errResult(`Lottie file not found: ${sourceAbs}`);
|
|
52059
|
+
}
|
|
52060
|
+
const ext = (sourceAbs.match(/\.([a-z0-9]+)$/i)?.[1] ?? "json").toLowerCase();
|
|
52061
|
+
if (ext !== "json" && ext !== "lottie") {
|
|
52062
|
+
return errResult(`Unsupported Lottie file extension: .${ext}. Use .json or .lottie.`);
|
|
52063
|
+
}
|
|
52064
|
+
lottieRelPath = `assets/lottie-${id}.${ext}`;
|
|
52065
|
+
lottieAbsPath = resolve12(projectDir, lottieRelPath);
|
|
52066
|
+
await mkdir5(dirname3(lottieAbsPath), { recursive: true });
|
|
52067
|
+
await copyFile(sourceAbs, lottieAbsPath);
|
|
52068
|
+
lottieInput = {
|
|
52069
|
+
src: lottieRelPath,
|
|
52070
|
+
position: opts.lottie.position,
|
|
52071
|
+
scale: opts.lottie.scale,
|
|
52072
|
+
opacity: opts.lottie.opacity,
|
|
52073
|
+
loop: opts.lottie.loop
|
|
52074
|
+
};
|
|
52075
|
+
}
|
|
51787
52076
|
const cfg = await loadVibeProjectConfig(projectDir);
|
|
51788
52077
|
const fallback2 = cfg?.defaultSceneDuration ?? 5;
|
|
51789
52078
|
const NARRATION_TAIL_BUFFER = 0.5;
|
|
@@ -51812,7 +52101,8 @@ async function executeSceneAdd(opts) {
|
|
|
51812
52101
|
kicker: opts.kicker,
|
|
51813
52102
|
imagePath: imageRelPath,
|
|
51814
52103
|
audioPath: audioRelPath,
|
|
51815
|
-
transcript: transcriptWords
|
|
52104
|
+
transcript: transcriptWords,
|
|
52105
|
+
lottie: lottieInput
|
|
51816
52106
|
});
|
|
51817
52107
|
await mkdir5(dirname3(scenePath), { recursive: true });
|
|
51818
52108
|
await writeFile10(scenePath, sceneHtml, "utf-8");
|
|
@@ -51833,6 +52123,7 @@ async function executeSceneAdd(opts) {
|
|
|
51833
52123
|
rootPath: relative5(process.cwd(), rootPath) || rootPath,
|
|
51834
52124
|
audioPath: audioAbsPath ? relative5(process.cwd(), audioAbsPath) || audioAbsPath : void 0,
|
|
51835
52125
|
imagePath: imageAbsPath ? relative5(process.cwd(), imageAbsPath) || imageAbsPath : void 0,
|
|
52126
|
+
lottiePath: lottieAbsPath ? relative5(process.cwd(), lottieAbsPath) || lottieAbsPath : void 0,
|
|
51836
52127
|
transcriptPath: transcriptAbsPath ? relative5(process.cwd(), transcriptAbsPath) || transcriptAbsPath : void 0,
|
|
51837
52128
|
transcriptWordCount
|
|
51838
52129
|
};
|
|
@@ -53099,7 +53390,7 @@ var editMotionOverlayTool = defineTool({
|
|
|
53099
53390
|
duration: external_exports.number().optional().describe("Overlay/render duration in seconds"),
|
|
53100
53391
|
start: external_exports.number().optional().describe("Overlay start time in seconds"),
|
|
53101
53392
|
style: external_exports.string().optional().describe("Style preset for generated overlays"),
|
|
53102
|
-
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-3.1-pro"]).optional().describe("LLM model for generated overlays"),
|
|
53393
|
+
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-2.5-pro", "gemini-3.1-pro"]).optional().describe("LLM model for generated overlays"),
|
|
53103
53394
|
understand: external_exports.enum(["auto", "off", "required"]).optional().describe("Analyze video before generated overlay (default: auto)"),
|
|
53104
53395
|
understandingPrompt: external_exports.string().optional().describe("Custom prompt for video understanding"),
|
|
53105
53396
|
position: external_exports.enum(["full", "center", "top-left", "top-right", "bottom-left", "bottom-right"]).optional().describe("Lottie overlay position"),
|
|
@@ -54833,7 +55124,7 @@ var inspectRenderTool = defineTool({
|
|
|
54833
55124
|
outputPath: external_exports.string().optional().describe("Optional review report path. Defaults to <project>/review-report.json."),
|
|
54834
55125
|
report: external_exports.boolean().optional().describe("Write review-report.json. Default true."),
|
|
54835
55126
|
ai: external_exports.boolean().optional().describe("Also run Gemini video review and merge findings into review-report.json. Default false."),
|
|
54836
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant for ai review. Default flash."),
|
|
55127
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant for ai review. Default flash."),
|
|
54837
55128
|
dryRun: external_exports.boolean().optional().describe("Preview resolved inputs without probing video or calling Gemini.")
|
|
54838
55129
|
}),
|
|
54839
55130
|
async execute(args, ctx) {
|
|
@@ -54885,7 +55176,7 @@ var analyzeMediaTool = defineTool({
|
|
|
54885
55176
|
schema: external_exports.object({
|
|
54886
55177
|
source: external_exports.string().describe("Path to image/video or YouTube URL"),
|
|
54887
55178
|
prompt: external_exports.string().describe("Analysis prompt (e.g., 'Describe the scene', 'Count people')"),
|
|
54888
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
55179
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
54889
55180
|
fps: external_exports.number().optional().describe("Frames per second for video sampling (default: 1)"),
|
|
54890
55181
|
start: external_exports.number().optional().describe("Start time in seconds for video analysis"),
|
|
54891
55182
|
end: external_exports.number().optional().describe("End time in seconds for video analysis"),
|
|
@@ -54913,7 +55204,7 @@ var analyzeVideoTool = defineTool({
|
|
|
54913
55204
|
schema: external_exports.object({
|
|
54914
55205
|
source: external_exports.string().describe("Path to video file"),
|
|
54915
55206
|
prompt: external_exports.string().describe("Analysis prompt"),
|
|
54916
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
55207
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
54917
55208
|
fps: external_exports.number().optional().describe("Frames per second for sampling"),
|
|
54918
55209
|
start: external_exports.number().optional().describe("Start time in seconds"),
|
|
54919
55210
|
end: external_exports.number().optional().describe("End time in seconds"),
|
|
@@ -54943,7 +55234,7 @@ var analyzeReviewTool = defineTool({
|
|
|
54943
55234
|
storyboardPath: external_exports.string().optional().describe("Path to storyboard.json for intent comparison"),
|
|
54944
55235
|
autoApply: external_exports.boolean().optional().describe("Automatically apply suggested fixes (default: false)"),
|
|
54945
55236
|
verify: external_exports.boolean().optional().describe("Re-review after applying fixes (default: false)"),
|
|
54946
|
-
model: external_exports.enum(["flash", "flash-2.5", "pro"]).optional().describe("Gemini model variant (default: flash)"),
|
|
55237
|
+
model: external_exports.enum(["flash", "latest", "flash-3", "flash-2.5", "pro", "pro-3.1"]).optional().describe("Gemini model variant (default: flash)"),
|
|
54947
55238
|
outputPath: external_exports.string().optional().describe("Output path for fixed video")
|
|
54948
55239
|
}),
|
|
54949
55240
|
async execute(args) {
|
|
@@ -55027,7 +55318,7 @@ var generateMotionTool = defineTool({
|
|
|
55027
55318
|
"Analyze the base video with Gemini before generating motion graphics: auto, off, or required (default: auto)"
|
|
55028
55319
|
),
|
|
55029
55320
|
understandingPrompt: external_exports.string().optional().describe("Custom prompt for video understanding when --video is provided"),
|
|
55030
|
-
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-3.1-pro"]).optional().describe("LLM model for code generation (default: sonnet)"),
|
|
55321
|
+
model: external_exports.enum(["sonnet", "opus", "gemini", "gemini-2.5-pro", "gemini-3.1-pro"]).optional().describe("LLM model for code generation (default: sonnet)"),
|
|
55031
55322
|
output: external_exports.string().optional().describe("Output path (TSX if code-only, MP4 if rendered)")
|
|
55032
55323
|
}),
|
|
55033
55324
|
async execute(args) {
|
|
@@ -55292,6 +55583,7 @@ var generateVideoTool = defineTool({
|
|
|
55292
55583
|
"Video provider (default: seedance when FAL_API_KEY is configured, otherwise first configured provider)"
|
|
55293
55584
|
),
|
|
55294
55585
|
image: external_exports.string().optional().describe("Reference image path for image-to-video"),
|
|
55586
|
+
endImage: external_exports.string().optional().describe("Ending frame image path for Seedance image-to-video"),
|
|
55295
55587
|
refImages: external_exports.array(external_exports.string()).optional().describe("Reference images for Seedance reference-to-video"),
|
|
55296
55588
|
refVideos: external_exports.array(external_exports.string()).optional().describe("Reference videos for Seedance reference-to-video"),
|
|
55297
55589
|
refAudio: external_exports.array(external_exports.string()).optional().describe("Reference audio files for Seedance reference-to-video"),
|
|
@@ -55299,7 +55591,7 @@ var generateVideoTool = defineTool({
|
|
|
55299
55591
|
ratio: external_exports.string().optional().describe("Aspect ratio: 16:9, 9:16, 1:1 (default: 16:9)"),
|
|
55300
55592
|
mode: external_exports.string().optional().describe("Kling mode: std or pro"),
|
|
55301
55593
|
negative: external_exports.string().optional().describe("Negative prompt (Seedance/Kling/Veo)"),
|
|
55302
|
-
resolution: external_exports.string().optional().describe("Resolution: 720p, 1080p, 4k
|
|
55594
|
+
resolution: external_exports.string().optional().describe("Resolution: 480p, 720p, 1080p, or 4k depending on provider"),
|
|
55303
55595
|
veoModel: external_exports.string().optional().describe("Veo model: 3.0, 3.1, 3.1-fast"),
|
|
55304
55596
|
runwayModel: external_exports.string().optional().describe("Runway model: gen4.5, gen4_turbo"),
|
|
55305
55597
|
seedanceModel: external_exports.string().optional().describe("Seedance variant: quality or fast (fal.ai only)"),
|
|
@@ -55345,10 +55637,10 @@ var generateVideoStatusTool = defineTool({
|
|
|
55345
55637
|
name: "generate_video_status",
|
|
55346
55638
|
category: "generate",
|
|
55347
55639
|
cost: "free",
|
|
55348
|
-
description: "Check video generation status for Runway or
|
|
55640
|
+
description: "Check video generation status for Grok, Runway, Kling, or Veo tasks.",
|
|
55349
55641
|
schema: external_exports.object({
|
|
55350
55642
|
taskId: external_exports.string().describe("Task ID from video generation"),
|
|
55351
|
-
provider: external_exports.enum(["runway", "kling"]).optional().describe("Provider (default: runway)"),
|
|
55643
|
+
provider: external_exports.enum(["grok", "runway", "kling", "veo"]).optional().describe("Provider (default: runway)"),
|
|
55352
55644
|
taskType: external_exports.enum(["text2video", "image2video"]).optional().describe("Kling task type (default: text2video)"),
|
|
55353
55645
|
wait: external_exports.boolean().optional().describe("Wait for completion"),
|
|
55354
55646
|
output: external_exports.string().optional().describe("Download video when complete")
|