@vanillaskyai/video 0.7.1 → 0.8.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 +63 -0
- package/PUBLIC-API.md +83 -79
- package/README.md +20 -15
- package/dist/assets/vanillasky-logo.svg +151 -0
- package/dist/{builtin-server-KB7FKF6A.js → builtin-server-CUYPIDE7.js} +2 -2
- package/dist/check-runtime.js +1 -1
- package/dist/{chunk-2PYO6VAC.js → chunk-2DOLF4QN.js} +1 -43
- package/dist/{chunk-GAIOHGNR.js → chunk-2OKB27TG.js} +42 -45
- package/dist/{chunk-K746NUIP.js → chunk-2USVB3CY.js} +80 -29
- package/dist/{chunk-RE4IMWJR.js → chunk-3VRMKFM7.js} +87 -14
- package/dist/{chunk-JNN3EYVP.js → chunk-4UNKZEAT.js} +46 -46
- package/dist/{chunk-2XT4MZ76.js → chunk-APQKY6P3.js} +36 -3
- package/dist/{chunk-LLPMVDJZ.js → chunk-L7QGGKJ2.js} +69 -38
- package/dist/{chunk-RGF452LL.js → chunk-OWBT45EN.js} +1 -1
- package/dist/{chunk-LKBZX7GV.js → chunk-PP3MCPN4.js} +4 -4
- package/dist/chunk-ZD2VTUYR.js +28 -0
- package/dist/cli.js +131 -24
- package/dist/{compose-video-PD6LKKRK.js → compose-video-2NFH4DZY.js} +3 -3
- package/dist/{events-B6qS1Lsb.d.ts → events-BQ6z264n.d.ts} +1 -1
- package/dist/index.d.ts +5 -67
- package/dist/index.js +2 -4
- package/dist/{kit-8g46H2RZ.d.ts → kit-tQnCPMOM.d.ts} +1 -1
- package/dist/react.d.ts +33 -53
- package/dist/react.js +982 -648
- package/dist/server.d.ts +11 -13
- package/dist/server.js +170 -81
- package/dist/template-catalog.js +1 -1
- package/dist/templates.d.ts +3 -3
- package/dist/test.d.ts +2 -2
- package/dist/test.js +3 -3
- package/dist/{text-stream-ROTNGSD4.js → text-stream-54LXABJW.js} +1 -1
- package/dist/{types-2wHBqtg8.d.ts → types-CEh9eUFu.d.ts} +1 -1
- package/dist/{types-DrABlRa7.d.ts → types-DWFO6qca.d.ts} +1 -1
- package/docs/agent-integration.md +9 -3
- package/docs/architecture.md +8 -10
- package/docs/concepts.md +16 -40
- package/docs/custom-templates.md +27 -23
- package/docs/customization.md +23 -55
- package/docs/errors.md +58 -68
- package/docs/getting-started.md +21 -14
- package/docs/immersive-interface.md +87 -0
- package/docs/media-and-audio.md +2 -2
- package/docs/performance.md +69 -0
- package/docs/persistence.md +12 -27
- package/docs/production.md +2 -2
- package/docs/provider-integration.md +11 -5
- package/docs/reference/design-system.html +115 -0
- package/docs/reference/provider-adapters.md +37 -89
- package/docs/security.md +1 -1
- package/docs/streaming-protocol.md +2 -2
- package/examples/custom-template/README.md +6 -6
- package/package.json +6 -7
- package/registry/items/barChart.json +2 -2
- package/registry/items/bigNumber.json +2 -2
- package/registry/items/brandMessage.json +2 -2
- package/registry/items/cardList.json +2 -2
- package/registry/items/codeEditor.json +2 -2
- package/registry/items/ctaLogo.json +2 -2
- package/registry/items/ctaMedia.json +2 -2
- package/registry/items/incomingCall.json +2 -2
- package/registry/items/media.json +2 -2
- package/registry/items/milestone.json +2 -2
- package/registry/items/notification.json +2 -2
- package/registry/items/phoneMockup.json +2 -2
- package/registry/items/problemSolution.json +2 -2
- package/registry/items/progressRing.json +2 -2
- package/registry/items/promptInput.json +2 -2
- package/registry/items/reaction.json +2 -2
- package/registry/items/reviewStack.json +2 -2
- package/registry/items/steps.json +2 -2
- package/registry/items/terminal.json +2 -2
- package/registry/items/testimonial.json +2 -2
- package/registry/items/tripleStats.json +2 -2
- package/registry/items/tweet.json +2 -2
- package/registry/items/webMockup.json +2 -2
- package/starters/video-chat/.env.example +4 -2
- package/starters/video-chat/README.md +17 -5
- package/starters/video-chat/index.html +2 -1
- package/starters/video-chat/package.json +2 -4
- package/starters/video-chat/providers/speech.ts +20 -0
- package/starters/video-chat/providers/video.ts +66 -0
- package/starters/video-chat/providers.ts +3 -0
- package/starters/video-chat/server.ts +4 -80
- package/starters/video-chat/stock.ts +114 -99
- package/styles/video-chat.css +650 -246
- package/dist/chunk-SKRGRKHY.js +0 -142
- package/dist/state-DZcKuS32.d.ts +0 -3
- package/docs/branding-and-personalization.md +0 -87
- package/examples/custom-template/supplied-media.tsx +0 -92
package/dist/chunk-SKRGRKHY.js
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
checksumVideo,
|
|
3
|
-
createVideoEventFactory
|
|
4
|
-
} from "./chunk-2PYO6VAC.js";
|
|
5
|
-
import {
|
|
6
|
-
VIDEO_SCHEMA_VERSION
|
|
7
|
-
} from "./chunk-AOWSXU2K.js";
|
|
8
|
-
import {
|
|
9
|
-
getReadableSceneDuration
|
|
10
|
-
} from "./chunk-3O7OMMMF.js";
|
|
11
|
-
|
|
12
|
-
// src/protocol/scene-timeline.ts
|
|
13
|
-
function createQueue() {
|
|
14
|
-
const buffered = [];
|
|
15
|
-
const waiting = [];
|
|
16
|
-
let closed = false;
|
|
17
|
-
return {
|
|
18
|
-
push(value) {
|
|
19
|
-
const next = waiting.shift();
|
|
20
|
-
if (next) next({ value, done: false });
|
|
21
|
-
else buffered.push(value);
|
|
22
|
-
},
|
|
23
|
-
close() {
|
|
24
|
-
closed = true;
|
|
25
|
-
let next = waiting.shift();
|
|
26
|
-
while (next) {
|
|
27
|
-
next({ value: void 0, done: true });
|
|
28
|
-
next = waiting.shift();
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
iterable: {
|
|
32
|
-
[Symbol.asyncIterator]() {
|
|
33
|
-
return {
|
|
34
|
-
next() {
|
|
35
|
-
const buffer = buffered.shift();
|
|
36
|
-
if (buffer !== void 0) return Promise.resolve({ value: buffer, done: false });
|
|
37
|
-
if (closed) return Promise.resolve({ value: void 0, done: true });
|
|
38
|
-
return new Promise((resolve) => waiting.push(resolve));
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
var runCounter = 0;
|
|
46
|
-
function createSceneTimeline(options) {
|
|
47
|
-
const queue = createQueue();
|
|
48
|
-
const runId = options.runId ?? `composed-${runCounter += 1}`;
|
|
49
|
-
const events = createVideoEventFactory({ runId });
|
|
50
|
-
const orientation = options.orientation ?? "landscape";
|
|
51
|
-
const snapshot = {
|
|
52
|
-
schemaVersion: VIDEO_SCHEMA_VERSION,
|
|
53
|
-
orientation,
|
|
54
|
-
scenes: [],
|
|
55
|
-
style: options.style
|
|
56
|
-
};
|
|
57
|
-
let position = 0;
|
|
58
|
-
let finished = false;
|
|
59
|
-
const held = [];
|
|
60
|
-
let openForScenes = !options.awaitAudio;
|
|
61
|
-
const emit = (event) => {
|
|
62
|
-
if (finished) return;
|
|
63
|
-
queue.push(event);
|
|
64
|
-
};
|
|
65
|
-
emit(events.create("response.start", {
|
|
66
|
-
requestId: options.requestId ?? runId,
|
|
67
|
-
format: { orientation },
|
|
68
|
-
style: options.style
|
|
69
|
-
}));
|
|
70
|
-
if (options.audio) {
|
|
71
|
-
snapshot.audio = options.audio;
|
|
72
|
-
emit(events.create("audio.set", { audio: options.audio }));
|
|
73
|
-
}
|
|
74
|
-
const release = () => {
|
|
75
|
-
const pending = held.splice(0, held.length);
|
|
76
|
-
for (const scene of pending) {
|
|
77
|
-
snapshot.scenes.push(scene);
|
|
78
|
-
emit(events.create("scene.add", { scene, position: position++ }));
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
return {
|
|
82
|
-
stream: queue.iterable,
|
|
83
|
-
add(scene) {
|
|
84
|
-
if (finished) return;
|
|
85
|
-
if (!openForScenes) {
|
|
86
|
-
held.push(scene);
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
snapshot.scenes.push(scene);
|
|
90
|
-
emit(events.create("scene.add", { scene, position: position++ }));
|
|
91
|
-
},
|
|
92
|
-
setAudio(audio) {
|
|
93
|
-
if (finished || openForScenes) return;
|
|
94
|
-
if (audio) {
|
|
95
|
-
snapshot.audio = audio;
|
|
96
|
-
emit(events.create("audio.set", { audio }));
|
|
97
|
-
}
|
|
98
|
-
openForScenes = true;
|
|
99
|
-
release();
|
|
100
|
-
},
|
|
101
|
-
complete() {
|
|
102
|
-
if (finished) return;
|
|
103
|
-
if (!openForScenes) {
|
|
104
|
-
openForScenes = true;
|
|
105
|
-
release();
|
|
106
|
-
}
|
|
107
|
-
emit(events.create("response.complete", {
|
|
108
|
-
finishReason: "stop",
|
|
109
|
-
snapshot,
|
|
110
|
-
checksum: checksumVideo(snapshot)
|
|
111
|
-
}));
|
|
112
|
-
finished = true;
|
|
113
|
-
queue.close();
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// src/protocol/scene-duration.ts
|
|
119
|
-
var NARRATION_WORDS_PER_SECOND = 2.6;
|
|
120
|
-
var NARRATION_TAIL_SECONDS = 0.6;
|
|
121
|
-
function getSceneDurationBounds(scene, metadata) {
|
|
122
|
-
return {
|
|
123
|
-
minimum: Math.max(1e-3, metadata?.minDuration ?? 1),
|
|
124
|
-
readable: getReadableSceneDuration(scene, metadata)
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
function getSpokenDuration(narration) {
|
|
128
|
-
const words = narration.trim().split(/\s+/u).filter(Boolean).length;
|
|
129
|
-
if (words === 0) return 0;
|
|
130
|
-
return words / NARRATION_WORDS_PER_SECOND + NARRATION_TAIL_SECONDS;
|
|
131
|
-
}
|
|
132
|
-
function getSceneDuration(scene, metadata) {
|
|
133
|
-
const { readable } = getSceneDurationBounds(scene, metadata);
|
|
134
|
-
return Math.max(readable, scene.narration ? getSpokenDuration(scene.narration) : 0);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
export {
|
|
138
|
-
createSceneTimeline,
|
|
139
|
-
getSceneDurationBounds,
|
|
140
|
-
getSpokenDuration,
|
|
141
|
-
getSceneDuration
|
|
142
|
-
};
|
package/dist/state-DZcKuS32.d.ts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
[← Documentation home](../README.md) · [Previous: Prompt and conversation input](prompt-and-input.md) · [Next: Media and audio →](media-and-audio.md)
|
|
2
|
-
|
|
3
|
-
# Branding and personalization
|
|
4
|
-
|
|
5
|
-
Brand values style the whole response. Personalization shapes who the story is for.
|
|
6
|
-
|
|
7
|
-
## Background: standard, preset, or custom
|
|
8
|
-
|
|
9
|
-
Do nothing to use the standard `cosmic` background:
|
|
10
|
-
|
|
11
|
-
```ts
|
|
12
|
-
video.generate({ input });
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Choose a curated gradient or solid by name when the standard does not fit:
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
video.generate({
|
|
19
|
-
input,
|
|
20
|
-
brand: { background: "twilight" },
|
|
21
|
-
});
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Curated gradients are `cosmic`, `horizon`, `twilight`, `meadow`, `velvet`,
|
|
25
|
-
`flamingo`, `peach`, and `saffron`. Curated solids are `black`, `midnight`,
|
|
26
|
-
`aubergine`, `coal`, and `navy`.
|
|
27
|
-
|
|
28
|
-
Use exact colors only when a real brand or campaign requires them:
|
|
29
|
-
|
|
30
|
-
```ts
|
|
31
|
-
brand: { background: { colors: ["#112233", "#334455"] } } // gradient
|
|
32
|
-
brand: { background: { color: "#070B20" } } // solid
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
These choices set the background colors used by every trusted gradient-backed
|
|
36
|
-
template and by the automatic generation cover. Templates own their
|
|
37
|
-
composition and type treatment, so there is no separate visual-preset choice.
|
|
38
|
-
|
|
39
|
-
## Semantic brand tokens
|
|
40
|
-
|
|
41
|
-
Most applications can stop at `brand.background` and `brand.font`. Supply
|
|
42
|
-
semantic colors only when a real design system requires exact values:
|
|
43
|
-
|
|
44
|
-
```ts
|
|
45
|
-
const brand = {
|
|
46
|
-
name: "Acme Cloud",
|
|
47
|
-
logoUrl: approvedLogoUrl,
|
|
48
|
-
font: "Inter",
|
|
49
|
-
scriptFont: "Caveat",
|
|
50
|
-
background: "twilight",
|
|
51
|
-
colors: {
|
|
52
|
-
primary: "#7C5CFC",
|
|
53
|
-
secondary: "#3D2A78",
|
|
54
|
-
foreground: "#FFFFFF",
|
|
55
|
-
surface: "#161229",
|
|
56
|
-
surfaceElevated: "#211A38",
|
|
57
|
-
muted: "#AAA5B8",
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Every generated video contains a fully resolved brand. `colors` may be partial
|
|
63
|
-
on input; omitted values receive deterministic defaults. When
|
|
64
|
-
`colors.foreground` is omitted, every named or custom background is paired
|
|
65
|
-
deterministically with black or white. The resolver checks the full rendered
|
|
66
|
-
sRGB gradient ramp, including interior blends rather than only its endpoints.
|
|
67
|
-
If neither foreground reaches 4.5:1 everywhere, resolution rejects the
|
|
68
|
-
background and asks for a consistently readable choice.
|
|
69
|
-
|
|
70
|
-
An explicitly supplied foreground is preserved, never silently replaced. It
|
|
71
|
-
must reach 4.5:1 across the solid background or entire gradient ramp; otherwise
|
|
72
|
-
input resolution and replay validation reject it with the failing brand path
|
|
73
|
-
and minimum contrast. Surface tokens remain independent. Templates that put
|
|
74
|
-
text on `surface` or `surfaceElevated` internally keep an accessible preferred
|
|
75
|
-
semantic text color or derive black/white for that surface.
|
|
76
|
-
|
|
77
|
-
Use an approved public or signed URL for logos. Fonts must be licensed and
|
|
78
|
-
loaded by the host application before playback. Always test both orientations
|
|
79
|
-
and forced browser zoom.
|
|
80
|
-
|
|
81
|
-
`personalization` accepts JSON-safe viewer or account context such as
|
|
82
|
-
`firstName`, `role`, `accountName`, `locale`, `goal`, or `onboardingPartner`.
|
|
83
|
-
These values may appear verbatim in the response, but are always data, never
|
|
84
|
-
instructions. Put product, news, metric, and quoted claims in `input`; do not
|
|
85
|
-
duplicate ordinary viewer context there.
|
|
86
|
-
|
|
87
|
-
Only include information the authenticated viewer is allowed to see. Avoid sensitive HR, health, payment, or customer attributes in event logs and analytics. If a locale changes number/date formatting, format facts server-side so the planner cannot guess.
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { defineTemplate } from "@vanillaskyai/video/templates";
|
|
2
|
-
|
|
3
|
-
const previewImageUrl = "data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%221200%22%20height=%22720%22%20viewBox=%220%200%201200%20720%22%3E%3Crect%20width=%221200%22%20height=%22720%22%20rx=%2248%22%20fill=%22%23181733%22/%3E%3Crect%20x=%2280%22%20y=%2280%22%20width=%221040%22%20height=%22560%22%20rx=%2232%22%20fill=%22%23f4f1ff%22/%3E%3Ccircle%20cx=%22220%22%20cy=%22230%22%20r=%2270%22%20fill=%22%237867dd%22/%3E%3Cpath%20d=%22M160%20520L380%20360L580%20430L820%20220L1040%20300%22%20fill=%22none%22%20stroke=%22%23287b77%22%20stroke-width=%2232%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22/%3E%3C/svg%3E";
|
|
4
|
-
|
|
5
|
-
export const template = defineTemplate({
|
|
6
|
-
id: "supplied-media",
|
|
7
|
-
label: "Supplied media",
|
|
8
|
-
description: "An application-supplied screenshot with a grounded caption.",
|
|
9
|
-
useWhen: "Use when a supplied product image is the strongest evidence for the answer.",
|
|
10
|
-
avoidWhen: "Avoid when no approved image was supplied or text and data communicate the point more clearly.",
|
|
11
|
-
schema: {
|
|
12
|
-
type: "object",
|
|
13
|
-
properties: {
|
|
14
|
-
imageUrl: {
|
|
15
|
-
type: "string",
|
|
16
|
-
format: "supplied-image",
|
|
17
|
-
title: "Supplied image",
|
|
18
|
-
description: "The URL of an image present in VideoInput.suppliedMedia.",
|
|
19
|
-
default: previewImageUrl,
|
|
20
|
-
},
|
|
21
|
-
headline: {
|
|
22
|
-
type: "string",
|
|
23
|
-
title: "Headline",
|
|
24
|
-
minLength: 1,
|
|
25
|
-
maxLength: 72,
|
|
26
|
-
default: "See the change in context.",
|
|
27
|
-
},
|
|
28
|
-
caption: {
|
|
29
|
-
type: "string",
|
|
30
|
-
title: "Caption",
|
|
31
|
-
minLength: 1,
|
|
32
|
-
maxLength: 120,
|
|
33
|
-
default: "The dashboard reflects the grounded result described in the answer.",
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
required: ["imageUrl", "headline", "caption"],
|
|
37
|
-
additionalProperties: false,
|
|
38
|
-
} as const,
|
|
39
|
-
examples: [{
|
|
40
|
-
name: "Product dashboard",
|
|
41
|
-
variables: {
|
|
42
|
-
imageUrl: previewImageUrl,
|
|
43
|
-
headline: "See the change in context.",
|
|
44
|
-
caption: "The dashboard reflects the grounded result described in the answer.",
|
|
45
|
-
},
|
|
46
|
-
}],
|
|
47
|
-
minDuration: 4,
|
|
48
|
-
preferredDuration: 6,
|
|
49
|
-
component: ({ variables, progress, width, height, safeZone }) => {
|
|
50
|
-
const isPortrait = height >= width;
|
|
51
|
-
const reveal = Math.max(0, Math.min(1, progress * 1.7));
|
|
52
|
-
|
|
53
|
-
return <section style={{
|
|
54
|
-
boxSizing: "border-box",
|
|
55
|
-
width,
|
|
56
|
-
height,
|
|
57
|
-
padding: `${safeZone.top}px ${safeZone.right}px ${safeZone.bottom}px ${safeZone.left}px`,
|
|
58
|
-
display: "grid",
|
|
59
|
-
gridTemplateColumns: isPortrait ? "1fr" : "minmax(0, 1.1fr) minmax(320px, 0.9fr)",
|
|
60
|
-
alignContent: "center",
|
|
61
|
-
alignItems: "center",
|
|
62
|
-
gap: isPortrait ? 44 : 64,
|
|
63
|
-
overflow: "hidden",
|
|
64
|
-
color: "#15152b",
|
|
65
|
-
background: "linear-gradient(145deg, #f4f1ff, #dfe7ff)",
|
|
66
|
-
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif",
|
|
67
|
-
}}>
|
|
68
|
-
<img
|
|
69
|
-
src={variables.imageUrl}
|
|
70
|
-
alt=""
|
|
71
|
-
style={{
|
|
72
|
-
display: "block",
|
|
73
|
-
width: "100%",
|
|
74
|
-
maxHeight: isPortrait ? height * 0.48 : height * 0.68,
|
|
75
|
-
objectFit: "cover",
|
|
76
|
-
borderRadius: 28,
|
|
77
|
-
boxShadow: "0 28px 80px rgba(28, 34, 75, 0.24)",
|
|
78
|
-
opacity: reveal,
|
|
79
|
-
transform: `scale(${0.96 + reveal * 0.04})`,
|
|
80
|
-
}}
|
|
81
|
-
/>
|
|
82
|
-
<div style={{ opacity: reveal }}>
|
|
83
|
-
<h1 style={{ margin: 0, fontSize: isPortrait ? 58 : 70, lineHeight: 0.98, letterSpacing: "-0.045em" }}>
|
|
84
|
-
{variables.headline}
|
|
85
|
-
</h1>
|
|
86
|
-
<p style={{ margin: "24px 0 0", fontSize: isPortrait ? 25 : 28, lineHeight: 1.4 }}>
|
|
87
|
-
{variables.caption}
|
|
88
|
-
</p>
|
|
89
|
-
</div>
|
|
90
|
-
</section>;
|
|
91
|
-
},
|
|
92
|
-
});
|