@lightcone-ai/daemon 0.15.70 → 0.15.71
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/package.json
CHANGED
|
@@ -292,7 +292,14 @@ export async function composeVideoV2({
|
|
|
292
292
|
finalClip = await silentClip({ videoPath: visualClip.path, duration: visualClip.duration, tmpDir });
|
|
293
293
|
}
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
// Accept `text` as an alias for `subtitle_text`: plan_video_segments takes
|
|
296
|
+
// segment narration as `text` on input, compose_video_v2's canonical name is
|
|
297
|
+
// `subtitle_text`. Either reaches the burn pass so subtitles aren't silently dropped.
|
|
298
|
+
const subtitleText = (
|
|
299
|
+
typeof seg.subtitle_text === 'string' ? seg.subtitle_text
|
|
300
|
+
: typeof seg.text === 'string' ? seg.text
|
|
301
|
+
: ''
|
|
302
|
+
).trim();
|
|
296
303
|
readyClips.push({ path: finalClip, duration: visualClip.duration, transition, subtitleText });
|
|
297
304
|
}
|
|
298
305
|
|
|
@@ -59,13 +59,30 @@ export async function runComposeVideoV2Tool({ segments, outro_paths, format, res
|
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
const warnings = [];
|
|
62
63
|
// Heuristic warning: a multi-segment image video that reuses one single image
|
|
63
64
|
// will look near-static — usually a sign the source page didn't render and the
|
|
64
65
|
// agent fell back to one blank screenshot.
|
|
65
|
-
let warning = null;
|
|
66
66
|
if (imagePaths.length >= 2 && new Set(imagePaths).size === 1) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
warnings.push(
|
|
68
|
+
`WARNING: all ${imagePaths.length} image segments reuse the same file (${imagePaths[0]}). `
|
|
69
|
+
+ 'The output will be near-static — verify the source page actually rendered before submitting this video.'
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
// Warn when narration is present but no subtitle text is — compose_video_v2 burns
|
|
73
|
+
// subtitles only from `subtitle_text` (or its `text` alias); without it the video
|
|
74
|
+
// ships with no captions. Simplest fix: pass plan_video_segments' output verbatim.
|
|
75
|
+
{
|
|
76
|
+
const hasSubText = s => (typeof s?.subtitle_text === 'string' && s.subtitle_text.trim())
|
|
77
|
+
|| (typeof s?.text === 'string' && s.text.trim());
|
|
78
|
+
const narratedNoSub = segments.filter(s =>
|
|
79
|
+
(typeof s?.audio_path === 'string' && s.audio_path.trim()) && !hasSubText(s)).length;
|
|
80
|
+
if (narratedNoSub > 0) {
|
|
81
|
+
warnings.push(
|
|
82
|
+
`WARNING: ${narratedNoSub} segment(s) have narration audio but no subtitle text — the output will have NO subtitles. `
|
|
83
|
+
+ 'If subtitles are wanted, set subtitle_text per segment (or pass the plan_video_segments output array verbatim).'
|
|
84
|
+
);
|
|
85
|
+
}
|
|
69
86
|
}
|
|
70
87
|
|
|
71
88
|
const outDir = workspaceDir
|
|
@@ -89,7 +106,7 @@ export async function runComposeVideoV2Tool({ segments, outro_paths, format, res
|
|
|
89
106
|
`segments=${segments.length}`,
|
|
90
107
|
`outro_clips=${(outro_paths ?? []).length}`,
|
|
91
108
|
];
|
|
92
|
-
|
|
109
|
+
for (const w of warnings) lines.push(w);
|
|
93
110
|
return toolText(lines.join('\n'));
|
|
94
111
|
} catch (error) {
|
|
95
112
|
return toolError(`compose_video_v2 failed: ${error.message}`);
|