Continuous video orchestrator: coordinate chained episode clip generation - #6232
Merged
Conversation
…ckends (#6227) Composes the script-to-beats compiler (#6225) and prompt linter (#6226) into an end-to-end pipeline: continuousVideo.js compiles a script + bible into clips, lints every clip prompt before any generation starts, submits clips sequentially to a chosen backend (local/reactor/fal) threading continuation conditioning between clips (a last-frame still, or reactor's native continue_from_clip_id), and stitches the results into one episode. A failed continuation clip re-attempts fresh rather than aborting the whole episode. POST /api/continuous-video submits an episode and rejects a lint failure before any backend call; GET /:jobId/events streams progress over SSE. Also fixes videoPromptLinter.js's private escapeRegExp to import the shared server/lib/textUtils.js implementation, per the repo-wide no-private-escape guard (pre-existing failure surfaced while working in this file).
- Detach videoGenEvents listeners when a backend's generate() call throws synchronously, instead of only on its own 'completed'/'failed' emit — otherwise a listener pair leaks per synchronously-failing clip. - Reach progress:1.0 once every clip completes (was capped at (N-1)/N) and stop dropping the "continuing"/"establishing" suffix off the SSE progress message. - Fall back fal's clip duration to the compiled beat's durationSeconds, matching reactor's existing fallback. - Route passes its already-compiled+linted clips into the orchestrator instead of having it recompile the script a second time.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
server/services/videoGen/continuousVideo.js: composes the script-to-beats compiler (Script-to-Beats Compiler for continuous video episodes #6225) and the prompt linter (Deterministic video-prompt linter for continuous episode clips #6226) into an end-to-end pipeline — compile a script + bible into clips, lint every clip prompt before any generation starts, submit clips sequentially to a chosen video backend (local LTX / reactor / fal), thread continuation conditioning between clips (a last-frame still, or reactor's nativecontinue_from_clip_id), and stitch the results into one episode withstitchVideos.POST /api/continuous-video(submits an episode, rejecting a lint failure with 422 before any backend call) andGET /api/continuous-video/:jobId/events(SSE progress), registered inserver/index.jsand the generated API route catalog.videoPromptLinter.js's privateescapeRegExpto import the sharedserver/lib/textUtils.jsimplementation — a pre-existing failure in the repo-wide no-private-escape guard, surfaced while working in this file.Test plan
server/services/videoGen/continuousVideo.test.js— clip composition (hard-cut opener + bible references), lint short-circuit, full happy-path chain + stitch, fresh-re-establish on a failed continuation clip, abort on a failed fresh clip, reactor'scontinue_from_clip_idconditioning, unknown-backend rejection.server/routes/continuousVideoEpisode.test.js— validation, lint-failure 422 before submission, running job descriptor, server-resolvedpythonPath/settings(client override stripped), 404 on an unknown SSE job.serversuite green (npm testinserver/), including the import-scoping budget test (backend generator modules are lazy-imported per backend to keep the widely-reached module's static closure small).opencode; findings addressed (listener leak on a synchronous backend throw, progress never reaching 1.0, dropped SSE message suffix, fal duration fallback, duplicate script compile between the route and the orchestrator).Closes #6227