@vanillaskyai/video 0.1.1 → 0.2.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/CHANGELOG.md +19 -0
- package/PUBLIC-API.md +20 -2
- package/README.md +7 -3
- package/dist/{builtin-server-F7YXRVCH.js → builtin-server-BRTZN4Q7.js} +2 -2
- package/dist/check-runtime.js +1 -1
- package/dist/{chunk-EVG2ZYIY.js → chunk-3O7OMMMF.js} +7 -4
- package/dist/{chunk-GRMUV7QY.js → chunk-BKF3A357.js} +1 -1
- package/dist/{chunk-A2X45FET.js → chunk-I5YWVQ5R.js} +1 -1
- package/dist/{chunk-ERY4S6QV.js → chunk-JW47XCRL.js} +6 -1
- package/dist/{chunk-FQ47WXAJ.js → chunk-K5SRF7D3.js} +4 -0
- package/dist/{chunk-YC5MFXA5.js → chunk-Q2DDQKEG.js} +34 -12
- package/dist/{chunk-XB7LH4J2.js → chunk-QTMHS7JD.js} +2 -1
- package/dist/{chunk-W2XJKG6C.js → chunk-RBQN3VSY.js} +2 -2
- package/dist/{chunk-OOPIETLW.js → chunk-S5ZU5WUU.js} +1 -1
- package/dist/{chunk-ABPKM4GK.js → chunk-STIFILQG.js} +1 -1
- package/dist/{chunk-IXCUY3B3.js → chunk-TGFO454Q.js} +169 -45
- package/dist/{chunk-CHLGW22F.js → chunk-XAMUOSX7.js} +3 -3
- package/dist/cli.js +5 -5
- package/dist/{compose-video-CN3VSWST.js → compose-video-34GRZIF2.js} +4 -4
- package/dist/{events-_wfjbmEp.d.ts → events-B-28kERX.d.ts} +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/{kit-BMNcHqa9.d.ts → kit-CBedbj1n.d.ts} +1 -1
- package/dist/react.d.ts +7 -4
- package/dist/react.js +226 -30
- package/dist/server.d.ts +21 -4
- package/dist/server.js +193 -14
- package/dist/{system-prompt-A6UXNTPK.js → system-prompt-GYTYGWGO.js} +1 -1
- package/dist/template-catalog.js +1 -1
- package/dist/templates.d.ts +3 -3
- package/dist/test.d.ts +3 -2
- package/dist/test.js +3 -3
- package/dist/{text-stream-6XHC7J47.js → text-stream-UPGUD2TD.js} +2 -2
- package/dist/{types-B-PZR6G_.d.ts → types-_t4bduwX.d.ts} +1 -0
- package/docs/concepts.md +7 -0
- package/docs/custom-templates.md +3 -3
- package/docs/errors.md +3 -1
- package/docs/getting-started.md +8 -6
- package/docs/input-and-first-scene.md +7 -4
- package/docs/integrate-nextjs.md +2 -2
- package/docs/media-and-audio.md +73 -14
- package/docs/prompt-and-input.md +7 -0
- package/docs/provider-integration.md +7 -0
- package/docs/reference/protocol.md +9 -0
- package/examples/nextjs-quickstart/package.json +1 -1
- package/package.json +1 -1
- package/registry/items/brandMessage.json +1 -2
- package/registry/items/media.json +2 -1
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
applyVideoEvent,
|
|
6
6
|
checksumVideo,
|
|
7
7
|
createVideoState
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-STIFILQG.js";
|
|
9
9
|
import {
|
|
10
10
|
parseVideoPlanPart,
|
|
11
11
|
safePublicDiagnostic
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-JW47XCRL.js";
|
|
13
13
|
import {
|
|
14
14
|
MAX_RETAINED_INSTRUCTIONS_LENGTH,
|
|
15
15
|
MAX_RETAINED_MEDIA_URLS,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
getCloserReserve,
|
|
27
27
|
getReadableSceneDuration,
|
|
28
28
|
paceScene
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-3O7OMMMF.js";
|
|
30
30
|
import {
|
|
31
31
|
resolveVideoBrand
|
|
32
32
|
} from "./chunk-XGRA2MUV.js";
|
|
@@ -105,9 +105,13 @@ function buildVideoUserPrompt(input, openingDurationSec = 0) {
|
|
|
105
105
|
"For a long source, summarize instead of attempting to represent every fact, unless the creative instructions explicitly request complete fact coverage that fits the duration.",
|
|
106
106
|
"Preserve exact wording and numbers for the takeaways you select. Preserve qualifiers, units, denominators, ranges, and comparison direction; for example, do not shorten 4.8 out of 5 to 4.8.",
|
|
107
107
|
"Choose the scene count from the distinct grounded material and the duration budget. Use fewer scenes for sparse input; continue beyond five when rich input warrants it and timing allows.",
|
|
108
|
+
"If the creative instructions explicitly require one separate scene per named item, release, section, or list entry, do not merge, group, or omit those required items. Keep related required scenes adjacent in a coherent progression while preserving each item as its own scene.",
|
|
109
|
+
"Before emitting, verify that the explicitly requested structure can fit readably within the maximum duration. If it cannot, preserve readability and the requested separation for the scenes that fit, then finish with plan.complete using finishReason length rather than silently changing the structure.",
|
|
110
|
+
"For ordinary multi-fact input, form at least three distinct beats: hook, comprehension, and payoff. Use only one or two beats when the source genuinely contains no more than two independent grounded takeaways. This is a narrative guideline, never permission to repeat facts or add filler.",
|
|
111
|
+
"After the first playable body scene, emit exactly one scene.add with placement closer. Generate a short grounded conclusion that answers the story's so-what; it must not repeat hook language or imply another scene follows.",
|
|
108
112
|
"Use a different suitable template for each body scene when the catalog supports it.",
|
|
109
113
|
"Never add filler to satisfy a count or diversity target.",
|
|
110
|
-
input.suppliedMedia?.length ? "Select zero or more relevant opaque supplied-media references for visible later scenes. Never invent or transform a reference, and
|
|
114
|
+
input.suppliedMedia?.length ? "Select zero or more relevant opaque supplied-media references for visible later scenes. Never invent or transform a reference. Only emit mediaKeyword when the trusted system catalog explicitly exposes it, and only on later scenes. Never invent mediaUrl or mediaPoster." : "No supplied media URL is available. Use asset-free templates unless the trusted system catalog explicitly permits host-resolved media intent. Only emit mediaKeyword when the trusted system catalog explicitly exposes it, and only on later scenes. Never invent mediaUrl or mediaPoster.",
|
|
111
115
|
"",
|
|
112
116
|
"RAW INPUT",
|
|
113
117
|
input.input.trim(),
|
|
@@ -158,12 +162,12 @@ function buildInitialConfig(input, audio, snapshotRetention, closerReserveSec, g
|
|
|
158
162
|
const openingText = input.opening?.trim();
|
|
159
163
|
const rawScenes = openingText ? [{
|
|
160
164
|
id: "supplied-opening",
|
|
161
|
-
templateId: "
|
|
165
|
+
templateId: "media",
|
|
162
166
|
variables: {
|
|
163
|
-
|
|
164
|
-
|
|
167
|
+
texts: openingText,
|
|
168
|
+
mediaType: "gradient"
|
|
165
169
|
},
|
|
166
|
-
timing: { fixedDuration:
|
|
170
|
+
timing: { fixedDuration: 3 }
|
|
167
171
|
}] : [];
|
|
168
172
|
const scenes = [];
|
|
169
173
|
const warnings = [];
|
|
@@ -252,11 +256,42 @@ function createOmittedForCloserWarning(sceneId) {
|
|
|
252
256
|
return {
|
|
253
257
|
code: "scene_omitted_for_closer",
|
|
254
258
|
category: "readability",
|
|
255
|
-
message: "Scene was omitted because the
|
|
259
|
+
message: "Scene was omitted because the reserved closer must remain the last scene.",
|
|
256
260
|
sceneId,
|
|
257
261
|
recoverable: true
|
|
258
262
|
};
|
|
259
263
|
}
|
|
264
|
+
function createDuplicateCloserWarning() {
|
|
265
|
+
return {
|
|
266
|
+
code: "scene_omitted_for_closer",
|
|
267
|
+
category: "readability",
|
|
268
|
+
message: "An additional closer was omitted because the first valid closer is already reserved.",
|
|
269
|
+
recoverable: true
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
function createIncompletePlanWarning() {
|
|
273
|
+
return {
|
|
274
|
+
code: "plan_incomplete",
|
|
275
|
+
category: "provider",
|
|
276
|
+
message: "The planner stopped at a length limit; some requested scenes or the ending may be missing.",
|
|
277
|
+
recoverable: true
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function createMissingCloserWarning() {
|
|
281
|
+
return {
|
|
282
|
+
code: "plan_missing_closer",
|
|
283
|
+
category: "provider",
|
|
284
|
+
message: "The planner completed without a valid closer; the video may end on a body scene.",
|
|
285
|
+
recoverable: true
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function pendingCloserReserve(scene, getTemplatePacing) {
|
|
289
|
+
const metadata = getTemplatePacing?.(scene.templateId);
|
|
290
|
+
const readableMinimum = getReadableSceneDuration(scene, metadata);
|
|
291
|
+
const explicitRange = scene.timing.startTime != null && scene.timing.endTime != null ? Math.max(0, scene.timing.endTime - scene.timing.startTime) : void 0;
|
|
292
|
+
const requested = explicitRange ?? scene.timing.fixedDuration ?? metadata?.preferredDuration ?? readableMinimum;
|
|
293
|
+
return Math.max(readableMinimum, requested);
|
|
294
|
+
}
|
|
260
295
|
function sceneSlotDuration(scene) {
|
|
261
296
|
return Math.max(0, (scene.timing.endTime ?? 0) - (scene.timing.startTime ?? 0));
|
|
262
297
|
}
|
|
@@ -278,8 +313,8 @@ function createSceneQualityWarnings(scene) {
|
|
|
278
313
|
}
|
|
279
314
|
function createVideo(input, options) {
|
|
280
315
|
validateInput(input);
|
|
281
|
-
if (input.opening?.trim() && options.capabilities?.templates != null && !options.capabilities.templates.includes("
|
|
282
|
-
throw new Error("Scene template
|
|
316
|
+
if (input.opening?.trim() && options.capabilities?.templates != null && !options.capabilities.templates.includes("media")) {
|
|
317
|
+
throw new Error("Scene template media was not negotiated");
|
|
283
318
|
}
|
|
284
319
|
const requestId = options.requestId ?? createId("request");
|
|
285
320
|
const runId = options.runId ?? createId("run");
|
|
@@ -379,6 +414,15 @@ function createVideo(input, options) {
|
|
|
379
414
|
resolveResult(finalState);
|
|
380
415
|
}
|
|
381
416
|
};
|
|
417
|
+
let planCompleted = false;
|
|
418
|
+
let generatedSceneCount = 0;
|
|
419
|
+
let runtimeDurationLimited = false;
|
|
420
|
+
let pendingCloser;
|
|
421
|
+
const deferredForCloser = [];
|
|
422
|
+
let plannerReportedLength = false;
|
|
423
|
+
let closerCommitted = false;
|
|
424
|
+
let missingCloser = false;
|
|
425
|
+
let finishReason = "stop";
|
|
382
426
|
try {
|
|
383
427
|
yield emit(events.create("response.start", {
|
|
384
428
|
requestId,
|
|
@@ -398,14 +442,7 @@ function createVideo(input, options) {
|
|
|
398
442
|
revision: 0
|
|
399
443
|
}));
|
|
400
444
|
}
|
|
401
|
-
|
|
402
|
-
let generatedSceneCount = 0;
|
|
403
|
-
let runtimeDurationLimited = false;
|
|
404
|
-
let askAccepted = false;
|
|
405
|
-
const deferredForCloser = [];
|
|
406
|
-
let plannerReportedLength = false;
|
|
407
|
-
let finishReason = "stop";
|
|
408
|
-
const systemPrompt = options.systemPrompt ?? (await import("./system-prompt-A6UXNTPK.js")).DEFAULT_VIDEO_SYSTEM_PROMPT;
|
|
445
|
+
const systemPrompt = options.systemPrompt ?? (await import("./system-prompt-GYTYGWGO.js")).DEFAULT_VIDEO_SYSTEM_PROMPT;
|
|
409
446
|
const context = { request, systemPrompt, userPrompt, initialConfig, signal: controller.signal };
|
|
410
447
|
attachGenerationLifecycleSink(context, lifecycle);
|
|
411
448
|
for await (const untrustedPart of options.generate(context)) {
|
|
@@ -421,21 +458,29 @@ function createVideo(input, options) {
|
|
|
421
458
|
if (options.capabilities?.templates != null && !options.capabilities.templates.includes(part.scene.templateId)) {
|
|
422
459
|
throw new Error(`Scene template ${part.scene.templateId} was not negotiated`);
|
|
423
460
|
}
|
|
424
|
-
if (askAccepted) {
|
|
425
|
-
runtimeDurationLimited = true;
|
|
426
|
-
rejectedSceneCount += 1;
|
|
427
|
-
yield emit(events.create("response.warning", {
|
|
428
|
-
warning: createOmittedForCloserWarning(part.scene.id)
|
|
429
|
-
}));
|
|
430
|
-
continue;
|
|
431
|
-
}
|
|
432
461
|
options.validateScene?.(part.scene, {
|
|
433
462
|
input,
|
|
434
463
|
previousScenes: state.config?.scenes ?? []
|
|
435
464
|
});
|
|
436
465
|
const templatePacing = options.getTemplatePacing?.(part.scene.templateId);
|
|
437
466
|
const isAskCandidate = templatePacing?.jobs?.includes("ask") === true;
|
|
438
|
-
|
|
467
|
+
const isPayoffCandidate = templatePacing?.jobs?.includes("payoff") === true;
|
|
468
|
+
if (part.placement === "closer" && templatePacing && !isAskCandidate && !isPayoffCandidate) {
|
|
469
|
+
throw new Error(`Scene template ${part.scene.templateId} cannot be used as a closer`);
|
|
470
|
+
}
|
|
471
|
+
const isCloserCandidate = part.placement === "closer" || isAskCandidate;
|
|
472
|
+
if (isCloserCandidate) {
|
|
473
|
+
if (pendingCloser) {
|
|
474
|
+
rejectedSceneCount += 1;
|
|
475
|
+
yield emit(events.create("response.warning", {
|
|
476
|
+
warning: createDuplicateCloserWarning()
|
|
477
|
+
}));
|
|
478
|
+
} else {
|
|
479
|
+
pendingCloser = part.scene;
|
|
480
|
+
}
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (deferredForCloser.length) {
|
|
439
484
|
deferredForCloser.push(part.scene);
|
|
440
485
|
continue;
|
|
441
486
|
}
|
|
@@ -443,7 +488,7 @@ function createVideo(input, options) {
|
|
|
443
488
|
previousScenes: state.config?.scenes ?? [],
|
|
444
489
|
audio: state.config?.audio,
|
|
445
490
|
maxDurationSec: input.maxDurationSec ?? 30,
|
|
446
|
-
closerReserveSec,
|
|
491
|
+
closerReserveSec: pendingCloser ? pendingCloserReserve(pendingCloser, options.getTemplatePacing) : closerReserveSec,
|
|
447
492
|
getTemplatePacing: options.getTemplatePacing
|
|
448
493
|
});
|
|
449
494
|
if (!paced.scene) {
|
|
@@ -459,16 +504,6 @@ function createVideo(input, options) {
|
|
|
459
504
|
continue;
|
|
460
505
|
}
|
|
461
506
|
const scene = paced.scene;
|
|
462
|
-
const isAsk = isAskCandidate;
|
|
463
|
-
if (isAsk && deferredForCloser.length) {
|
|
464
|
-
runtimeDurationLimited = true;
|
|
465
|
-
for (const deferred of deferredForCloser.splice(0)) {
|
|
466
|
-
rejectedSceneCount += 1;
|
|
467
|
-
yield emit(events.create("response.warning", {
|
|
468
|
-
warning: createOmittedForCloserWarning(deferred.id)
|
|
469
|
-
}));
|
|
470
|
-
}
|
|
471
|
-
}
|
|
472
507
|
for (const warning of paced.warnings) {
|
|
473
508
|
yield emit(events.create("response.warning", { warning }));
|
|
474
509
|
}
|
|
@@ -480,13 +515,24 @@ function createVideo(input, options) {
|
|
|
480
515
|
position: state.config?.scenes.length ?? 0,
|
|
481
516
|
revision: 0
|
|
482
517
|
}));
|
|
483
|
-
if (isAsk) {
|
|
484
|
-
askAccepted = true;
|
|
485
|
-
}
|
|
486
518
|
generatedSceneCount += 1;
|
|
487
519
|
acceptedSceneCount += 1;
|
|
488
520
|
timeToFirstSceneMs ??= Math.max(0, now() - startedAt);
|
|
489
521
|
} else if (part.type === "scene.patch") {
|
|
522
|
+
if (pendingCloser?.id === part.sceneId) {
|
|
523
|
+
const nextPendingCloser = {
|
|
524
|
+
...pendingCloser,
|
|
525
|
+
...part.patch,
|
|
526
|
+
variables: part.patch.variables ? { ...pendingCloser.variables, ...part.patch.variables } : pendingCloser.variables,
|
|
527
|
+
timing: part.patch.timing ? { ...pendingCloser.timing, ...part.patch.timing } : pendingCloser.timing
|
|
528
|
+
};
|
|
529
|
+
options.validateScene?.(nextPendingCloser, {
|
|
530
|
+
input,
|
|
531
|
+
previousScenes: state.config?.scenes ?? []
|
|
532
|
+
});
|
|
533
|
+
pendingCloser = nextPendingCloser;
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
490
536
|
const scenes = state.config?.scenes ?? [];
|
|
491
537
|
const sceneIndex = scenes.findIndex((scene) => scene.id === part.sceneId);
|
|
492
538
|
if (sceneIndex < 0) throw new Error(`Scene ${part.sceneId} does not exist`);
|
|
@@ -521,7 +567,7 @@ function createVideo(input, options) {
|
|
|
521
567
|
previousScenes: scenes.slice(0, sceneIndex),
|
|
522
568
|
audio: state.config?.audio,
|
|
523
569
|
maxDurationSec: input.maxDurationSec ?? 30,
|
|
524
|
-
closerReserveSec,
|
|
570
|
+
closerReserveSec: pendingCloser ? pendingCloserReserve(pendingCloser, options.getTemplatePacing) : closerReserveSec,
|
|
525
571
|
getTemplatePacing: options.getTemplatePacing
|
|
526
572
|
});
|
|
527
573
|
if (!pacedPatch.scene) {
|
|
@@ -561,6 +607,18 @@ function createVideo(input, options) {
|
|
|
561
607
|
patch
|
|
562
608
|
}));
|
|
563
609
|
} else if (part.type === "asset.patch") {
|
|
610
|
+
if (pendingCloser?.id === part.sceneId) {
|
|
611
|
+
const nextPendingCloser = {
|
|
612
|
+
...pendingCloser,
|
|
613
|
+
variables: { ...pendingCloser.variables, ...part.variables }
|
|
614
|
+
};
|
|
615
|
+
options.validateScene?.(nextPendingCloser, {
|
|
616
|
+
input,
|
|
617
|
+
previousScenes: state.config?.scenes ?? []
|
|
618
|
+
});
|
|
619
|
+
pendingCloser = nextPendingCloser;
|
|
620
|
+
continue;
|
|
621
|
+
}
|
|
564
622
|
const scenes = state.config?.scenes ?? [];
|
|
565
623
|
const scene = scenes.find((item) => item.id === part.sceneId);
|
|
566
624
|
if (!scene) throw new Error(`Scene ${part.sceneId} does not exist`);
|
|
@@ -604,7 +662,39 @@ function createVideo(input, options) {
|
|
|
604
662
|
yield errorEvent;
|
|
605
663
|
} else if (part.type === "plan.complete") {
|
|
606
664
|
if (planCompleted) throw new Error("The planner emitted plan.complete more than once");
|
|
607
|
-
if (
|
|
665
|
+
if (pendingCloser) {
|
|
666
|
+
if (deferredForCloser.length) runtimeDurationLimited = true;
|
|
667
|
+
for (const deferred of deferredForCloser.splice(0)) {
|
|
668
|
+
rejectedSceneCount += 1;
|
|
669
|
+
yield emit(events.create("response.warning", {
|
|
670
|
+
warning: createOmittedForCloserWarning(deferred.id)
|
|
671
|
+
}));
|
|
672
|
+
}
|
|
673
|
+
const pacedCloser = paceScene(pendingCloser, {
|
|
674
|
+
previousScenes: state.config?.scenes ?? [],
|
|
675
|
+
audio: state.config?.audio,
|
|
676
|
+
maxDurationSec: input.maxDurationSec ?? 30,
|
|
677
|
+
closerReserveSec: 0,
|
|
678
|
+
getTemplatePacing: options.getTemplatePacing
|
|
679
|
+
});
|
|
680
|
+
for (const warning of pacedCloser.warnings) {
|
|
681
|
+
yield emit(events.create("response.warning", { warning }));
|
|
682
|
+
}
|
|
683
|
+
if (pacedCloser.scene) {
|
|
684
|
+
yield emit(events.create("scene.add", {
|
|
685
|
+
scene: pacedCloser.scene,
|
|
686
|
+
position: state.config?.scenes.length ?? 0,
|
|
687
|
+
revision: 0
|
|
688
|
+
}));
|
|
689
|
+
generatedSceneCount += 1;
|
|
690
|
+
acceptedSceneCount += 1;
|
|
691
|
+
timeToFirstSceneMs ??= Math.max(0, now() - startedAt);
|
|
692
|
+
closerCommitted = true;
|
|
693
|
+
} else {
|
|
694
|
+
runtimeDurationLimited = true;
|
|
695
|
+
rejectedSceneCount += 1;
|
|
696
|
+
}
|
|
697
|
+
} else if (deferredForCloser.length) {
|
|
608
698
|
for (const deferred of deferredForCloser.splice(0)) {
|
|
609
699
|
const recovered = paceScene(deferred, {
|
|
610
700
|
previousScenes: state.config?.scenes ?? [],
|
|
@@ -634,8 +724,15 @@ function createVideo(input, options) {
|
|
|
634
724
|
timeToFirstSceneMs ??= Math.max(0, now() - startedAt);
|
|
635
725
|
}
|
|
636
726
|
}
|
|
727
|
+
if (options.requireCloser && !closerCommitted) {
|
|
728
|
+
missingCloser = true;
|
|
729
|
+
yield emit(events.create("response.warning", {
|
|
730
|
+
warning: createMissingCloserWarning()
|
|
731
|
+
}));
|
|
732
|
+
}
|
|
637
733
|
planCompleted = true;
|
|
638
|
-
|
|
734
|
+
const reportedFinishReason = part.finishReason ?? "stop";
|
|
735
|
+
finishReason = runtimeDurationLimited ? "length" : reportedFinishReason !== "stop" ? reportedFinishReason : missingCloser ? "other" : "stop";
|
|
639
736
|
plannerReportedLength = part.finishReason === "length";
|
|
640
737
|
continue;
|
|
641
738
|
}
|
|
@@ -665,6 +762,11 @@ function createVideo(input, options) {
|
|
|
665
762
|
if (plannerReportedLength && generatedSceneCount === 0) {
|
|
666
763
|
throw new Error("The planner was truncated before adding a generated scene");
|
|
667
764
|
}
|
|
765
|
+
if (plannerReportedLength) {
|
|
766
|
+
yield emit(events.create("response.warning", {
|
|
767
|
+
warning: createIncompletePlanWarning()
|
|
768
|
+
}));
|
|
769
|
+
}
|
|
668
770
|
if (!state.config?.scenes.length) throw new Error("The planner completed without adding a scene");
|
|
669
771
|
const snapshot = parseVideo(state.config);
|
|
670
772
|
const completeEvent = emit(events.create("response.complete", {
|
|
@@ -699,6 +801,28 @@ function createVideo(input, options) {
|
|
|
699
801
|
return;
|
|
700
802
|
}
|
|
701
803
|
try {
|
|
804
|
+
if (pendingCloser && !closerCommitted && state.config?.scenes.length) {
|
|
805
|
+
const pacedCloser = paceScene(pendingCloser, {
|
|
806
|
+
previousScenes: state.config.scenes,
|
|
807
|
+
audio: state.config.audio,
|
|
808
|
+
maxDurationSec: input.maxDurationSec ?? 30,
|
|
809
|
+
closerReserveSec: 0,
|
|
810
|
+
getTemplatePacing: options.getTemplatePacing
|
|
811
|
+
});
|
|
812
|
+
for (const warning of pacedCloser.warnings) {
|
|
813
|
+
yield emit(events.create("response.warning", { warning }));
|
|
814
|
+
}
|
|
815
|
+
if (pacedCloser.scene) {
|
|
816
|
+
yield emit(events.create("scene.add", {
|
|
817
|
+
scene: pacedCloser.scene,
|
|
818
|
+
position: state.config.scenes.length,
|
|
819
|
+
revision: 0
|
|
820
|
+
}));
|
|
821
|
+
generatedSceneCount += 1;
|
|
822
|
+
acceptedSceneCount += 1;
|
|
823
|
+
closerCommitted = true;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
702
826
|
const provider = await settleProviderLifecycle();
|
|
703
827
|
for (const warning of provider.warnings) {
|
|
704
828
|
if (!state.warnings.some((existing) => existing.code === warning.code && existing.message === warning.message)) {
|
|
@@ -7,7 +7,8 @@ var GENERATED_BUILTIN_TEMPLATE_CATALOG = [
|
|
|
7
7
|
"family": "Media & motion",
|
|
8
8
|
"jobs": [
|
|
9
9
|
"setup",
|
|
10
|
-
"atmosphere"
|
|
10
|
+
"atmosphere",
|
|
11
|
+
"payoff"
|
|
11
12
|
],
|
|
12
13
|
"register": "motion-led",
|
|
13
14
|
"useWhen": "A visual hook, scenic beat, or concrete product-context line benefits from immersive media.",
|
|
@@ -2405,8 +2406,7 @@ var GENERATED_BUILTIN_TEMPLATE_CATALOG = [
|
|
|
2405
2406
|
"description": "A single iMessage-style outgoing bubble floats over media or a brand gradient.",
|
|
2406
2407
|
"family": "Social & messaging",
|
|
2407
2408
|
"jobs": [
|
|
2408
|
-
"claim"
|
|
2409
|
-
"payoff"
|
|
2409
|
+
"claim"
|
|
2410
2410
|
],
|
|
2411
2411
|
"register": "card-led",
|
|
2412
2412
|
"useWhen": "A direct one-to-one thank-you, invitation, promise, or concise launch note is the point.",
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
3
|
-
import "./chunk-
|
|
4
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-Q2DDQKEG.js";
|
|
3
|
+
import "./chunk-K5SRF7D3.js";
|
|
4
|
+
import "./chunk-3O7OMMMF.js";
|
|
5
5
|
import {
|
|
6
6
|
isTemplatePropertyFormatSupported,
|
|
7
7
|
validateTemplateSchemaValue
|
|
@@ -9,13 +9,13 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
getBuiltinTemplateMetadata,
|
|
11
11
|
listBuiltinTemplateMetadata
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XAMUOSX7.js";
|
|
13
13
|
import {
|
|
14
14
|
assertTemplateTransitionMetadata
|
|
15
15
|
} from "./chunk-2E6T633S.js";
|
|
16
16
|
import {
|
|
17
17
|
BUILTIN_TEMPLATE_MANIFEST
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-RBQN3VSY.js";
|
|
19
19
|
import {
|
|
20
20
|
getTemplateDefaults,
|
|
21
21
|
isMeaningfullyPresentTemplateValue,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createVideo
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TGFO454Q.js";
|
|
4
4
|
import "./chunk-E7CL7UPB.js";
|
|
5
|
-
import "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-STIFILQG.js";
|
|
6
|
+
import "./chunk-JW47XCRL.js";
|
|
7
7
|
import "./chunk-GHJEAP4O.js";
|
|
8
8
|
import "./chunk-EE6PK6XC.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-3O7OMMMF.js";
|
|
10
10
|
import "./chunk-XGRA2MUV.js";
|
|
11
11
|
export {
|
|
12
12
|
createVideo
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { e as VideoOrientation, g as VideoStyle, V as Video, j as VideoCapabilities, a as VideoAudio, f as VideoScene, k as VIDEO_PROTOCOL_VERSION } from './types-
|
|
1
|
+
import { e as VideoOrientation, g as VideoStyle, V as Video, j as VideoCapabilities, a as VideoAudio, f as VideoScene, k as VIDEO_PROTOCOL_VERSION } from './types-_t4bduwX.js';
|
|
2
2
|
|
|
3
3
|
type VideoWarningCategory = "validation" | "readability" | "grounding" | "provider" | "media" | "protocol";
|
|
4
|
-
type VideoWarningCode = "scene_duration_adjusted" | "scene_omitted_unreadable" | "scene_omitted_for_closer" | "scene_patch_rejected_readability" | "chart_scale_imbalance" | "provider_warning" | "provider_diagnostics_unavailable";
|
|
4
|
+
type VideoWarningCode = "scene_duration_adjusted" | "scene_omitted_unreadable" | "scene_omitted_for_closer" | "scene_patch_rejected_readability" | "chart_scale_imbalance" | "plan_incomplete" | "plan_missing_closer" | "provider_warning" | "provider_diagnostics_unavailable";
|
|
5
5
|
/** A bounded, client-safe diagnostic that never includes provider payloads. */
|
|
6
6
|
interface VideoWarning {
|
|
7
7
|
code: VideoWarningCode;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { V as Video } from './types-
|
|
2
|
-
export { a as VideoAudio, b as VideoBackground, c as VideoBrand, d as VideoInput, e as VideoOrientation, f as VideoScene, g as VideoStyle, h as VideoStyleOptions, i as VideoSuppliedMedia } from './types-
|
|
1
|
+
import { V as Video } from './types-_t4bduwX.js';
|
|
2
|
+
export { a as VideoAudio, b as VideoBackground, c as VideoBrand, d as VideoInput, e as VideoOrientation, f as VideoScene, g as VideoStyle, h as VideoStyleOptions, i as VideoSuppliedMedia } from './types-_t4bduwX.js';
|
|
3
3
|
export { V as VideoStatus } from './state-DZcKuS32.js';
|
|
4
4
|
|
|
5
5
|
type VideoValidationErrorCode = "invalid_video" | "unsupported_video_version";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as VideoStyle, j as VideoCapabilities } from './types-
|
|
1
|
+
import { g as VideoStyle, j as VideoCapabilities } from './types-_t4bduwX.js';
|
|
2
2
|
import { ComponentType } from 'react';
|
|
3
3
|
import { S as SceneTemplateMetadata, d as TemplateJsonSchema, f as TemplateJsonSchemaProperty } from './catalog-types-BIhSpOWK.js';
|
|
4
4
|
|
package/dist/react.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { CSSProperties, ReactElement } from 'react';
|
|
2
|
-
import { V as VideoEvent, a as VideoWarning } from './events-
|
|
3
|
-
import { e as VideoOrientation, V as Video, d as VideoInput } from './types-
|
|
4
|
-
import { T as TemplateRegistry } from './kit-
|
|
2
|
+
import { V as VideoEvent, a as VideoWarning } from './events-B-28kERX.js';
|
|
3
|
+
import { e as VideoOrientation, V as Video, d as VideoInput } from './types-_t4bduwX.js';
|
|
4
|
+
import { T as TemplateRegistry } from './kit-CBedbj1n.js';
|
|
5
5
|
import { V as VideoStatus } from './state-DZcKuS32.js';
|
|
6
6
|
import './catalog-types-BIhSpOWK.js';
|
|
7
7
|
|
|
8
|
+
type VideoPlaybackMode = "manual" | "muted-autoplay" | "autoplay-with-sound" | "autoplay-after-interaction";
|
|
8
9
|
interface VideoPlayerSharedProps {
|
|
10
|
+
/** High-level startup policy. When set, this overrides autoPlay and startMuted. */
|
|
11
|
+
playbackMode?: VideoPlaybackMode;
|
|
9
12
|
/** Initial playback state. Reduced-motion preferences take precedence. */
|
|
10
13
|
autoPlay?: boolean;
|
|
11
14
|
startMuted?: boolean;
|
|
@@ -78,4 +81,4 @@ interface UseVideoResult {
|
|
|
78
81
|
}
|
|
79
82
|
declare function useVideo(options?: UseVideoOptions): UseVideoResult;
|
|
80
83
|
|
|
81
|
-
export { type UseVideoOptions, type UseVideoResult, VideoError, type VideoErrorOptions, VideoPlayer, type VideoPlayerProps, useVideo };
|
|
84
|
+
export { type UseVideoOptions, type UseVideoResult, VideoError, type VideoErrorOptions, type VideoPlaybackMode, VideoPlayer, type VideoPlayerProps, useVideo };
|