@skyphusion-labs/vivijure-core 0.9.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/LICENSE +661 -0
- package/README.md +87 -0
- package/dist/audio-routing.d.ts +2 -0
- package/dist/audio-routing.d.ts.map +1 -0
- package/dist/audio-routing.js +4 -0
- package/dist/audio-routing.js.map +1 -0
- package/dist/audio-stage.d.ts +4 -0
- package/dist/audio-stage.d.ts.map +1 -0
- package/dist/audio-stage.js +25 -0
- package/dist/audio-stage.js.map +1 -0
- package/dist/beat-analyze.d.ts +22 -0
- package/dist/beat-analyze.d.ts.map +1 -0
- package/dist/beat-analyze.js +111 -0
- package/dist/beat-analyze.js.map +1 -0
- package/dist/beat-sync-types.d.ts +33 -0
- package/dist/beat-sync-types.d.ts.map +1 -0
- package/dist/beat-sync-types.js +4 -0
- package/dist/beat-sync-types.js.map +1 -0
- package/dist/bundle-assembler.d.ts +54 -0
- package/dist/bundle-assembler.d.ts.map +1 -0
- package/dist/bundle-assembler.js +376 -0
- package/dist/bundle-assembler.js.map +1 -0
- package/dist/bundle-durations.d.ts +5 -0
- package/dist/bundle-durations.d.ts.map +1 -0
- package/dist/bundle-durations.js +68 -0
- package/dist/bundle-durations.js.map +1 -0
- package/dist/bundle-storyboard.d.ts +11 -0
- package/dist/bundle-storyboard.d.ts.map +1 -0
- package/dist/bundle-storyboard.js +82 -0
- package/dist/bundle-storyboard.js.map +1 -0
- package/dist/captions.d.ts +25 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +56 -0
- package/dist/captions.js.map +1 -0
- package/dist/cast-db.d.ts +61 -0
- package/dist/cast-db.d.ts.map +1 -0
- package/dist/cast-db.js +324 -0
- package/dist/cast-db.js.map +1 -0
- package/dist/cast-lora-train.d.ts +18 -0
- package/dist/cast-lora-train.d.ts.map +1 -0
- package/dist/cast-lora-train.js +215 -0
- package/dist/cast-lora-train.js.map +1 -0
- package/dist/cast-loras.d.ts +21 -0
- package/dist/cast-loras.d.ts.map +1 -0
- package/dist/cast-loras.js +69 -0
- package/dist/cast-loras.js.map +1 -0
- package/dist/clip-content-validate.d.ts +43 -0
- package/dist/clip-content-validate.d.ts.map +1 -0
- package/dist/clip-content-validate.js +115 -0
- package/dist/clip-content-validate.js.map +1 -0
- package/dist/clip-job-model.d.ts +42 -0
- package/dist/clip-job-model.d.ts.map +1 -0
- package/dist/clip-job-model.js +8 -0
- package/dist/clip-job-model.js.map +1 -0
- package/dist/clip-validate.d.ts +33 -0
- package/dist/clip-validate.d.ts.map +1 -0
- package/dist/clip-validate.js +247 -0
- package/dist/clip-validate.js.map +1 -0
- package/dist/d1-retry.d.ts +20 -0
- package/dist/d1-retry.d.ts.map +1 -0
- package/dist/d1-retry.js +67 -0
- package/dist/d1-retry.js.map +1 -0
- package/dist/db-env.d.ts +6 -0
- package/dist/db-env.d.ts.map +1 -0
- package/dist/db-env.js +2 -0
- package/dist/db-env.js.map +1 -0
- package/dist/dialogue-lines.d.ts +23 -0
- package/dist/dialogue-lines.d.ts.map +1 -0
- package/dist/dialogue-lines.js +84 -0
- package/dist/dialogue-lines.js.map +1 -0
- package/dist/film-advance-lease.d.ts +9 -0
- package/dist/film-advance-lease.d.ts.map +1 -0
- package/dist/film-advance-lease.js +19 -0
- package/dist/film-advance-lease.js.map +1 -0
- package/dist/film-model.d.ts +415 -0
- package/dist/film-model.d.ts.map +1 -0
- package/dist/film-model.js +541 -0
- package/dist/film-model.js.map +1 -0
- package/dist/film-orchestrator.d.ts +216 -0
- package/dist/film-orchestrator.d.ts.map +1 -0
- package/dist/film-orchestrator.js +2204 -0
- package/dist/film-orchestrator.js.map +1 -0
- package/dist/film-render-bridge.d.ts +26 -0
- package/dist/film-render-bridge.d.ts.map +1 -0
- package/dist/film-render-bridge.js +176 -0
- package/dist/film-render-bridge.js.map +1 -0
- package/dist/finish-hash.d.ts +10 -0
- package/dist/finish-hash.d.ts.map +1 -0
- package/dist/finish-hash.js +60 -0
- package/dist/finish-hash.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/key-safety.d.ts +5 -0
- package/dist/key-safety.d.ts.map +1 -0
- package/dist/key-safety.js +23 -0
- package/dist/key-safety.js.map +1 -0
- package/dist/lora-bundle.d.ts +19 -0
- package/dist/lora-bundle.d.ts.map +1 -0
- package/dist/lora-bundle.js +75 -0
- package/dist/lora-bundle.js.map +1 -0
- package/dist/lora-keys.d.ts +2 -0
- package/dist/lora-keys.d.ts.map +1 -0
- package/dist/lora-keys.js +4 -0
- package/dist/lora-keys.js.map +1 -0
- package/dist/modules/conformance.d.ts +58 -0
- package/dist/modules/conformance.d.ts.map +1 -0
- package/dist/modules/conformance.js +369 -0
- package/dist/modules/conformance.js.map +1 -0
- package/dist/modules/manifest-validate.d.ts +5 -0
- package/dist/modules/manifest-validate.d.ts.map +1 -0
- package/dist/modules/manifest-validate.js +60 -0
- package/dist/modules/manifest-validate.js.map +1 -0
- package/dist/modules/registry.d.ts +184 -0
- package/dist/modules/registry.d.ts.map +1 -0
- package/dist/modules/registry.js +653 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/modules/render-pipeline.d.ts +38 -0
- package/dist/modules/render-pipeline.d.ts.map +1 -0
- package/dist/modules/render-pipeline.js +40 -0
- package/dist/modules/render-pipeline.js.map +1 -0
- package/dist/modules/types.d.ts +544 -0
- package/dist/modules/types.d.ts.map +1 -0
- package/dist/modules/types.js +57 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/operator-config.d.ts +20 -0
- package/dist/operator-config.d.ts.map +1 -0
- package/dist/operator-config.js +85 -0
- package/dist/operator-config.js.map +1 -0
- package/dist/output-extract.d.ts +8 -0
- package/dist/output-extract.d.ts.map +1 -0
- package/dist/output-extract.js +129 -0
- package/dist/output-extract.js.map +1 -0
- package/dist/planner-prompt.d.ts +12 -0
- package/dist/planner-prompt.d.ts.map +1 -0
- package/dist/planner-prompt.js +337 -0
- package/dist/planner-prompt.js.map +1 -0
- package/dist/planner-yaml.d.ts +15 -0
- package/dist/planner-yaml.d.ts.map +1 -0
- package/dist/planner-yaml.js +157 -0
- package/dist/planner-yaml.js.map +1 -0
- package/dist/platform/fetcher.d.ts +3 -0
- package/dist/platform/fetcher.d.ts.map +1 -0
- package/dist/platform/fetcher.js +7 -0
- package/dist/platform/fetcher.js.map +1 -0
- package/dist/platform/index.d.ts +6 -0
- package/dist/platform/index.d.ts.map +1 -0
- package/dist/platform/index.js +5 -0
- package/dist/platform/index.js.map +1 -0
- package/dist/platform/object-store-r2.d.ts +26 -0
- package/dist/platform/object-store-r2.d.ts.map +1 -0
- package/dist/platform/object-store-r2.js +74 -0
- package/dist/platform/object-store-r2.js.map +1 -0
- package/dist/platform/orchestrator-context.d.ts +20 -0
- package/dist/platform/orchestrator-context.d.ts.map +1 -0
- package/dist/platform/orchestrator-context.js +28 -0
- package/dist/platform/orchestrator-context.js.map +1 -0
- package/dist/platform/r2-types.d.ts +41 -0
- package/dist/platform/r2-types.d.ts.map +1 -0
- package/dist/platform/r2-types.js +3 -0
- package/dist/platform/r2-types.js.map +1 -0
- package/dist/platform/types.d.ts +90 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +23 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/preflight.d.ts +57 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +243 -0
- package/dist/preflight.js.map +1 -0
- package/dist/presign.d.ts +5 -0
- package/dist/presign.d.ts.map +1 -0
- package/dist/presign.js +24 -0
- package/dist/presign.js.map +1 -0
- package/dist/public-id.d.ts +8 -0
- package/dist/public-id.d.ts.map +1 -0
- package/dist/public-id.js +25 -0
- package/dist/public-id.js.map +1 -0
- package/dist/render-adopt.d.ts +3 -0
- package/dist/render-adopt.d.ts.map +1 -0
- package/dist/render-adopt.js +92 -0
- package/dist/render-adopt.js.map +1 -0
- package/dist/render-log.d.ts +25 -0
- package/dist/render-log.d.ts.map +1 -0
- package/dist/render-log.js +139 -0
- package/dist/render-log.js.map +1 -0
- package/dist/render-module-config.d.ts +28 -0
- package/dist/render-module-config.d.ts.map +1 -0
- package/dist/render-module-config.js +124 -0
- package/dist/render-module-config.js.map +1 -0
- package/dist/render-mux.d.ts +18 -0
- package/dist/render-mux.d.ts.map +1 -0
- package/dist/render-mux.js +69 -0
- package/dist/render-mux.js.map +1 -0
- package/dist/render-orchestrator.d.ts +71 -0
- package/dist/render-orchestrator.d.ts.map +1 -0
- package/dist/render-orchestrator.js +376 -0
- package/dist/render-orchestrator.js.map +1 -0
- package/dist/render-sweep.d.ts +5 -0
- package/dist/render-sweep.d.ts.map +1 -0
- package/dist/render-sweep.js +62 -0
- package/dist/render-sweep.js.map +1 -0
- package/dist/renders-db.d.ts +129 -0
- package/dist/renders-db.d.ts.map +1 -0
- package/dist/renders-db.js +752 -0
- package/dist/renders-db.js.map +1 -0
- package/dist/runpod-submit.d.ts +151 -0
- package/dist/runpod-submit.d.ts.map +1 -0
- package/dist/runpod-submit.js +469 -0
- package/dist/runpod-submit.js.map +1 -0
- package/dist/runpod-types.d.ts +2 -0
- package/dist/runpod-types.d.ts.map +1 -0
- package/dist/runpod-types.js +4 -0
- package/dist/runpod-types.js.map +1 -0
- package/dist/scatter-notify.d.ts +4 -0
- package/dist/scatter-notify.d.ts.map +1 -0
- package/dist/scatter-notify.js +43 -0
- package/dist/scatter-notify.js.map +1 -0
- package/dist/scatter-orchestrator-types.d.ts +56 -0
- package/dist/scatter-orchestrator-types.d.ts.map +1 -0
- package/dist/scatter-orchestrator-types.js +3 -0
- package/dist/scatter-orchestrator-types.js.map +1 -0
- package/dist/scatter-orchestrator.d.ts +70 -0
- package/dist/scatter-orchestrator.d.ts.map +1 -0
- package/dist/scatter-orchestrator.js +614 -0
- package/dist/scatter-orchestrator.js.map +1 -0
- package/dist/scatter.d.ts +35 -0
- package/dist/scatter.d.ts.map +1 -0
- package/dist/scatter.js +171 -0
- package/dist/scatter.js.map +1 -0
- package/dist/secret-store.d.ts +5 -0
- package/dist/secret-store.d.ts.map +1 -0
- package/dist/secret-store.js +19 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/shot-durations-parse.d.ts +3 -0
- package/dist/shot-durations-parse.d.ts.map +1 -0
- package/dist/shot-durations-parse.js +43 -0
- package/dist/shot-durations-parse.js.map +1 -0
- package/dist/srt.d.ts +11 -0
- package/dist/srt.d.ts.map +1 -0
- package/dist/srt.js +54 -0
- package/dist/srt.js.map +1 -0
- package/dist/storyboard-ids.d.ts +2 -0
- package/dist/storyboard-ids.d.ts.map +1 -0
- package/dist/storyboard-ids.js +12 -0
- package/dist/storyboard-ids.js.map +1 -0
- package/dist/storyboard-projects-db.d.ts +31 -0
- package/dist/storyboard-projects-db.d.ts.map +1 -0
- package/dist/storyboard-projects-db.js +153 -0
- package/dist/storyboard-projects-db.js.map +1 -0
- package/dist/storyboard-validate.d.ts +72 -0
- package/dist/storyboard-validate.d.ts.map +1 -0
- package/dist/storyboard-validate.js +595 -0
- package/dist/storyboard-validate.js.map +1 -0
- package/dist/structured-events.d.ts +6 -0
- package/dist/structured-events.d.ts.map +1 -0
- package/dist/structured-events.js +15 -0
- package/dist/structured-events.js.map +1 -0
- package/dist/tar.d.ts +9 -0
- package/dist/tar.d.ts.map +1 -0
- package/dist/tar.js +151 -0
- package/dist/tar.js.map +1 -0
- package/dist/voices.d.ts +12 -0
- package/dist/voices.d.ts.map +1 -0
- package/dist/voices.js +37 -0
- package/dist/voices.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
// Render-execution orchestrator: drive the motion.backend module per shot, ASYNC (invoke -> poll)
|
|
2
|
+
// and ACROSS REQUESTS, so a Worker never holds a multi-minute generation. POST starts the job
|
|
3
|
+
// (resolves the chosen motion.backend module, submits each shot, persists the poll tokens to an R2
|
|
4
|
+
// job doc). GET advances it (polls the shots still pending; the module's /poll finalizes a clip to
|
|
5
|
+
// R2 on completion). The caller polls GET until `complete`. Keyframes arrive as URLs -- the GPU
|
|
6
|
+
// keyframe stage feeds them later; for now the clip stage stands alone.
|
|
7
|
+
//
|
|
8
|
+
// State is an R2 json per job. GET only polls shots still pending (done ones are not re-polled, so
|
|
9
|
+
// no re-download). For concurrency-safe progress a Durable Object is the upgrade; this MVP assumes
|
|
10
|
+
// the caller polls sequentially.
|
|
11
|
+
import { discoverModules, invokeModule, pollModule, cancelModule, resolveFetcher, servingForHook, validateConfig, } from "./modules/registry.js";
|
|
12
|
+
import { hookOutputViolation } from "./modules/conformance.js";
|
|
13
|
+
import { emitStructuredEvent } from "./structured-events.js";
|
|
14
|
+
import { summarizeJob, } from "./clip-job-model.js";
|
|
15
|
+
import { validateClipArtifact } from "./clip-validate.js";
|
|
16
|
+
export { summarizeJob };
|
|
17
|
+
const jobKey = (jobId) => `renders/${jobId}/clips-job.json`;
|
|
18
|
+
/** Pure: aggregate the per-shot failure reasons into one honest string (#754). */
|
|
19
|
+
export function describeClipFailures(job) {
|
|
20
|
+
const failed = job.shots.filter((s) => s.status === "failed");
|
|
21
|
+
if (!failed.length)
|
|
22
|
+
return "";
|
|
23
|
+
return failed.map((s) => `${s.shot_id}: ${s.error || "unknown error"}`).join("; ");
|
|
24
|
+
}
|
|
25
|
+
/** Pure: is a poll/invoke error TRANSIENT or DETERMINISTIC? Shared classifier (#719). */
|
|
26
|
+
export function classifyTransientFailure(error) {
|
|
27
|
+
const e = error ?? "";
|
|
28
|
+
const m = e.match(/->\s*(\d{3})\b/);
|
|
29
|
+
if (m) {
|
|
30
|
+
const s = Number(m[1]);
|
|
31
|
+
return s === 408 || s === 429 || (s >= 500 && s <= 599) ? "transient" : "deterministic";
|
|
32
|
+
}
|
|
33
|
+
if (/unreachable|timed? ?out|timeout|network|econnreset|connection (reset|lost)|fetch failed/i.test(e)) {
|
|
34
|
+
return "transient";
|
|
35
|
+
}
|
|
36
|
+
return "deterministic";
|
|
37
|
+
}
|
|
38
|
+
/** Consecutive transient poll errors a clip shot tolerates before failing loud (#719). */
|
|
39
|
+
export const CLIP_POLL_MAX_ATTEMPTS = 3;
|
|
40
|
+
/** Apply a /poll outcome to a shot (pure): failure -> failed; still pending -> unchanged; output ->
|
|
41
|
+
* done with the clip key. */
|
|
42
|
+
export function applyPoll(shot, r) {
|
|
43
|
+
if (!r.ok) {
|
|
44
|
+
// #719: one TRANSIENT poll failure must not STICKILY fail a healthy in-flight render. Mirror the
|
|
45
|
+
// finish chain's bounded-attempts contract: tolerate up to CLIP_POLL_MAX_ATTEMPTS CONSECUTIVE
|
|
46
|
+
// transient errors (the shot stays pending; the next sweep re-polls; any successful poll resets
|
|
47
|
+
// the count), then fail loud with the real error. A DETERMINISTIC module-reported failure still
|
|
48
|
+
// fails immediately.
|
|
49
|
+
if (classifyTransientFailure(r.error) === "transient") {
|
|
50
|
+
const attempts = (shot.poll_attempts ?? 0) + 1;
|
|
51
|
+
if (attempts < CLIP_POLL_MAX_ATTEMPTS) {
|
|
52
|
+
shot.poll_attempts = attempts;
|
|
53
|
+
return; // stays pending; re-polled next sweep
|
|
54
|
+
}
|
|
55
|
+
shot.status = "failed";
|
|
56
|
+
shot.error = `${r.error} (persisted through ${attempts} consecutive polls, #719)`;
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
shot.status = "failed";
|
|
60
|
+
shot.error = r.error;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (r.pending) {
|
|
64
|
+
if (shot.poll_attempts)
|
|
65
|
+
shot.poll_attempts = 0; // a successful round-trip resets the blip budget
|
|
66
|
+
return; // still running
|
|
67
|
+
}
|
|
68
|
+
const output = r.output;
|
|
69
|
+
const violation = hookOutputViolation(shot.motion_backend ?? "motion.backend", "motion.backend", output);
|
|
70
|
+
if (violation) {
|
|
71
|
+
shot.status = "failed";
|
|
72
|
+
shot.error = violation;
|
|
73
|
+
return;
|
|
74
|
+
} // envelope-ok but off-contract: fail loud, never advance garbage
|
|
75
|
+
shot.status = "done";
|
|
76
|
+
shot.clip_key = output.clip_key;
|
|
77
|
+
// #707: retain what the backend delivered so the film summary can show delivered-vs-planned. The
|
|
78
|
+
// contract has always carried fps+frames; modules with nothing to report send frames=0 (sentinel) --
|
|
79
|
+
// treat that as absent rather than recording a fabricated 0-frame delivery.
|
|
80
|
+
if (typeof output.fps === "number" && output.fps > 0 && typeof output.frames === "number" && output.frames > 0) {
|
|
81
|
+
shot.delivered_fps = output.fps;
|
|
82
|
+
shot.delivered_frames = output.frames;
|
|
83
|
+
}
|
|
84
|
+
// #705: tier honesty rides the same channel, independent of the duration numbers.
|
|
85
|
+
if (typeof output.distilled === "boolean")
|
|
86
|
+
shot.distilled = output.distilled;
|
|
87
|
+
}
|
|
88
|
+
/** Pure: does an R2 clips-object filename belong to this shot? The backend writes a finished motion clip
|
|
89
|
+
* per shot under `renders/<project>/clips/`, named with the shot id followed by a NON-digit separator
|
|
90
|
+
* (e.g. `shot_09_i2v.mp4`, `shot_09_seedance.mp4`). Match the shot id only at a digit boundary so
|
|
91
|
+
* `shot_1` never swallows `shot_10`; exclude `_finished*` (finish-chain outputs, not motion clips);
|
|
92
|
+
* require a video extension. Matches by shot-id boundary, NOT the backend's exact slug, so it stays
|
|
93
|
+
* independent of the backend naming convention (the core never hardcodes where the backend wrote). */
|
|
94
|
+
export function clipFileMatchesShot(file, shotId) {
|
|
95
|
+
if (!file.startsWith(shotId))
|
|
96
|
+
return false;
|
|
97
|
+
const rest = file.slice(shotId.length);
|
|
98
|
+
if (rest.length === 0)
|
|
99
|
+
return false; // need a separator + extension
|
|
100
|
+
if (/^\d/.test(rest))
|
|
101
|
+
return false; // digit boundary: shot_1 must not match shot_10...
|
|
102
|
+
if (/(^|[._-])finished([._-]|$)/i.test(rest))
|
|
103
|
+
return false; // finish-chain output, not a motion clip
|
|
104
|
+
return /\.(mp4|mov|webm|mkv)$/i.test(file); // a video file
|
|
105
|
+
}
|
|
106
|
+
/** Pure: does an R2 clips-object filename belong to this shot's FINISH-chain output? The finish modules
|
|
107
|
+
* write `renders/<project>/clips/<shot_id>_finished.mp4`. Same shot-id digit boundary as the motion-clip
|
|
108
|
+
* matcher, but here the `_finished` marker is REQUIRED (it is the finish output, not the raw motion clip)
|
|
109
|
+
* and a video extension is required. Matches by boundary + the `finished` marker, not a hardcoded full
|
|
110
|
+
* slug, so it stays independent of the backend convention. */
|
|
111
|
+
export function finishedClipFileMatchesShot(file, shotId) {
|
|
112
|
+
if (!file.startsWith(shotId))
|
|
113
|
+
return false;
|
|
114
|
+
const rest = file.slice(shotId.length);
|
|
115
|
+
if (/^\d/.test(rest))
|
|
116
|
+
return false; // digit boundary: shot_1 must not match shot_10...
|
|
117
|
+
if (!/(^|[._-])finished([._-]|$)/i.test(rest))
|
|
118
|
+
return false; // MUST be a finish-chain output
|
|
119
|
+
return /\.(mp4|mov|webm|mkv)$/i.test(file);
|
|
120
|
+
}
|
|
121
|
+
/** Map shot_id -> R2 key for the objects under `renders/<project>/clips/` that match `matches` (by shot-id
|
|
122
|
+
* boundary). Makes R2 PRESENCE the authority on completion: an artifact in R2 beats a module's poll
|
|
123
|
+
* verdict (the backend wrote it even if its RunPod job was later GC'd and the module fast-failed the
|
|
124
|
+
* poll; issue #141). `matches` selects the raw motion clip (default) or the finish output. Only the
|
|
125
|
+
* requested shot ids are returned. */
|
|
126
|
+
export async function listClipsByShotId(env, project, shotIds, matches = clipFileMatchesShot, minUploadedMs = 0) {
|
|
127
|
+
const prefix = `renders/${project}/clips/`;
|
|
128
|
+
const found = new Map(); // shot_id -> key (first match wins)
|
|
129
|
+
let cursor;
|
|
130
|
+
do {
|
|
131
|
+
const listed = await env.R2_RENDERS.list({ prefix, cursor, limit: 1000 });
|
|
132
|
+
for (const o of listed.objects) {
|
|
133
|
+
// Freshness guard (#661): when a floor is set, skip any clip written BEFORE this run started. A prior
|
|
134
|
+
// render of the same project name leaves clips at the identical renders/<project>/clips/<shot>_<backend>
|
|
135
|
+
// path; without this the stall/fail reclaim adopts a 4-day-old clip and ships wrong content silently
|
|
136
|
+
// (the #245/#249 class). This run own clips always upload AFTER the job created_at, so the legit #141
|
|
137
|
+
// reclaim survives. R2Object.uploaded is a Date; job stamps are epoch ms -- normalize explicitly.
|
|
138
|
+
if (minUploadedMs && o.uploaded.getTime() < minUploadedMs)
|
|
139
|
+
continue;
|
|
140
|
+
const file = o.key.slice(prefix.length);
|
|
141
|
+
for (const shotId of shotIds) {
|
|
142
|
+
if (!found.has(shotId) && matches(file, shotId))
|
|
143
|
+
found.set(shotId, o.key);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
cursor = listed.truncated ? listed.cursor : undefined;
|
|
147
|
+
} while (cursor);
|
|
148
|
+
return found;
|
|
149
|
+
}
|
|
150
|
+
/** Start a clip job: resolve the motion.backend module per shot, submit, persist poll tokens. */
|
|
151
|
+
export async function startClipJob(env, args, preModules) {
|
|
152
|
+
const envRec = env;
|
|
153
|
+
const modules = preModules ?? await discoverModules(envRec);
|
|
154
|
+
const serving = servingForHook(modules, "motion.backend");
|
|
155
|
+
const defaultMb = args.motion_backend
|
|
156
|
+
? serving.find((m) => m.name === args.motion_backend) ?? null
|
|
157
|
+
: serving[0] ?? null;
|
|
158
|
+
const moduleConfigs = args.module_configs ?? {};
|
|
159
|
+
const defaultConfig = defaultMb
|
|
160
|
+
? validateConfig(defaultMb.config_schema, args.config ?? moduleConfigs[defaultMb.name])
|
|
161
|
+
: {};
|
|
162
|
+
const job_id = "clips-" + crypto.randomUUID();
|
|
163
|
+
const shots = [];
|
|
164
|
+
for (const sh of args.shots) {
|
|
165
|
+
const shot = { ...sh, status: "pending" };
|
|
166
|
+
const mbName = sh.motion_backend ?? args.motion_backend ?? defaultMb?.name;
|
|
167
|
+
const mb = mbName ? serving.find((m) => m.name === mbName) ?? null : defaultMb;
|
|
168
|
+
const binding = mb ? mb.binding : null;
|
|
169
|
+
shot.binding = binding;
|
|
170
|
+
shot.motion_backend = mb?.name ?? undefined;
|
|
171
|
+
const fetcher = binding ? resolveFetcher(envRec, binding) : null;
|
|
172
|
+
const config = mb
|
|
173
|
+
? validateConfig(mb.config_schema, moduleConfigs[mb.name] ?? (mb.name === defaultMb?.name ? args.config : undefined) ?? args.config)
|
|
174
|
+
: defaultConfig;
|
|
175
|
+
if (!mb || !fetcher) {
|
|
176
|
+
shot.status = "failed";
|
|
177
|
+
shot.error = mb ? `module ${mb.name} (${binding}) is not bound` : "no motion.backend module installed";
|
|
178
|
+
shots.push(shot);
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const r = await invokeModule(fetcher, {
|
|
182
|
+
hook: "motion.backend",
|
|
183
|
+
input: { shot_id: sh.shot_id, keyframe_url: sh.keyframe_url, keyframe_key: sh.keyframe_key, prompt: sh.prompt, seconds: sh.seconds },
|
|
184
|
+
config,
|
|
185
|
+
context: { project: args.project, job_id },
|
|
186
|
+
});
|
|
187
|
+
if (!r.ok) {
|
|
188
|
+
shot.status = "failed";
|
|
189
|
+
shot.error = r.error;
|
|
190
|
+
}
|
|
191
|
+
else if (r.pending) {
|
|
192
|
+
shot.poll = r.poll;
|
|
193
|
+
shot.runpod_job_id = r.jobId; // #536: retain the backend job id for cancel/accounting
|
|
194
|
+
}
|
|
195
|
+
else if ("output" in r) {
|
|
196
|
+
const output = r.output;
|
|
197
|
+
const violation = hookOutputViolation(mb.name, "motion.backend", output);
|
|
198
|
+
if (violation) {
|
|
199
|
+
shot.status = "failed";
|
|
200
|
+
shot.error = violation;
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
shot.status = "done";
|
|
204
|
+
shot.clip_key = output.clip_key;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
shot.status = "failed";
|
|
209
|
+
shot.error = "module returned neither output nor a poll token";
|
|
210
|
+
}
|
|
211
|
+
shots.push(shot);
|
|
212
|
+
}
|
|
213
|
+
const job = {
|
|
214
|
+
job_id,
|
|
215
|
+
project: args.project,
|
|
216
|
+
motion_backend: defaultMb ? defaultMb.name : null,
|
|
217
|
+
binding: defaultMb ? defaultMb.binding : null,
|
|
218
|
+
module_configs: Object.keys(moduleConfigs).length ? moduleConfigs : undefined,
|
|
219
|
+
shots,
|
|
220
|
+
created_at: Date.now(),
|
|
221
|
+
};
|
|
222
|
+
await env.R2_RENDERS.put(jobKey(job_id), JSON.stringify(job), { httpMetadata: { contentType: "application/json" } });
|
|
223
|
+
return job;
|
|
224
|
+
}
|
|
225
|
+
/** Advance a clip job: poll the shots still pending; the module finalizes a clip to R2 on done. */
|
|
226
|
+
export async function advanceClipJob(env, jobId, preModules) {
|
|
227
|
+
const obj = await env.R2_RENDERS.get(jobKey(jobId));
|
|
228
|
+
if (!obj)
|
|
229
|
+
return null;
|
|
230
|
+
const job = JSON.parse(await obj.text());
|
|
231
|
+
const envRec = env;
|
|
232
|
+
for (const shot of job.shots) {
|
|
233
|
+
if (shot.status !== "pending" || !shot.poll)
|
|
234
|
+
continue;
|
|
235
|
+
const binding = shot.binding ?? job.binding;
|
|
236
|
+
const fetcher = binding ? resolveFetcher(envRec, binding) : null;
|
|
237
|
+
if (!fetcher) {
|
|
238
|
+
shot.status = "failed";
|
|
239
|
+
shot.error = "module binding no longer bound";
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
const p = await pollModule(fetcher, { poll: shot.poll });
|
|
243
|
+
applyPoll(shot, p);
|
|
244
|
+
}
|
|
245
|
+
// R2 PRESENCE IS AUTHORITATIVE (issue #141): reclaim any FAILED shot whose clip is in R2 -- whether it
|
|
246
|
+
// failed this pass or a prior one -- so a #142 fast-fail can never drop a shot whose clip actually
|
|
247
|
+
// landed. Runs BEFORE the caller's summarizeJob() complete/advance judgment. (The caller also calls
|
|
248
|
+
// reclaimClipsFromR2 again right before its complete-check; both are idempotent + cheap.)
|
|
249
|
+
await reclaimClipsFromR2(env, job);
|
|
250
|
+
// #536: a shot still FAILED that had started a remote job (it held a poll token) may have left the RunPod
|
|
251
|
+
// job running -- fire a best-effort cancel so the backend does not keep burning GPU after the studio gave
|
|
252
|
+
// up (the 307s-of-H200 zombie observed on the S18 gate). reclaimClipsFromR2 ran first, so a shot whose
|
|
253
|
+
// clip actually landed is already done and skipped. A module without /cancel logs an honest orphan.
|
|
254
|
+
await cancelFailedShots(env, job, preModules);
|
|
255
|
+
await validateDoneClips(env, job); // #523 Layer 1: structural gate before the caller advances to finish/upscale spend
|
|
256
|
+
await env.R2_RENDERS.put(jobKey(jobId), JSON.stringify(job), { httpMetadata: { contentType: "application/json" } });
|
|
257
|
+
return job;
|
|
258
|
+
}
|
|
259
|
+
/** #536: fire a best-effort remote cancel for every shot that is FAILED, held a poll token (so a remote
|
|
260
|
+
* job was started), and has not been cancelled yet. Discovers the registry only when there IS an orphan to
|
|
261
|
+
* cancel (the happy path pays nothing); the film tick threads its once-discovered registry in. */
|
|
262
|
+
async function cancelFailedShots(env, job, preModules) {
|
|
263
|
+
const orphans = job.shots.filter((s) => s.status === "failed" && s.poll && !s.cancel_sent);
|
|
264
|
+
if (!orphans.length)
|
|
265
|
+
return;
|
|
266
|
+
const envRec = env;
|
|
267
|
+
const modules = preModules ?? await discoverModules(envRec);
|
|
268
|
+
for (const shot of orphans)
|
|
269
|
+
await cancelShotRemote(envRec, job, shot, modules);
|
|
270
|
+
}
|
|
271
|
+
/** #536: cancel ONE shot in-flight RunPod job via its motion module (cancelModule, keyed by the poll
|
|
272
|
+
* token, exactly as cancelInFlightKeyframe does for the keyframe phase). Records cancel_sent so it fires
|
|
273
|
+
* at most once, and NAMES the RunPod job in every orphan log so a left-running job is actionable. Mirrors
|
|
274
|
+
* the honest-orphan discipline: an unbound module or a module with no cancel primitive logs loudly, it
|
|
275
|
+
* never hides the leak. */
|
|
276
|
+
async function cancelShotRemote(envRec, job, shot, modules) {
|
|
277
|
+
const jobId = shot.runpod_job_id ?? "(job id unknown)";
|
|
278
|
+
const binding = shot.binding ?? job.binding;
|
|
279
|
+
const mb = binding ? (modules.find((m) => m.binding === binding) ?? null) : null;
|
|
280
|
+
const fetcher = binding ? resolveFetcher(envRec, binding) : null;
|
|
281
|
+
shot.cancel_sent = true; // best-effort ONCE, whatever the outcome -- never re-fire every tick
|
|
282
|
+
if (!mb || !fetcher) {
|
|
283
|
+
console.warn(`clip job ${job.job_id}: cannot cancel failed shot ${shot.shot_id} -- module ${binding ?? "?"} not bound; RunPod job ${jobId} left running (ORPHAN) (#536)`);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
if (!mb.cancelable) {
|
|
287
|
+
console.warn(`clip job ${job.job_id}: motion module ${mb.name} has no cancel primitive (cancelable=false); RunPod job ${jobId} for shot ${shot.shot_id} left running (ORPHAN) (#536)`);
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const r = await cancelModule(fetcher, { poll: shot.poll });
|
|
291
|
+
if (r.ok)
|
|
292
|
+
console.warn(`clip job ${job.job_id}: cancelled in-flight RunPod job ${jobId} for failed shot ${shot.shot_id} via ${mb.name} (#536)`);
|
|
293
|
+
else
|
|
294
|
+
console.warn(`clip job ${job.job_id}: cancel FAILED (${r.error}) for shot ${shot.shot_id} -- RunPod job ${jobId} left running (ORPHAN) (#536)`);
|
|
295
|
+
}
|
|
296
|
+
/** #536: teardown cancel -- STOP every in-flight (pending, poll-token-bearing) shot RunPod job when a clip
|
|
297
|
+
* job is cancelled/torn down, so a user-cancelled render does not leave the GPU running (the motion-phase
|
|
298
|
+
* sibling of cancelInFlightKeyframe; cancelFilmJob calls this off the clips phase). Persists cancel_sent.
|
|
299
|
+
* No-op when nothing is in flight. */
|
|
300
|
+
export async function cancelInFlightClips(env, jobId, preModules) {
|
|
301
|
+
const obj = await env.R2_RENDERS.get(jobKey(jobId));
|
|
302
|
+
if (!obj)
|
|
303
|
+
return;
|
|
304
|
+
const job = JSON.parse(await obj.text());
|
|
305
|
+
const inflight = job.shots.filter((s) => s.status === "pending" && s.poll && !s.cancel_sent);
|
|
306
|
+
if (!inflight.length)
|
|
307
|
+
return;
|
|
308
|
+
const envRec = env;
|
|
309
|
+
const modules = preModules ?? await discoverModules(envRec);
|
|
310
|
+
for (const shot of inflight)
|
|
311
|
+
await cancelShotRemote(envRec, job, shot, modules);
|
|
312
|
+
await env.R2_RENDERS.put(jobKey(jobId), JSON.stringify(job), { httpMetadata: { contentType: "application/json" } });
|
|
313
|
+
}
|
|
314
|
+
/** R2 PRESENCE IS THE SOURCE OF TRUTH for clip completion. Mutates the clip job in place: any shot that
|
|
315
|
+
* is NOT done but whose motion clip is present in R2 (matched by shot-id boundary) is marked done with
|
|
316
|
+
* that key (pending OR failed -- the artifact overrides a module's premature fast-fail; issue #141). A
|
|
317
|
+
* shot with no R2 clip is left as-is (a genuine non-render). Only lists R2 when there is at least one
|
|
318
|
+
* not-done shot to reclaim (the all-done happy path pays nothing). Returns the number adopted. This is
|
|
319
|
+
* the single reclaim used both inside advanceClipJob AND by the film orchestrator before it judges the
|
|
320
|
+
* clip job complete, so a fast-fail at 150s can never advance the film with a clip dropped. */
|
|
321
|
+
export async function reclaimClipsFromR2(env, job) {
|
|
322
|
+
const notDone = job.shots.filter((s) => s.status !== "done" && s.validated !== "fail");
|
|
323
|
+
if (!notDone.length)
|
|
324
|
+
return 0;
|
|
325
|
+
const present = await listClipsByShotId(env, job.project, notDone.map((s) => s.shot_id), clipFileMatchesShot, job.created_at);
|
|
326
|
+
let adopted = 0;
|
|
327
|
+
for (const shot of notDone) {
|
|
328
|
+
if (present.has(shot.shot_id)) {
|
|
329
|
+
shot.status = "done";
|
|
330
|
+
shot.clip_key = present.get(shot.shot_id);
|
|
331
|
+
shot.poll = undefined;
|
|
332
|
+
shot.error = undefined; // clear a premature failure; the artifact is the source of truth
|
|
333
|
+
shot.validated = undefined; // #523: re-validate the freshly-adopted artifact
|
|
334
|
+
adopted += 1;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return adopted;
|
|
338
|
+
}
|
|
339
|
+
/** #523 Layer 1: validate each newly-done clip's STRUCTURE (mp4 box tree) before the finish / dialogue /
|
|
340
|
+
* upscale chain spends anything. Engine-agnostic: every motion.backend clip (cloud backend, both local
|
|
341
|
+
* doors, any future module) funnels through this one chokepoint. Idempotent per shot via `validated`, so
|
|
342
|
+
* it runs at most once and can be called from more than one seam. A structural FAILURE flips the shot to
|
|
343
|
+
* failed with the real reason (honest-failure #245/#249: never a silent advance, never applied=[]) and
|
|
344
|
+
* clears its poll token so the orphan-cancel pass ignores a clip that already landed. A "skip" (artifact
|
|
345
|
+
* unreadable / validation disabled) leaves the shot untouched -- an I/O blip must never false-reject a
|
|
346
|
+
* real render. Emits one `clip.validate` structured event per shot (docs/observability.md) so smoke tests
|
|
347
|
+
* assert on the event, not prose. Returns true iff it changed any shot; the CALLER owns the job-doc write.
|
|
348
|
+
*
|
|
349
|
+
* HONEST SCOPE: this catches the STRUCTURAL-corruption class (truncated / empty / zero-frame /
|
|
350
|
+
* zero-duration / non-mp4). It does NOT catch the local-16gb#35 pure-noise clip, which is a structurally
|
|
351
|
+
* valid mp4 -- that needs a pixel decode (Layer 2, a video-finish-container pre-gate, filed separately). */
|
|
352
|
+
export async function validateDoneClips(env, job) {
|
|
353
|
+
let changed = false;
|
|
354
|
+
for (const shot of job.shots) {
|
|
355
|
+
if (shot.status !== "done" || !shot.clip_key || shot.validated)
|
|
356
|
+
continue;
|
|
357
|
+
const res = await validateClipArtifact(env, shot.clip_key, shot.seconds);
|
|
358
|
+
shot.validated = res.verdict;
|
|
359
|
+
emitStructuredEvent({
|
|
360
|
+
ev: "clip.validate",
|
|
361
|
+
job_id: job.job_id,
|
|
362
|
+
shot_id: shot.shot_id,
|
|
363
|
+
verdict: res.verdict,
|
|
364
|
+
checks: res.checks,
|
|
365
|
+
...(res.reason ? { reason: res.reason } : {}),
|
|
366
|
+
});
|
|
367
|
+
if (res.verdict === "fail") {
|
|
368
|
+
shot.status = "failed";
|
|
369
|
+
shot.error = `clip failed output validation: ${res.reason}`;
|
|
370
|
+
shot.poll = undefined; // it already produced a (bad) artifact; do not fire an orphan cancel
|
|
371
|
+
changed = true;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return changed;
|
|
375
|
+
}
|
|
376
|
+
//# sourceMappingURL=render-orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-orchestrator.js","sourceRoot":"","sources":["../src/render-orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Env, ExecutionContext } from "./platform/orchestrator-context.js";
|
|
2
|
+
/** Max age for jobs the sweep still tries to resolve (24h, matches RunPod job TTL). */
|
|
3
|
+
export declare const SWEEP_MAX_AGE_SECONDS: number;
|
|
4
|
+
export declare function sweepUnresolvedJobs(env: Env, ctx?: ExecutionContext): Promise<number>;
|
|
5
|
+
//# sourceMappingURL=render-sweep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-sweep.d.ts","sourceRoot":"","sources":["../src/render-sweep.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAMhF,uFAAuF;AACvF,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAE/C,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B3F"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Background cron sweep: advance film / scatter jobs that have no client polling.
|
|
2
|
+
import { advanceFilmJob, filmJobDocKey } from "./film-orchestrator.js";
|
|
3
|
+
import { filmJobToPollView, isFilmJobId } from "./film-render-bridge.js";
|
|
4
|
+
import { advanceScatterJob, isScatterJobId } from "./scatter-orchestrator.js";
|
|
5
|
+
import { listStrandedPostClipsFilmJobs, listUnresolvedNotifiableJobs, updateRenderFromView } from "./renders-db.js";
|
|
6
|
+
/** Max age for jobs the sweep still tries to resolve (24h, matches RunPod job TTL). */
|
|
7
|
+
export const SWEEP_MAX_AGE_SECONDS = 24 * 3600;
|
|
8
|
+
export async function sweepUnresolvedJobs(env, ctx) {
|
|
9
|
+
// Pass 1: jobs young enough to still be live on RunPod (keyframe / clips can still
|
|
10
|
+
// be polled). This is the common path.
|
|
11
|
+
const jobIds = await listUnresolvedNotifiableJobs(env, SWEEP_MAX_AGE_SECONDS);
|
|
12
|
+
// Pass 2: post-clips film jobs that aged out of pass 1 but stalled before "done"
|
|
13
|
+
// with their clips already rendered to R2. The remaining work (the CPU-only concat)
|
|
14
|
+
// never expires, so we keep re-driving them -- gated on the film-job doc still
|
|
15
|
+
// existing in R2 so we never chase a swept/GC'd job. De-dup against pass 1.
|
|
16
|
+
const seen = new Set(jobIds);
|
|
17
|
+
const stranded = [];
|
|
18
|
+
for (const id of await listStrandedPostClipsFilmJobs(env, SWEEP_MAX_AGE_SECONDS)) {
|
|
19
|
+
if (!seen.has(id) && isFilmJobId(id) && (await filmJobDocExists(env, id))) {
|
|
20
|
+
seen.add(id);
|
|
21
|
+
stranded.push(id);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
let n = 0;
|
|
25
|
+
for (const jobId of [...jobIds, ...stranded]) {
|
|
26
|
+
try {
|
|
27
|
+
const handled = await resolveOneJob(env, jobId, ctx);
|
|
28
|
+
if (handled)
|
|
29
|
+
n += 1;
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
console.warn(`render sweep failed for ${jobId}: ${e.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return n;
|
|
36
|
+
}
|
|
37
|
+
/** Cheap presence check: a stranded film job is only worth re-driving if its job doc
|
|
38
|
+
* (which carries the finished clip keys) is still in R2. A swept doc means the clips
|
|
39
|
+
* are gone too -- nothing to assemble -- so we skip it. */
|
|
40
|
+
async function filmJobDocExists(env, jobId) {
|
|
41
|
+
try {
|
|
42
|
+
return (await env.R2_RENDERS.head(filmJobDocKey(jobId))) !== null;
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function resolveOneJob(env, jobId, ctx) {
|
|
49
|
+
if (isScatterJobId(jobId)) {
|
|
50
|
+
const view = await advanceScatterJob(env, jobId, ctx);
|
|
51
|
+
return view !== null;
|
|
52
|
+
}
|
|
53
|
+
if (isFilmJobId(jobId)) {
|
|
54
|
+
const r = await advanceFilmJob(env, jobId);
|
|
55
|
+
if (!r)
|
|
56
|
+
return false;
|
|
57
|
+
await updateRenderFromView(env, filmJobToPollView(r.job, r.clipJob), ctx);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=render-sweep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-sweep.js","sourceRoot":"","sources":["../src/render-sweep.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Env, ExecutionContext } from "./platform/orchestrator-context.js";
|
|
2
|
+
import type { RunpodJobView } from "./runpod-types.js";
|
|
3
|
+
export interface NewRenderRow {
|
|
4
|
+
jobId: string;
|
|
5
|
+
project: string;
|
|
6
|
+
bundleKey: string;
|
|
7
|
+
qualityTier: string;
|
|
8
|
+
renderOverrides?: Record<string, unknown>;
|
|
9
|
+
status: string;
|
|
10
|
+
mode?: "full" | "keyframes-only" | "finalized" | "cloud-finalized";
|
|
11
|
+
projectId?: number | null;
|
|
12
|
+
parentId?: number | null;
|
|
13
|
+
}
|
|
14
|
+
export interface KeyframeRef {
|
|
15
|
+
shot_id: string;
|
|
16
|
+
key: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RenderRow {
|
|
19
|
+
id: number;
|
|
20
|
+
public_id: string;
|
|
21
|
+
job_id: string;
|
|
22
|
+
project: string;
|
|
23
|
+
bundle_key: string;
|
|
24
|
+
quality_tier: string;
|
|
25
|
+
render_overrides: Record<string, unknown> | null;
|
|
26
|
+
status: string;
|
|
27
|
+
output_key: string | null;
|
|
28
|
+
output: unknown;
|
|
29
|
+
error: string | null;
|
|
30
|
+
execution_time_ms: number | null;
|
|
31
|
+
delay_time_ms: number | null;
|
|
32
|
+
submitted_at: number;
|
|
33
|
+
updated_at: number;
|
|
34
|
+
completed_at: number | null;
|
|
35
|
+
label: string | null;
|
|
36
|
+
keyframes: KeyframeRef[] | null;
|
|
37
|
+
mode: "full" | "keyframes-only" | "finalized" | "cloud-finalized";
|
|
38
|
+
locked_shots: string[] | null;
|
|
39
|
+
project_id: number | null;
|
|
40
|
+
folder_path: string | null;
|
|
41
|
+
tags: string[];
|
|
42
|
+
parent_id: number | null;
|
|
43
|
+
project_public_id: string | null;
|
|
44
|
+
parent_public_id: string | null;
|
|
45
|
+
}
|
|
46
|
+
export type PublicRenderRow = Omit<RenderRow, "id" | "project_id" | "parent_id" | "public_id" | "project_public_id" | "parent_public_id"> & {
|
|
47
|
+
id: string;
|
|
48
|
+
project_id: string | null;
|
|
49
|
+
parent_id: string | null;
|
|
50
|
+
};
|
|
51
|
+
export declare function toPublicRenderRow(row: RenderRow): PublicRenderRow;
|
|
52
|
+
export declare function normalizeProjectIdInput(raw: unknown): number | null;
|
|
53
|
+
export declare function isTerminalStatus(status: string): boolean;
|
|
54
|
+
export declare const PHANTOM_GRACE_SECONDS = 150;
|
|
55
|
+
export type PhantomDecision = "terminal" | "confirming" | "phantom";
|
|
56
|
+
export declare function classifyMissingJob(rowStatus: string, submittedAtSec: number, nowSec: number, graceSec?: number): PhantomDecision;
|
|
57
|
+
/** Build the bound INSERT for a render row, idempotent on job_id (ON CONFLICT DO NOTHING).
|
|
58
|
+
* Returned UNEXECUTED so a caller can `.run()` it directly (insertRender) or compose several
|
|
59
|
+
* into one all-or-nothing `env.DB.batch([...])` -- the atomic scatter submit (#289). */
|
|
60
|
+
export declare function buildInsertRenderStmt(env: Env, row: NewRenderRow): import("./index.js").PreparedStatement;
|
|
61
|
+
export declare function insertRender(env: Env, row: NewRenderRow): Promise<void>;
|
|
62
|
+
export declare function updateRenderFromView(env: Env, view: RunpodJobView, ctx?: ExecutionContext): Promise<void>;
|
|
63
|
+
export declare function setCloudAnimateProgress(env: Env, jobId: string, done: number, total: number): Promise<void>;
|
|
64
|
+
export interface HybridLaneProgress {
|
|
65
|
+
gpu: {
|
|
66
|
+
done: number;
|
|
67
|
+
total: number;
|
|
68
|
+
status?: string;
|
|
69
|
+
};
|
|
70
|
+
cloud: {
|
|
71
|
+
done: number;
|
|
72
|
+
total: number;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
export declare function setHybridProgress(env: Env, jobId: string, lanes: HybridLaneProgress): Promise<void>;
|
|
76
|
+
export interface RenderPollRow {
|
|
77
|
+
status: string;
|
|
78
|
+
submitted_at: number;
|
|
79
|
+
output: unknown;
|
|
80
|
+
output_key: string | null;
|
|
81
|
+
error: string | null;
|
|
82
|
+
}
|
|
83
|
+
export declare function getRenderForPoll(env: Env, jobId: string): Promise<RenderPollRow | null>;
|
|
84
|
+
export declare function markRenderFailedByJobId(env: Env, jobId: string, error: string): Promise<boolean>;
|
|
85
|
+
export declare function claimFinish(env: Env, jobId: string): Promise<boolean>;
|
|
86
|
+
export declare function markFinishDone(env: Env, jobId: string, outputKey: string, outputJson: string): Promise<void>;
|
|
87
|
+
export interface RenderNotifyRow {
|
|
88
|
+
project: string;
|
|
89
|
+
status: string;
|
|
90
|
+
output_key: string | null;
|
|
91
|
+
error: string | null;
|
|
92
|
+
execution_time_ms: number | null;
|
|
93
|
+
mode: string | null;
|
|
94
|
+
}
|
|
95
|
+
export declare function claimRenderNotify(env: Env, jobId: string): Promise<RenderNotifyRow | null>;
|
|
96
|
+
export { FILM_ADVANCE_LEASE_TTL_SECONDS, claimFilmAdvance, releaseFilmAdvance, type FilmAdvanceClaim, } from "./film-advance-lease.js";
|
|
97
|
+
export declare function listUnresolvedNotifiableJobs(env: Env, maxAgeSeconds: number, limit?: number): Promise<string[]>;
|
|
98
|
+
export declare function listStrandedPostClipsFilmJobs(env: Env, maxAgeSeconds: number, limit?: number): Promise<string[]>;
|
|
99
|
+
export declare function markFinishFailed(env: Env, jobId: string, error: string): Promise<void>;
|
|
100
|
+
export declare function getFinishState(env: Env, jobId: string): Promise<{
|
|
101
|
+
finish_state: string | null;
|
|
102
|
+
output_key: string | null;
|
|
103
|
+
} | null>;
|
|
104
|
+
export declare function normalizeLockedShots(raw: unknown): string[];
|
|
105
|
+
export declare function normalizeFolderPath(raw: unknown): string | null;
|
|
106
|
+
export declare function normalizeTags(raw: unknown): string[];
|
|
107
|
+
export declare function normalizeKeyframes(raw: unknown): KeyframeRef[];
|
|
108
|
+
export declare function setRenderAudioOutput(env: Env, id: number, outputKey: string, seconds: number | null): Promise<boolean>;
|
|
109
|
+
export declare function getRenderIdByPublicId(env: Env, publicId: string): Promise<number | null>;
|
|
110
|
+
export declare function getRenderByIdForUser(env: Env, id: number): Promise<RenderRow | null>;
|
|
111
|
+
export declare function setRenderLabel(env: Env, id: number, label: string | null): Promise<boolean>;
|
|
112
|
+
export declare function countOtherRowsWithOutputKey(env: Env, id: number, outputKey: string): Promise<number>;
|
|
113
|
+
export declare function deleteRenderRow(env: Env, id: number): Promise<boolean>;
|
|
114
|
+
/** The renders-list page size when a caller passes no `limit`. ONE source of truth for both the
|
|
115
|
+
* GET /api/storyboard/renders route and this function's default, so they cannot drift (#670: the route
|
|
116
|
+
* said 100, this signature said 50). 50 is a sensible API/MCP page (well under the 200 clamp below);
|
|
117
|
+
* the frontend always sends its own explicit limit, so this governs headless/API/MCP consumers. */
|
|
118
|
+
export declare const DEFAULT_RENDERS_LIMIT = 50;
|
|
119
|
+
export declare function listRendersForUser(env: Env, limit?: number, projectId?: number | null): Promise<RenderRow[]>;
|
|
120
|
+
export declare function setRenderLockedShots(env: Env, id: number, lockedShots: string[]): Promise<boolean>;
|
|
121
|
+
export declare function getRenderIdByJobId(env: Env, jobId: string): Promise<number | null>;
|
|
122
|
+
export declare function getScatterChildren(env: Env, parentId: number): Promise<Array<{
|
|
123
|
+
job_id: string;
|
|
124
|
+
status: string;
|
|
125
|
+
}>>;
|
|
126
|
+
export declare function setRenderFolder(env: Env, id: number, folderPath: string | null): Promise<boolean>;
|
|
127
|
+
export declare function setRenderTags(env: Env, id: number, tags: string[]): Promise<boolean>;
|
|
128
|
+
export declare function listUserTags(env: Env): Promise<string[]>;
|
|
129
|
+
//# sourceMappingURL=renders-db.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"renders-db.d.ts","sourceRoot":"","sources":["../src/renders-db.ts"],"names":[],"mappings":"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"}
|