@vanillaskyai/video 0.9.0 → 0.10.1
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/dist/{builtin-server-HW6HGXCZ.js → builtin-server-W4PLJUZ5.js} +2 -2
- package/dist/check-runtime.js +2 -2
- package/dist/{chunk-UDIODEDK.js → chunk-224QNWRA.js} +5 -1
- package/dist/{chunk-MXEYPK7M.js → chunk-4ZJLPHBV.js} +194 -62
- package/dist/{chunk-ZDJNFA52.js → chunk-5BSJLT6H.js} +6 -6
- package/dist/{chunk-G7IZBBWF.js → chunk-5C6HZNHY.js} +12 -14
- package/dist/{chunk-3ZTEFJIR.js → chunk-6KZGF63O.js} +47 -12
- package/dist/{chunk-LH4BPALA.js → chunk-IIN5M5HW.js} +194 -61
- package/dist/{chunk-MQILEEXC.js → chunk-IR44XKBI.js} +1 -1
- package/dist/{chunk-OR52UMSF.js → chunk-JKVOBTRO.js} +3 -2
- package/dist/chunk-KHLO5OHT.js +35 -0
- package/dist/{chunk-PAJ44TFW.js → chunk-LVM5Q2DL.js} +8 -6
- package/dist/chunk-VQH3JTQC.js +16 -0
- package/dist/{cinema-media-YQHSIFDA.js → cinema-media-APDJS7SC.js} +3 -2
- package/dist/cli.js +4 -4
- package/dist/{comparison-RZMMHZR2.js → comparison-ZVE2DE7U.js} +14 -4
- package/dist/{compose-video-TBFTONUC.js → compose-video-BH5K6XWT.js} +1 -1
- package/dist/{editorial-timeline-OZX7OS6G.js → editorial-timeline-YIXXVJUV.js} +10 -3
- package/dist/key-figure-I2C37FWV.js +30 -0
- package/dist/{mobile-message-UZUPIKHD.js → mobile-message-JSGBU6EX.js} +3 -2
- package/dist/{preload-media-CFTZIMZL.js → preload-media-LJXWKTWG.js} +1 -1
- package/dist/quote-XH54G3FS.js +33 -0
- package/dist/react.js +58 -33
- package/dist/server.js +106 -27
- package/dist/{system-prompt-SYRT5DWM.js → system-prompt-AG26KJAA.js} +1 -1
- package/dist/template-catalog.d.ts +154 -19
- package/dist/template-catalog.js +1 -1
- package/dist/test.js +2 -2
- package/docs/customization.md +1 -1
- package/docs/maintainers/cinematic-migration.md +4 -0
- package/docs/media-and-audio.md +3 -3
- package/docs/provider-integration.md +1 -1
- package/package.json +1 -1
- package/registry/items/cinemaMedia.json +1 -1
- package/registry/items/comparison.json +71 -4
- package/registry/items/editorialTimeline.json +71 -4
- package/registry/items/keyFigure.json +69 -4
- package/registry/items/mobileMessage.json +1 -1
- package/registry/items/quote.json +71 -4
- package/starters/video-chat/package.json +1 -1
- package/dist/focus-cards-TJ72BT7U.js +0 -20
- package/dist/key-figure-GYENXKH3.js +0 -20
- package/dist/quote-EW5HQA6H.js +0 -23
- package/registry/items/focusCards.json +0 -90
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ VanillaSky follows semantic versioning. This changelog begins with the 0.1 beta.
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.10.1
|
|
8
|
+
|
|
9
|
+
- Continue narration through failed built-in media using the authored fallback or the existing graphic on black. Keep the recovery anchor after URL resolution, and observe actual mounted images for photo readiness.
|
|
10
|
+
|
|
11
|
+
- Match planning, narration, visual progression and endings to explanations, fiction, comedy, imaginative requests and practical answers. Remove conflicting instructions that forced a factual arc, fixed sentence length or a different template for every beat.
|
|
12
|
+
- Ask follow-up generation to exclude questions already answered by the full narration, including paraphrases, and to preserve the conversation’s intent.
|
|
13
|
+
|
|
14
|
+
## 0.10.0
|
|
15
|
+
|
|
16
|
+
### Breaking
|
|
17
|
+
|
|
18
|
+
- Remove `focusCards` from the built-in catalog and generated source templates, as requested. Existing callers must replace it with narration over `cinemaMedia`, or an appropriate comparison/timeline when supported by their content. Persisted videos using that ID must be regenerated before playback with the new catalog.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Opening narration advances into the first shot and body. Exact repeated introductory sentences are removed without additional model calls or startup waits.
|
|
23
|
+
- Prefer relevant footage over repeated graphic scenes; use no more than one explanatory overlay in a typical thirty-second answer. Comparison, key figure, quote and timeline can now use optional host-resolved media with a contrast scrim and soft text shadows. Black remains the fallback; chapter titles stay black.
|
|
24
|
+
|
|
25
|
+
|
|
7
26
|
## 0.9.0
|
|
8
27
|
|
|
9
28
|
- Continue video playback with subtitles when native browser speech cannot start, without weakening generated-audio readiness or counting paused time toward the fallback.
|
package/dist/check-runtime.js
CHANGED
|
@@ -19,8 +19,12 @@ function resolveMediaType(mediaType, mediaUrl) {
|
|
|
19
19
|
if (mediaType === "photo") return "photo";
|
|
20
20
|
return mediaUrl && isVideoUrl(mediaUrl) ? "video" : "photo";
|
|
21
21
|
}
|
|
22
|
+
function hasSceneMedia(variables) {
|
|
23
|
+
return String(variables.mediaUrl || "").trim() !== "" && String(variables.mediaType || "auto") !== "gradient";
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
export {
|
|
24
27
|
limitsConcurrentVideoDecoders,
|
|
25
|
-
resolveMediaType
|
|
28
|
+
resolveMediaType,
|
|
29
|
+
hasSceneMedia
|
|
26
30
|
};
|
|
@@ -80,31 +80,6 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
80
80
|
],
|
|
81
81
|
"additionalProperties": false
|
|
82
82
|
},
|
|
83
|
-
"focusCards": {
|
|
84
|
-
"type": "object",
|
|
85
|
-
"properties": {
|
|
86
|
-
"items": {
|
|
87
|
-
"type": "array",
|
|
88
|
-
"minItems": 2,
|
|
89
|
-
"maxItems": 4,
|
|
90
|
-
"items": {
|
|
91
|
-
"type": "string",
|
|
92
|
-
"minLength": 1,
|
|
93
|
-
"maxLength": 55
|
|
94
|
-
},
|
|
95
|
-
"default": [
|
|
96
|
-
"Listen closely",
|
|
97
|
-
"Notice the pattern",
|
|
98
|
-
"Make room for change"
|
|
99
|
-
],
|
|
100
|
-
"description": "2\u20134 parallel phrases, about 2\u20136 words each; no heading or numbering."
|
|
101
|
-
}
|
|
102
|
-
},
|
|
103
|
-
"required": [
|
|
104
|
-
"items"
|
|
105
|
-
],
|
|
106
|
-
"additionalProperties": false
|
|
107
|
-
},
|
|
108
83
|
"editorialTimeline": {
|
|
109
84
|
"type": "object",
|
|
110
85
|
"properties": {
|
|
@@ -138,12 +113,59 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
138
113
|
}
|
|
139
114
|
],
|
|
140
115
|
"description": "3\u20135 ordered events or actions, each with one short label; no dates."
|
|
116
|
+
},
|
|
117
|
+
"mediaKeyword": {
|
|
118
|
+
"type": "string",
|
|
119
|
+
"format": "stock-media-keyword",
|
|
120
|
+
"minLength": 1,
|
|
121
|
+
"maxLength": 80,
|
|
122
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
123
|
+
"examples": [
|
|
124
|
+
"Ocean waves breaking on a rocky shore"
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
"mediaUrl": {
|
|
128
|
+
"type": "string",
|
|
129
|
+
"format": "uri",
|
|
130
|
+
"description": "Host-only approved photo or video URL.",
|
|
131
|
+
"default": ""
|
|
132
|
+
},
|
|
133
|
+
"mediaType": {
|
|
134
|
+
"type": "string",
|
|
135
|
+
"enum": [
|
|
136
|
+
"photo",
|
|
137
|
+
"video"
|
|
138
|
+
],
|
|
139
|
+
"default": "video",
|
|
140
|
+
"description": "Host-resolved asset kind."
|
|
141
|
+
},
|
|
142
|
+
"mediaPoster": {
|
|
143
|
+
"type": "string",
|
|
144
|
+
"format": "uri",
|
|
145
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
146
|
+
"default": ""
|
|
147
|
+
},
|
|
148
|
+
"shotDirection": {
|
|
149
|
+
"type": "string",
|
|
150
|
+
"maxLength": 220,
|
|
151
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
152
|
+
},
|
|
153
|
+
"mediaSource": {
|
|
154
|
+
"type": "string",
|
|
155
|
+
"enum": [
|
|
156
|
+
"generate",
|
|
157
|
+
"stock"
|
|
158
|
+
],
|
|
159
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
141
160
|
}
|
|
142
161
|
},
|
|
143
162
|
"required": [
|
|
144
163
|
"events"
|
|
145
164
|
],
|
|
146
|
-
"additionalProperties": false
|
|
165
|
+
"additionalProperties": false,
|
|
166
|
+
"x-vanillasky": {
|
|
167
|
+
"allowsStockMedia": true
|
|
168
|
+
}
|
|
147
169
|
},
|
|
148
170
|
"mobileMessage": {
|
|
149
171
|
"type": "object",
|
|
@@ -239,13 +261,60 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
239
261
|
"maxLength": 60,
|
|
240
262
|
"default": "More room to think",
|
|
241
263
|
"description": "Second real alternative, parallel to the first."
|
|
264
|
+
},
|
|
265
|
+
"mediaKeyword": {
|
|
266
|
+
"type": "string",
|
|
267
|
+
"format": "stock-media-keyword",
|
|
268
|
+
"minLength": 1,
|
|
269
|
+
"maxLength": 80,
|
|
270
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
271
|
+
"examples": [
|
|
272
|
+
"Ocean waves breaking on a rocky shore"
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
"mediaUrl": {
|
|
276
|
+
"type": "string",
|
|
277
|
+
"format": "uri",
|
|
278
|
+
"description": "Host-only approved photo or video URL.",
|
|
279
|
+
"default": ""
|
|
280
|
+
},
|
|
281
|
+
"mediaType": {
|
|
282
|
+
"type": "string",
|
|
283
|
+
"enum": [
|
|
284
|
+
"photo",
|
|
285
|
+
"video"
|
|
286
|
+
],
|
|
287
|
+
"default": "video",
|
|
288
|
+
"description": "Host-resolved asset kind."
|
|
289
|
+
},
|
|
290
|
+
"mediaPoster": {
|
|
291
|
+
"type": "string",
|
|
292
|
+
"format": "uri",
|
|
293
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
294
|
+
"default": ""
|
|
295
|
+
},
|
|
296
|
+
"shotDirection": {
|
|
297
|
+
"type": "string",
|
|
298
|
+
"maxLength": 220,
|
|
299
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
300
|
+
},
|
|
301
|
+
"mediaSource": {
|
|
302
|
+
"type": "string",
|
|
303
|
+
"enum": [
|
|
304
|
+
"generate",
|
|
305
|
+
"stock"
|
|
306
|
+
],
|
|
307
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
242
308
|
}
|
|
243
309
|
},
|
|
244
310
|
"required": [
|
|
245
311
|
"leftText",
|
|
246
312
|
"rightText"
|
|
247
313
|
],
|
|
248
|
-
"additionalProperties": false
|
|
314
|
+
"additionalProperties": false,
|
|
315
|
+
"x-vanillasky": {
|
|
316
|
+
"allowsStockMedia": true
|
|
317
|
+
}
|
|
249
318
|
},
|
|
250
319
|
"quote": {
|
|
251
320
|
"type": "object",
|
|
@@ -268,13 +337,60 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
268
337
|
"Illustrative example"
|
|
269
338
|
],
|
|
270
339
|
"description": "Grounded attribution belonging to these exact quoted words."
|
|
340
|
+
},
|
|
341
|
+
"mediaKeyword": {
|
|
342
|
+
"type": "string",
|
|
343
|
+
"format": "stock-media-keyword",
|
|
344
|
+
"minLength": 1,
|
|
345
|
+
"maxLength": 80,
|
|
346
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
347
|
+
"examples": [
|
|
348
|
+
"Ocean waves breaking on a rocky shore"
|
|
349
|
+
]
|
|
350
|
+
},
|
|
351
|
+
"mediaUrl": {
|
|
352
|
+
"type": "string",
|
|
353
|
+
"format": "uri",
|
|
354
|
+
"description": "Host-only approved photo or video URL.",
|
|
355
|
+
"default": ""
|
|
356
|
+
},
|
|
357
|
+
"mediaType": {
|
|
358
|
+
"type": "string",
|
|
359
|
+
"enum": [
|
|
360
|
+
"photo",
|
|
361
|
+
"video"
|
|
362
|
+
],
|
|
363
|
+
"default": "video",
|
|
364
|
+
"description": "Host-resolved asset kind."
|
|
365
|
+
},
|
|
366
|
+
"mediaPoster": {
|
|
367
|
+
"type": "string",
|
|
368
|
+
"format": "uri",
|
|
369
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
370
|
+
"default": ""
|
|
371
|
+
},
|
|
372
|
+
"shotDirection": {
|
|
373
|
+
"type": "string",
|
|
374
|
+
"maxLength": 220,
|
|
375
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
376
|
+
},
|
|
377
|
+
"mediaSource": {
|
|
378
|
+
"type": "string",
|
|
379
|
+
"enum": [
|
|
380
|
+
"generate",
|
|
381
|
+
"stock"
|
|
382
|
+
],
|
|
383
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
271
384
|
}
|
|
272
385
|
},
|
|
273
386
|
"required": [
|
|
274
387
|
"quote",
|
|
275
388
|
"attribution"
|
|
276
389
|
],
|
|
277
|
-
"additionalProperties": false
|
|
390
|
+
"additionalProperties": false,
|
|
391
|
+
"x-vanillasky": {
|
|
392
|
+
"allowsStockMedia": true
|
|
393
|
+
}
|
|
278
394
|
},
|
|
279
395
|
"keyFigure": {
|
|
280
396
|
"type": "object",
|
|
@@ -297,6 +413,50 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
297
413
|
"Illustrative example"
|
|
298
414
|
],
|
|
299
415
|
"description": "Exactly one short label identifying the quantity and its context."
|
|
416
|
+
},
|
|
417
|
+
"mediaKeyword": {
|
|
418
|
+
"type": "string",
|
|
419
|
+
"format": "stock-media-keyword",
|
|
420
|
+
"minLength": 1,
|
|
421
|
+
"maxLength": 80,
|
|
422
|
+
"description": "2\u20138 word literal subject/action search intent, maximum 80 characters. Host resolves URLs.",
|
|
423
|
+
"examples": [
|
|
424
|
+
"Ocean waves breaking on a rocky shore"
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
"mediaUrl": {
|
|
428
|
+
"type": "string",
|
|
429
|
+
"format": "uri",
|
|
430
|
+
"description": "Host-only approved photo or video URL.",
|
|
431
|
+
"default": ""
|
|
432
|
+
},
|
|
433
|
+
"mediaType": {
|
|
434
|
+
"type": "string",
|
|
435
|
+
"enum": [
|
|
436
|
+
"photo",
|
|
437
|
+
"video"
|
|
438
|
+
],
|
|
439
|
+
"default": "video",
|
|
440
|
+
"description": "Host-resolved asset kind."
|
|
441
|
+
},
|
|
442
|
+
"mediaPoster": {
|
|
443
|
+
"type": "string",
|
|
444
|
+
"format": "uri",
|
|
445
|
+
"description": "Host-only approved poster URL for video decoding.",
|
|
446
|
+
"default": ""
|
|
447
|
+
},
|
|
448
|
+
"shotDirection": {
|
|
449
|
+
"type": "string",
|
|
450
|
+
"maxLength": 220,
|
|
451
|
+
"description": "Optional action, framing and continuity for generation. Preserve the subject; do not request rendered text."
|
|
452
|
+
},
|
|
453
|
+
"mediaSource": {
|
|
454
|
+
"type": "string",
|
|
455
|
+
"enum": [
|
|
456
|
+
"generate",
|
|
457
|
+
"stock"
|
|
458
|
+
],
|
|
459
|
+
"description": "Generate distinctive illustrative shots; use approved stock for familiar observable subjects."
|
|
300
460
|
}
|
|
301
461
|
},
|
|
302
462
|
"required": [
|
|
@@ -305,7 +465,8 @@ var BUILTIN_TEMPLATE_SCHEMAS = {
|
|
|
305
465
|
],
|
|
306
466
|
"additionalProperties": false,
|
|
307
467
|
"x-vanillasky": {
|
|
308
|
-
"requiresStat": true
|
|
468
|
+
"requiresStat": true,
|
|
469
|
+
"allowsStockMedia": true
|
|
309
470
|
}
|
|
310
471
|
}
|
|
311
472
|
};
|
|
@@ -369,38 +530,9 @@ var BUILTIN_TEMPLATE_MANIFEST = [
|
|
|
369
530
|
},
|
|
370
531
|
schema: BUILTIN_TEMPLATE_SCHEMAS.chapterTitle
|
|
371
532
|
},
|
|
372
|
-
{
|
|
373
|
-
"label": "Focus cards",
|
|
374
|
-
"description": "Two to four short phrases fade in sequentially on black; no boxes or heading.",
|
|
375
|
-
"usesGlobalTextEffect": false,
|
|
376
|
-
"usesGlobalTransition": false,
|
|
377
|
-
"usesGlobalBackgroundEffect": false,
|
|
378
|
-
"textCanvas": "tight",
|
|
379
|
-
"id": "focusCards",
|
|
380
|
-
"family": "Explainers",
|
|
381
|
-
"jobs": [
|
|
382
|
-
"setup",
|
|
383
|
-
"proof"
|
|
384
|
-
],
|
|
385
|
-
"register": "card-led",
|
|
386
|
-
"useWhen": "Two to four short parallel points support an explanation. ",
|
|
387
|
-
"avoidWhen": "The points require an order, long paragraphs, numerical data or additional images to make sense.",
|
|
388
|
-
"minDuration": 4,
|
|
389
|
-
"preferredDuration": 5,
|
|
390
|
-
"timing": {
|
|
391
|
-
"contentFields": [
|
|
392
|
-
"items"
|
|
393
|
-
],
|
|
394
|
-
"contentUnit": "items",
|
|
395
|
-
"revealSeconds": 2.4,
|
|
396
|
-
"holdSeconds": 1.8,
|
|
397
|
-
"exitSeconds": 0
|
|
398
|
-
},
|
|
399
|
-
schema: BUILTIN_TEMPLATE_SCHEMAS.focusCards
|
|
400
|
-
},
|
|
401
533
|
{
|
|
402
534
|
"label": "Timeline",
|
|
403
|
-
"description": "Three to five events on a fine continuous line
|
|
535
|
+
"description": "Three to five events on a fine continuous line over relevant media or black; without dates.",
|
|
404
536
|
"usesGlobalTextEffect": false,
|
|
405
537
|
"usesGlobalTransition": false,
|
|
406
538
|
"usesGlobalBackgroundEffect": false,
|
|
@@ -458,7 +590,7 @@ var BUILTIN_TEMPLATE_MANIFEST = [
|
|
|
458
590
|
},
|
|
459
591
|
{
|
|
460
592
|
"label": "Comparison",
|
|
461
|
-
"description": "Two short statements with equal weight
|
|
593
|
+
"description": "Two short statements with equal weight over relevant media or black, side by side or stacked in portrait.",
|
|
462
594
|
"usesGlobalTextEffect": false,
|
|
463
595
|
"usesGlobalTransition": false,
|
|
464
596
|
"usesGlobalBackgroundEffect": false,
|
|
@@ -489,7 +621,7 @@ var BUILTIN_TEMPLATE_MANIFEST = [
|
|
|
489
621
|
},
|
|
490
622
|
{
|
|
491
623
|
"label": "Quote",
|
|
492
|
-
"description": "A short exact quotation with a legible attribution
|
|
624
|
+
"description": "A short exact quotation with a legible attribution over relevant media or black.",
|
|
493
625
|
"usesGlobalTextEffect": false,
|
|
494
626
|
"usesGlobalTransition": false,
|
|
495
627
|
"usesGlobalBackgroundEffect": false,
|
|
@@ -518,7 +650,7 @@ var BUILTIN_TEMPLATE_MANIFEST = [
|
|
|
518
650
|
},
|
|
519
651
|
{
|
|
520
652
|
"label": "Key figure",
|
|
521
|
-
"description": "One supplied figure with one short label
|
|
653
|
+
"description": "One supplied figure with one short label over relevant media or black.",
|
|
522
654
|
"usesGlobalTextEffect": false,
|
|
523
655
|
"usesGlobalTransition": false,
|
|
524
656
|
"usesGlobalBackgroundEffect": false,
|
|
@@ -114,15 +114,15 @@ function buildVideoUserPrompt(input, openingDurationSec = 0) {
|
|
|
114
114
|
"Add that scene before resolving any stock or supplied asset. Resolve media as part of each complete later body scene."
|
|
115
115
|
],
|
|
116
116
|
"Use only claims supported by the factual basis permitted by the trusted system prompt.",
|
|
117
|
-
"
|
|
117
|
+
"Develop the requested answer within the duration: preserve its mechanism, essential actions, story resolution or punchline. A short prompt can need several distinct visual beats; input length is not the answer length.",
|
|
118
118
|
"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.",
|
|
119
119
|
"When selecting claims from the raw input, preserve their exact wording and numbers. Preserve qualifiers, units, denominators, ranges, and comparison direction; for example, do not shorten 4.8 out of 5 to 4.8.",
|
|
120
|
-
"Choose the scene count from the
|
|
120
|
+
"Choose the scene count from the requested intent, visual progression and duration budget. A joke can be brief; a practical sequence or imaginative story may need more development. Do not stop while an essential step or payoff is missing.",
|
|
121
121
|
"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.",
|
|
122
122
|
"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.",
|
|
123
|
-
"
|
|
124
|
-
"Emit exactly one final scene.add with placement closer.
|
|
125
|
-
"
|
|
123
|
+
"Before plan.complete, check that the answer fulfills the actual request. Do not mistake a hook and a single supporting statement for a complete explanation, or explain a joke after its punchline.",
|
|
124
|
+
"Emit exactly one final scene.add with placement closer. Land the requested ending without repeating the opening or implying another scene follows.",
|
|
125
|
+
"Reuse the same suitable template when it serves successive beats. Vary the subject action, shot scale, perspective or purposeful detail, not the template merely for variety.",
|
|
126
126
|
"Never add filler to satisfy a count or diversity target.",
|
|
127
127
|
input.suppliedMedia?.length ? input.opening === false ? "Select zero or more relevant opaque supplied-media references for visible scenes. Never invent or transform a reference. Only emit mediaKeyword when the trusted system catalog explicitly exposes it. Never invent mediaUrl or mediaPoster." : "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." : input.opening === false ? "No supplied media URL is available. Use asset-free templates unless the trusted system catalog explicitly permits host-resolved media intent, which may begin on the first scene. Only emit mediaKeyword when the trusted system catalog explicitly exposes it. 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.",
|
|
128
128
|
"",
|
|
@@ -691,7 +691,7 @@ function createVideo(rawInput, options) {
|
|
|
691
691
|
position
|
|
692
692
|
}));
|
|
693
693
|
}
|
|
694
|
-
const systemPrompt = options.systemPrompt ?? (await import("./system-prompt-
|
|
694
|
+
const systemPrompt = options.systemPrompt ?? (await import("./system-prompt-AG26KJAA.js")).createVideoSystemPrompt(input.knowledgeMode);
|
|
695
695
|
const context = { request, systemPrompt, userPrompt, initialConfig, signal: controller.signal };
|
|
696
696
|
attachGenerationLifecycleSink(context, lifecycle);
|
|
697
697
|
for await (const untrustedPart of options.generate(context)) {
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-77VY4O7A.js";
|
|
7
7
|
import {
|
|
8
8
|
resolveMediaType
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-224QNWRA.js";
|
|
10
10
|
import {
|
|
11
11
|
useExternalVideoBackdrop
|
|
12
12
|
} from "./chunk-TVIU23OM.js";
|
|
@@ -163,17 +163,22 @@ var SceneBackground = ({
|
|
|
163
163
|
onError: () => setMediaPaint("failed")
|
|
164
164
|
}
|
|
165
165
|
) : /* @__PURE__ */ jsx(
|
|
166
|
-
"
|
|
166
|
+
"img",
|
|
167
167
|
{
|
|
168
|
+
src: mediaUrl,
|
|
169
|
+
alt: "",
|
|
170
|
+
"aria-hidden": "true",
|
|
171
|
+
draggable: false,
|
|
168
172
|
"data-media-position": mediaPosition,
|
|
169
173
|
style: {
|
|
170
174
|
position: "absolute",
|
|
171
175
|
inset: 0,
|
|
172
176
|
transform: bgTransform.transform,
|
|
173
177
|
transformOrigin: bgTransform.transformOrigin,
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
width: "100%",
|
|
179
|
+
height: "100%",
|
|
180
|
+
objectFit: "cover",
|
|
181
|
+
objectPosition: resolvedPosition
|
|
177
182
|
}
|
|
178
183
|
}
|
|
179
184
|
)),
|
|
@@ -195,14 +200,7 @@ var SceneBackground = ({
|
|
|
195
200
|
] });
|
|
196
201
|
};
|
|
197
202
|
|
|
198
|
-
// src/visual-system/scene-templates/cinema-media.tsx
|
|
199
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
200
|
-
function MediaScene({ variables, style, width, height, progress, sceneDuration, isPlaying }) {
|
|
201
|
-
return /* @__PURE__ */ jsx2("div", { "data-template": "cinemaMedia", style: { width, height, position: "relative", overflow: "hidden" }, children: /* @__PURE__ */ jsx2(SceneBackground, { style, width, height, progress, sceneDuration, ...getMediaBackgroundProps(variables), mediaTreatment: "none", backgroundEffect: "none", isPlaying }) });
|
|
202
|
-
}
|
|
203
|
-
var MediaSceneTemplate = MediaScene;
|
|
204
|
-
|
|
205
203
|
export {
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
getMediaBackgroundProps,
|
|
205
|
+
SceneBackground
|
|
208
206
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
limitsConcurrentVideoDecoders,
|
|
3
3
|
resolveMediaType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-224QNWRA.js";
|
|
5
5
|
import {
|
|
6
6
|
ExternalVideoBackdropProvider,
|
|
7
7
|
resolveDensity
|
|
@@ -21,10 +21,12 @@ import { createContext, useContext, useEffect, useRef } from "react";
|
|
|
21
21
|
import { jsx } from "react/jsx-runtime";
|
|
22
22
|
var MountedReadinessContext = createContext(void 0);
|
|
23
23
|
var sceneReadinessKey = (scene) => `${scene.id}\0${String(scene.variables.mediaUrl || "")}`;
|
|
24
|
-
function MountedSceneReadiness({ scene, playing, fallback = false }) {
|
|
24
|
+
function MountedSceneReadiness({ scene, playing, fallback = false, onFailure }) {
|
|
25
25
|
const marker = useRef(null);
|
|
26
26
|
const report = useContext(MountedReadinessContext);
|
|
27
27
|
const key = sceneReadinessKey(scene);
|
|
28
|
+
const onFailureRef = useRef(onFailure);
|
|
29
|
+
onFailureRef.current = onFailure;
|
|
28
30
|
useEffect(() => {
|
|
29
31
|
if (!report || !playing) return;
|
|
30
32
|
let stopped = false;
|
|
@@ -35,13 +37,14 @@ function MountedSceneReadiness({ scene, playing, fallback = false }) {
|
|
|
35
37
|
const finish = (error, actualVideoFrame = false) => {
|
|
36
38
|
if (!stopped) {
|
|
37
39
|
stopped = true;
|
|
38
|
-
|
|
40
|
+
if (error && onFailureRef.current) onFailureRef.current();
|
|
41
|
+
else report(key, error, actualVideoFrame);
|
|
39
42
|
}
|
|
40
43
|
};
|
|
41
44
|
const check = () => {
|
|
42
45
|
if (stopped) return;
|
|
43
46
|
const root = marker.current?.closest("[data-video-frame]");
|
|
44
|
-
if (fallback && root?.querySelector("[data-scene-fallback]")) {
|
|
47
|
+
if (fallback && root?.querySelector("[data-scene-fallback]") && !root.querySelector("[data-template-loading]") && document.fonts?.status !== "loading") {
|
|
45
48
|
finish();
|
|
46
49
|
return;
|
|
47
50
|
}
|
|
@@ -132,6 +135,7 @@ import {
|
|
|
132
135
|
lazy,
|
|
133
136
|
Suspense,
|
|
134
137
|
useState,
|
|
138
|
+
useCallback,
|
|
135
139
|
useEffect as useEffect2,
|
|
136
140
|
useSyncExternalStore
|
|
137
141
|
} from "react";
|
|
@@ -269,7 +273,9 @@ function SceneLayer({
|
|
|
269
273
|
zIndex,
|
|
270
274
|
externalVideoBackdrop
|
|
271
275
|
}) {
|
|
272
|
-
const
|
|
276
|
+
const mediaFailed = externalVideoBackdrop === "fallback";
|
|
277
|
+
const recoveryTitle = mediaFailed && range.scene.templateId === "cinemaMedia" && typeof range.scene.variables.fallbackText === "string" ? range.scene.variables.fallbackText : void 0;
|
|
278
|
+
const template = kit.getTemplate(recoveryTitle ? "chapterTitle" : range.scene.templateId);
|
|
273
279
|
const duration = range.end - range.start;
|
|
274
280
|
return /* @__PURE__ */ jsx2(
|
|
275
281
|
ExternalVideoBackdropProvider,
|
|
@@ -281,6 +287,7 @@ function SceneLayer({
|
|
|
281
287
|
"div",
|
|
282
288
|
{
|
|
283
289
|
"data-scene-layer": layer,
|
|
290
|
+
"data-scene-fallback": mediaFailed ? "true" : void 0,
|
|
284
291
|
"data-layer-scene-id": range.scene.id,
|
|
285
292
|
"data-layer-template-id": range.scene.templateId,
|
|
286
293
|
"aria-hidden": interactive ? void 0 : true,
|
|
@@ -308,7 +315,9 @@ function SceneLayer({
|
|
|
308
315
|
createElement(template.component, {
|
|
309
316
|
variables: {
|
|
310
317
|
...template.defaults ?? getTemplateDefaults(template.schema),
|
|
311
|
-
...range.scene.variables
|
|
318
|
+
...range.scene.variables,
|
|
319
|
+
...mediaFailed ? { mediaUrl: "", mediaPoster: "", mediaType: "gradient" } : {},
|
|
320
|
+
...recoveryTitle ? { title: recoveryTitle } : {}
|
|
312
321
|
},
|
|
313
322
|
style: config.style,
|
|
314
323
|
progress,
|
|
@@ -344,7 +353,18 @@ function VideoFrame({
|
|
|
344
353
|
className,
|
|
345
354
|
style
|
|
346
355
|
}) {
|
|
347
|
-
const [
|
|
356
|
+
const [failedMedia, setFailedMedia] = useState(() => /* @__PURE__ */ new Set());
|
|
357
|
+
const markMediaFailed = useCallback((key) => {
|
|
358
|
+
if (!key || !config.scenes.some((scene) => sceneReadinessKey(scene) === key)) return;
|
|
359
|
+
setFailedMedia((previous) => previous.has(key) ? previous : /* @__PURE__ */ new Set([...previous, key]));
|
|
360
|
+
}, [config.scenes]);
|
|
361
|
+
useEffect2(() => {
|
|
362
|
+
const currentKeys = new Set(config.scenes.map(sceneReadinessKey));
|
|
363
|
+
setFailedMedia((previous) => {
|
|
364
|
+
const retained = new Set([...previous].filter((key) => currentKeys.has(key)));
|
|
365
|
+
return retained.size === previous.size ? previous : retained;
|
|
366
|
+
});
|
|
367
|
+
}, [config.scenes]);
|
|
348
368
|
const [readyPersistentVideo, setReadyPersistentVideo] = useState();
|
|
349
369
|
const decoderConstrainedDevice = useDecoderConstraint();
|
|
350
370
|
const timeline = resolveVideoTimeline(config);
|
|
@@ -422,7 +442,8 @@ function VideoFrame({
|
|
|
422
442
|
mediaPosition: String(posterPreparationRange.scene.variables.mediaPosition || "center"),
|
|
423
443
|
backgroundEffect: posterPreparationRange.scene.backgroundEffect ?? config.style.defaultBackgroundEffect
|
|
424
444
|
} : void 0;
|
|
425
|
-
const
|
|
445
|
+
const activeMediaFailed = failedMedia.has(sceneReadinessKey(active.scene));
|
|
446
|
+
const persistentVideoFailed = persistentVideoKey !== void 0 && failedMedia.has(persistentVideoKey);
|
|
426
447
|
const persistentVideoReady = persistentVideoRange !== void 0 && (String(persistentVideoRange.scene.variables.mediaPoster || "") !== "" || readyPersistentVideo === persistentVideoKey);
|
|
427
448
|
const persistentVideoMode = persistentVideoFailed ? "fallback" : persistentVideoReady ? "ready" : "pending";
|
|
428
449
|
const mountingNext = Boolean(
|
|
@@ -442,6 +463,12 @@ function VideoFrame({
|
|
|
442
463
|
return /* @__PURE__ */ jsxs(
|
|
443
464
|
"div",
|
|
444
465
|
{
|
|
466
|
+
onErrorCapture: (event) => {
|
|
467
|
+
const target = event.target;
|
|
468
|
+
if ((target instanceof HTMLVideoElement || target instanceof HTMLImageElement) && target.getAttribute("src") === active.scene.variables.mediaUrl && supportsExternalVideoBackdrop(activeTemplate) && (target.closest("[data-layer-scene-id]")?.getAttribute("data-layer-scene-id") === active.scene.id || target.closest("[data-persistent-video-scene-id]")?.getAttribute("data-persistent-video-scene-id") === active.scene.id)) {
|
|
469
|
+
markMediaFailed(sceneReadinessKey(active.scene));
|
|
470
|
+
}
|
|
471
|
+
},
|
|
445
472
|
"data-video-frame": "ready",
|
|
446
473
|
"data-scene-id": active.scene.id,
|
|
447
474
|
"data-template-id": active.scene.templateId,
|
|
@@ -455,7 +482,15 @@ function VideoFrame({
|
|
|
455
482
|
...style
|
|
456
483
|
},
|
|
457
484
|
children: [
|
|
458
|
-
/* @__PURE__ */ jsx2(
|
|
485
|
+
/* @__PURE__ */ jsx2(
|
|
486
|
+
MountedSceneReadiness,
|
|
487
|
+
{
|
|
488
|
+
scene: active.scene,
|
|
489
|
+
playing,
|
|
490
|
+
fallback: activeMediaFailed,
|
|
491
|
+
onFailure: sceneHasBackdrop(active) && supportsExternalVideoBackdrop(activeTemplate) && !activeMediaFailed ? () => markMediaFailed(sceneReadinessKey(active.scene)) : void 0
|
|
492
|
+
}
|
|
493
|
+
),
|
|
459
494
|
preparedReadinessRange && /* @__PURE__ */ jsx2(PreparedSceneReadiness, { scene: preparedReadinessRange.scene }),
|
|
460
495
|
/* @__PURE__ */ jsxs(
|
|
461
496
|
"div",
|
|
@@ -530,7 +565,7 @@ function VideoFrame({
|
|
|
530
565
|
opacity: decoderConstrainedTransition ? blendProgress : 0
|
|
531
566
|
} : void 0,
|
|
532
567
|
onReady: () => setReadyPersistentVideo(persistentVideoKey),
|
|
533
|
-
onError: () =>
|
|
568
|
+
onError: () => markMediaFailed(persistentVideoKey)
|
|
534
569
|
}
|
|
535
570
|
) })
|
|
536
571
|
}
|
|
@@ -554,7 +589,7 @@ function VideoFrame({
|
|
|
554
589
|
opacity: 1 - blendProgress,
|
|
555
590
|
interactive: true,
|
|
556
591
|
zIndex: 1,
|
|
557
|
-
externalVideoBackdrop: persistentVideoRange?.scene.id === active.scene.id ? persistentVideoMode : false
|
|
592
|
+
externalVideoBackdrop: activeMediaFailed ? "fallback" : persistentVideoRange?.scene.id === active.scene.id ? persistentVideoMode : false
|
|
558
593
|
},
|
|
559
594
|
active.scene.id
|
|
560
595
|
),
|
|
@@ -598,7 +633,7 @@ function VideoFrame({
|
|
|
598
633
|
opacity: 1,
|
|
599
634
|
interactive: true,
|
|
600
635
|
zIndex: 1,
|
|
601
|
-
externalVideoBackdrop: persistentVideoRange?.scene.id === active.scene.id ? persistentVideoMode : false
|
|
636
|
+
externalVideoBackdrop: activeMediaFailed ? "fallback" : persistentVideoRange?.scene.id === active.scene.id ? persistentVideoMode : false
|
|
602
637
|
},
|
|
603
638
|
active.scene.id
|
|
604
639
|
)
|