@vanillaskyai/video 0.10.23 → 0.11.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 +69 -0
- package/PUBLIC-API.md +47 -438
- package/README.md +53 -97
- package/dist/builtin-metadata-OT6V7TB4.js +8 -0
- package/dist/{chapter-title-2JVDU62E.js → chapter-title-2RCXX7SN.js} +1 -2
- package/dist/{chunk-5BSJLT6H.js → chunk-2WIETEL7.js} +16 -29
- package/dist/{chunk-3O7OMMMF.js → chunk-35K6IKB2.js} +3 -3
- package/dist/{chunk-PDQFQIQW.js → chunk-3EQ6PVWL.js} +1 -1
- package/dist/chunk-4G4JBMCM.js +37 -0
- package/dist/{chunk-7AA2JWHZ.js → chunk-5DOQTIMD.js} +6 -6
- package/dist/chunk-666HGTVZ.js +41 -0
- package/dist/{chunk-7M56IUUX.js → chunk-6Z3ID54H.js} +0 -18
- package/dist/chunk-AUN4S3YW.js +50 -0
- package/dist/chunk-HIQM4J3U.js +30 -0
- package/dist/chunk-ISWQ6T5X.js +36 -0
- package/dist/{chunk-224QNWRA.js → chunk-K5J7ESRO.js} +1 -10
- package/dist/chunk-NM4CXXZY.js +25 -0
- package/dist/{chunk-44WND2VP.js → chunk-RFXHLLYU.js} +34 -62
- package/dist/{chunk-RXTN2CW6.js → chunk-Z3DLSLAJ.js} +1 -1
- package/dist/cinema-media-YZ2UANJG.js +365 -0
- package/dist/cli.js +154 -1748
- package/dist/{compose-video-BH5K6XWT.js → compose-video-RSLI4CVP.js} +4 -4
- package/dist/{events-B4YCc4vc.d.ts → events-BZAfl0Dm.d.ts} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -6
- package/dist/preload-media-23JXUFCF.js +77 -0
- package/dist/react.d.ts +39 -15
- package/dist/react.js +1355 -740
- package/dist/scene-validation-SGLLLFY5.js +9 -0
- package/dist/server.d.ts +67 -117
- package/dist/server.js +296 -626
- package/dist/test.d.ts +2 -2
- package/dist/test.js +21 -21
- package/dist/{text-stream-LD364KBI.js → text-stream-SOVLYR2L.js} +2 -2
- package/dist/{types-BqB8zC9u.d.ts → types-CG-kPI81.d.ts} +3 -1
- package/dist/{types-DdZw4GRQ.d.ts → types-ht-Zw3Wv.d.ts} +1 -1
- package/docs/agent-integration.md +19 -64
- package/docs/architecture.md +80 -106
- package/docs/customization.md +49 -66
- package/docs/development.md +18 -17
- package/docs/errors.md +4 -4
- package/docs/getting-started.md +74 -93
- package/docs/media-and-audio.md +9 -7
- package/docs/performance.md +11 -6
- package/docs/persistence.md +3 -7
- package/docs/production.md +4 -15
- package/docs/prompt-and-input.md +1 -2
- package/docs/provider-integration.md +156 -181
- package/docs/reference/protocol.md +5 -14
- package/docs/reference/provider-adapters.md +21 -13
- package/docs/security.md +1 -14
- package/docs/testing.md +56 -123
- package/package.json +4 -25
- package/starters/video-chat/.env.example +12 -4
- package/starters/video-chat/.env.native.example +13 -0
- package/starters/video-chat/README.md +72 -11
- package/starters/video-chat/package.json +1 -1
- package/starters/video-chat/providers/text-native.ts +94 -0
- package/starters/video-chat/providers/text.ts +19 -0
- package/starters/video-chat/providers/transcription.ts +32 -0
- package/starters/video-chat/providers/video-custom.ts +45 -0
- package/starters/video-chat/providers/video-delivery.ts +57 -0
- package/starters/video-chat/providers/video-google.ts +48 -0
- package/starters/video-chat/providers/video-job.ts +103 -0
- package/starters/video-chat/providers/video-runway.ts +45 -0
- package/starters/video-chat/providers/video.ts +39 -63
- package/starters/video-chat/server.ts +3 -29
- package/starters/video-chat/vite.config.ts +2 -8
- package/styles/video-chat.css +8 -105
- package/dist/builtin-server-W4PLJUZ5.js +0 -8
- package/dist/catalog-types-WTbLP6Jh.d.ts +0 -78
- package/dist/check-runtime.d.ts +0 -15
- package/dist/check-runtime.js +0 -96
- package/dist/chunk-2E6T633S.js +0 -27
- package/dist/chunk-4YM2M62S.js +0 -13
- package/dist/chunk-4ZJLPHBV.js +0 -684
- package/dist/chunk-5JBMYQP6.js +0 -156
- package/dist/chunk-73NTSFFI.js +0 -81
- package/dist/chunk-EGVQODKU.js +0 -83
- package/dist/chunk-HFVNAPHZ.js +0 -35
- package/dist/chunk-IIN5M5HW.js +0 -697
- package/dist/chunk-IQMYK5DX.js +0 -133
- package/dist/chunk-IR44XKBI.js +0 -46
- package/dist/chunk-JKVOBTRO.js +0 -145
- package/dist/chunk-LVM5Q2DL.js +0 -68
- package/dist/chunk-M4QTEJTK.js +0 -709
- package/dist/chunk-QSBDB4J2.js +0 -16
- package/dist/chunk-R3XAOMKP.js +0 -29
- package/dist/chunk-SPVTJH3F.js +0 -24
- package/dist/chunk-YAHT3LST.js +0 -663
- package/dist/chunk-ZD2VTUYR.js +0 -28
- package/dist/cinema-media-HYCDG65Z.js +0 -11
- package/dist/comparison-XXAP4S4J.js +0 -36
- package/dist/editorial-timeline-VUQC6KPA.js +0 -42
- package/dist/key-figure-4TJK7HLT.js +0 -29
- package/dist/kit-DrRpdn0p.d.ts +0 -79
- package/dist/mobile-message-FIHAO6XC.js +0 -49
- package/dist/preload-media-LJXWKTWG.js +0 -57
- package/dist/quote-GRPIYKQJ.js +0 -32
- package/dist/system-prompt-AG26KJAA.js +0 -12
- package/dist/template-catalog.d.ts +0 -400
- package/dist/template-catalog.js +0 -6
- package/dist/templates.d.ts +0 -25
- package/dist/templates.js +0 -102
- package/dist/validate-4OUD2CLX.js +0 -10
- package/docs/concepts.md +0 -107
- package/docs/custom-templates.md +0 -346
- package/docs/immersive-interface.md +0 -86
- package/docs/motion-and-effects.md +0 -109
- package/docs/reference/design-system.html +0 -125
- package/docs/responsive-orientation.md +0 -37
- package/docs/streaming-protocol.md +0 -15
- package/examples/custom-template/README.md +0 -19
- package/examples/custom-template/minimal-text.tsx +0 -82
- package/examples/custom-template/structured-data.tsx +0 -104
- package/registry/items/backgrounds.json +0 -70
- package/registry/items/chapterTitle.json +0 -80
- package/registry/items/cinemaMedia.json +0 -136
- package/registry/items/comparison.json +0 -168
- package/registry/items/editorialTimeline.json +0 -172
- package/registry/items/keyFigure.json +0 -162
- package/registry/items/mobileMessage.json +0 -153
- package/registry/items/motion.json +0 -45
- package/registry/items/quote.json +0 -161
- package/registry/items/template-context.json +0 -31
- package/registry/items/theme.json +0 -47
- package/registry/items/typography.json +0 -47
package/docs/custom-templates.md
DELETED
|
@@ -1,346 +0,0 @@
|
|
|
1
|
-
[← Documentation home](../README.md) · [Previous: Customization](customization.md) · [Next: Motion and effects →](motion-and-effects.md)
|
|
2
|
-
|
|
3
|
-
# Custom templates
|
|
4
|
-
|
|
5
|
-
VanillaSky turns context into a visual response. Your AI determines what matters
|
|
6
|
-
from the available context; a template defines how one kind of grounded answer
|
|
7
|
-
appears in motion. Custom templates let your application own that visual
|
|
8
|
-
vocabulary without letting the model generate React, HTML, or CSS.
|
|
9
|
-
|
|
10
|
-
You edit one source file. VanillaSky derives the model-facing description,
|
|
11
|
-
server validation, browser registry, and TypeScript variable shape from it.
|
|
12
|
-
|
|
13
|
-
## The shortest path
|
|
14
|
-
|
|
15
|
-
The playback and server package does not install a TypeScript compiler. Install
|
|
16
|
-
the optional compiler only for source-owned templates and the template
|
|
17
|
-
ownership commands below:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install --save-dev tsx
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
List the effective catalog, including project-owned templates, before choosing
|
|
24
|
-
what to build or copy:
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
npx vanillasky templates list
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Create an original template:
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
npx vanillasky templates create customer-health
|
|
34
|
-
npx vanillasky templates describe customer-health
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Or copy a built-in when its behavior is already close:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
npx vanillasky templates add keyFigure
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Then edit the owned `.tsx` file, regenerate the two small registries, and check
|
|
44
|
-
the complete contract:
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
npx vanillasky templates sync
|
|
48
|
-
npx vanillasky templates check
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
For an original template, the source is
|
|
52
|
-
`vanillasky/templates/customer-health.tsx`. For the copied built-in, it is
|
|
53
|
-
`vanillasky/templates/keyFigure.tsx`. These are application source: commit them,
|
|
54
|
-
review them, and change them like any other React component.
|
|
55
|
-
|
|
56
|
-
`create` and `add` run `sync` once, so the generated entry points exist
|
|
57
|
-
immediately. Run `sync` again after every source edit. Run `check` before every
|
|
58
|
-
commit. `check` validates metadata, schema/default validity, named examples, deterministic
|
|
59
|
-
renders at progress boundaries in portrait and landscape, and browser/server
|
|
60
|
-
registry parity.
|
|
61
|
-
|
|
62
|
-
Preview either operation without applying the proposed file writes:
|
|
63
|
-
|
|
64
|
-
```bash
|
|
65
|
-
npx vanillasky templates add keyFigure --dry-run
|
|
66
|
-
npx vanillasky templates add keyFigure --diff
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
`--dry-run` lists every proposed file and `--diff` shows its content changes,
|
|
70
|
-
including the generated browser and server registries. The CLI does not apply
|
|
71
|
-
any proposed file write. When project templates already exist, these previews
|
|
72
|
-
execute that trusted application source to derive the complete registry plan.
|
|
73
|
-
Because trusted project source can have its own side effects, preview execution is
|
|
74
|
-
resource-bounded but is not a sandbox and does not guarantee that the entire
|
|
75
|
-
project remains byte-identical. Review project template code before running
|
|
76
|
-
preview commands.
|
|
77
|
-
|
|
78
|
-
An edited file is never replaced unless you explicitly pass `--overwrite`.
|
|
79
|
-
|
|
80
|
-
## One file is the contract
|
|
81
|
-
|
|
82
|
-
The file created by `vanillasky templates create` is a complete working template. Keep
|
|
83
|
-
these concerns together:
|
|
84
|
-
|
|
85
|
-
- `useWhen` and `avoidWhen` tell the AI when the visual is appropriate;
|
|
86
|
-
- `jobs` declares the narrative roles the template can fill, and decides
|
|
87
|
-
whether it may close a video;
|
|
88
|
-
- `schema` defines allowed variables, validation, defaults, labels, and
|
|
89
|
-
grounding formats;
|
|
90
|
-
- named `examples` provide complete deterministic preview values;
|
|
91
|
-
- `component` receives only validated variables and render context;
|
|
92
|
-
- raw `progress`, dimensions, and `safeZone` make semantic state deterministic
|
|
93
|
-
and layout safe in portrait and landscape.
|
|
94
|
-
|
|
95
|
-
### Which templates may close a video
|
|
96
|
-
|
|
97
|
-
Every complete plan ends on exactly one closer, and the runtime only accepts a
|
|
98
|
-
closer whose `jobs` include `"ask"` or `"payoff"`. Marking any other template as
|
|
99
|
-
the closer rejects that scene with `Scene template <id> cannot be used as a
|
|
100
|
-
closer`, and the reserved closing time is given to a template that qualifies.
|
|
101
|
-
|
|
102
|
-
Declare `jobs: ["ask"]` on a call to action and `jobs: ["payoff"]` on a
|
|
103
|
-
celebration or resolution beat. A template that only presents evidence keeps
|
|
104
|
-
`jobs: ["proof"]` and is never asked to close.
|
|
105
|
-
|
|
106
|
-
The same rule reads the built-in catalog, so an application that wants to
|
|
107
|
-
constrain how its videos end can compute the eligible IDs instead of guessing:
|
|
108
|
-
|
|
109
|
-
```ts
|
|
110
|
-
import { builtinTemplates } from "@vanillaskyai/video/templates/catalog";
|
|
111
|
-
|
|
112
|
-
const closerTemplateIds = builtinTemplates
|
|
113
|
-
.filter((template) => template.jobs.some((job) => job === "ask" || job === "payoff"))
|
|
114
|
-
.map((template) => template.id);
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Pacing uses the same signal: the planner reserves time for the closer whenever
|
|
118
|
-
the selected catalog contains a template with one of those two jobs.
|
|
119
|
-
|
|
120
|
-
Customer templates hard-cut by default. Opt into renderer-owned fades only
|
|
121
|
-
for scenes that use the standard media-background variables, and only after
|
|
122
|
-
both timing points are visually tested in portrait and landscape. Shared render
|
|
123
|
-
black backgrounds and unchanged media do not crossfade:
|
|
124
|
-
|
|
125
|
-
```tsx
|
|
126
|
-
export default defineTemplate({
|
|
127
|
-
// ...the normal one-file contract
|
|
128
|
-
usesGlobalTransition: true,
|
|
129
|
-
transitionTiming: { entryReadyProgress: 0.2, holdProgress: 0.7 },
|
|
130
|
-
component: ({ progress, motionProgress = progress, ...props }) => {
|
|
131
|
-
// Both clocks cover the complete declared 0→1 scene duration.
|
|
132
|
-
// Use progress for facts/media/screens; motionProgress for presentation.
|
|
133
|
-
return <CustomerScene {...props} dataProgress={progress} motionProgress={motionProgress} />;
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
`entryReadyProgress` must show recognizable content in verification captures.
|
|
139
|
-
`holdProgress` is the audited complete-readable checkpoint before the
|
|
140
|
-
template's own exit begins. These values document and test the choreography;
|
|
141
|
-
they never advance or shorten the runtime clock. The SDK validates
|
|
142
|
-
`0 <= entryReadyProgress < holdProgress <= 1`.
|
|
143
|
-
|
|
144
|
-
When changed media crossfades, the incoming layer can be partly visible while
|
|
145
|
-
raw `progress` is exactly zero. A custom template that counts or types a value
|
|
146
|
-
from a synthetic placeholder must hide only that transient wrapper during the
|
|
147
|
-
crossfade. Compare the formatted display value to the formatted final value so
|
|
148
|
-
a sourced zero is not mistaken for a placeholder:
|
|
149
|
-
|
|
150
|
-
<!-- verify:transition-semantic-value:start -->
|
|
151
|
-
```tsx
|
|
152
|
-
import type { CSSProperties } from "react";
|
|
153
|
-
|
|
154
|
-
interface TransitionSemanticValueProps {
|
|
155
|
-
displayValue: string;
|
|
156
|
-
finalValue: string;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
export function TransitionSemanticValue({
|
|
160
|
-
displayValue,
|
|
161
|
-
finalValue,
|
|
162
|
-
}: TransitionSemanticValueProps) {
|
|
163
|
-
const isTransient = displayValue !== finalValue;
|
|
164
|
-
|
|
165
|
-
return <span
|
|
166
|
-
data-transition-semantic={isTransient ? "transient" : undefined}
|
|
167
|
-
style={isTransient ? {
|
|
168
|
-
visibility: "var(--vanillasky-transition-semantic-visibility, visible)" as CSSProperties["visibility"],
|
|
169
|
-
} : undefined}
|
|
170
|
-
>
|
|
171
|
-
{displayValue}
|
|
172
|
-
</span>;
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
<!-- verify:transition-semantic-value:end -->
|
|
176
|
-
|
|
177
|
-
The variable defaults to `visible`, so direct rendering and hard cuts are
|
|
178
|
-
unchanged. Do not apply it to grounded headings, CTA copy, supplied media, or
|
|
179
|
-
the whole scene: those must remain recognizable at `entryReadyProgress`.
|
|
180
|
-
|
|
181
|
-
The only SDK import an original one-file template needs is public:
|
|
182
|
-
|
|
183
|
-
```tsx
|
|
184
|
-
import { defineTemplate } from "@vanillaskyai/video/templates";
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
Start from the generated file or one of the packaged references:
|
|
188
|
-
|
|
189
|
-
| Content shape | Reference |
|
|
190
|
-
| --- | --- |
|
|
191
|
-
| One headline and supporting line | [Minimal text](../examples/custom-template/minimal-text.tsx) |
|
|
192
|
-
| One exact metric and its change | [Structured data](../examples/custom-template/structured-data.tsx) |
|
|
193
|
-
|
|
194
|
-
The [reference comparison](../examples/custom-template/README.md) explains when
|
|
195
|
-
to choose each. Copy a file into `vanillasky/templates/`, change its ID and
|
|
196
|
-
content contract, then run `sync` and `check`.
|
|
197
|
-
|
|
198
|
-
## Connect the generated registries
|
|
199
|
-
|
|
200
|
-
`sync` generates two files from the owned templates:
|
|
201
|
-
|
|
202
|
-
```text
|
|
203
|
-
vanillasky/
|
|
204
|
-
├── templates/
|
|
205
|
-
│ └── customer-health.tsx # source you edit
|
|
206
|
-
├── index.ts # browser registry, generated
|
|
207
|
-
└── server.ts # React-free model/validation registry, generated
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
The server registry connects custom template metadata to the prompt, model
|
|
211
|
-
selection, and validator. Import it in the route that connects your model:
|
|
212
|
-
|
|
213
|
-
```ts
|
|
214
|
-
// src/video-route.ts
|
|
215
|
-
import { generateText, streamText } from "ai";
|
|
216
|
-
import { createVideoChatHandler } from "@vanillaskyai/video/server";
|
|
217
|
-
import { videoModel } from "./video-model";
|
|
218
|
-
import { templates } from "../vanillasky/server";
|
|
219
|
-
|
|
220
|
-
export const handleVideoChat = createVideoChatHandler({
|
|
221
|
-
templates,
|
|
222
|
-
authorize: (request) => {
|
|
223
|
-
if (process.env.VANILLASKY_LOCAL_DEMO !== "1") return false;
|
|
224
|
-
const hostname = new URL(request.url).hostname;
|
|
225
|
-
return hostname === "localhost" || hostname === "127.0.0.1";
|
|
226
|
-
},
|
|
227
|
-
generateText: async ({ systemPrompt, userPrompt, signal }) => {
|
|
228
|
-
const result = await generateText({
|
|
229
|
-
model: videoModel,
|
|
230
|
-
system: systemPrompt,
|
|
231
|
-
prompt: userPrompt,
|
|
232
|
-
abortSignal: signal,
|
|
233
|
-
});
|
|
234
|
-
return result.text;
|
|
235
|
-
},
|
|
236
|
-
streamText: ({ systemPrompt, userPrompt, signal }) => streamText({
|
|
237
|
-
model: videoModel,
|
|
238
|
-
system: systemPrompt,
|
|
239
|
-
prompt: userPrompt,
|
|
240
|
-
abortSignal: signal,
|
|
241
|
-
}),
|
|
242
|
-
});
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
The local-only authorization above is intentionally narrow. Supply its marker
|
|
246
|
-
only from the development command; replace it with your application's session
|
|
247
|
-
check before deployment, as shown in
|
|
248
|
-
[Getting started](getting-started.md).
|
|
249
|
-
|
|
250
|
-
Use the browser registry for generation and playback:
|
|
251
|
-
|
|
252
|
-
```tsx
|
|
253
|
-
// src/video-chat.tsx
|
|
254
|
-
import { VideoChat } from "@vanillaskyai/video/react";
|
|
255
|
-
import "@vanillaskyai/video/video-chat.css";
|
|
256
|
-
import { templates } from "../vanillasky";
|
|
257
|
-
|
|
258
|
-
export function App() {
|
|
259
|
-
return <VideoChat options={{ templates }} />;
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Adjust relative paths for your application layout. Do not edit `index.ts` or
|
|
264
|
-
`server.ts`; `sync` replaces them. A matching ID replaces that built-in on both
|
|
265
|
-
sides, a new ID extends the catalog, and every other built-in remains available.
|
|
266
|
-
|
|
267
|
-
## Preview without an LLM
|
|
268
|
-
|
|
269
|
-
Template rendering is deterministic. Preview a saved `Video` directly in your
|
|
270
|
-
application so iteration uses your actual CSS, fonts, container, React version,
|
|
271
|
-
and browser. This path calls no model and needs no server route:
|
|
272
|
-
|
|
273
|
-
<!-- verify:custom-template-preview:start -->
|
|
274
|
-
```tsx
|
|
275
|
-
import type { Video } from "@vanillaskyai/video";
|
|
276
|
-
import { VideoPlayer } from "@vanillaskyai/video/react";
|
|
277
|
-
import { templates } from "../vanillasky";
|
|
278
|
-
|
|
279
|
-
const savedVideo: Video = {
|
|
280
|
-
schemaVersion: "0.2",
|
|
281
|
-
orientation: "portrait",
|
|
282
|
-
scenes: [{
|
|
283
|
-
id: "customer-health-preview",
|
|
284
|
-
templateId: "customer-health",
|
|
285
|
-
variables: {
|
|
286
|
-
title: "Customer health is improving",
|
|
287
|
-
subtitle: "Activation increased after guided onboarding.",
|
|
288
|
-
},
|
|
289
|
-
timing: { fixedDuration: 5 },
|
|
290
|
-
}],
|
|
291
|
-
style: {},
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
export function TemplatePreview() {
|
|
295
|
-
return <VideoPlayer video={savedVideo} templates={templates} autoPlay={false} />;
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
<!-- verify:custom-template-preview:end -->
|
|
299
|
-
|
|
300
|
-
Change the saved variables to each named example, inspect both orientations,
|
|
301
|
-
and play the scene to inspect its full progress range. This is also the
|
|
302
|
-
production replay path for a completed chat turn saved from `chat.turns`.
|
|
303
|
-
|
|
304
|
-
## Schema and grounding
|
|
305
|
-
|
|
306
|
-
Use JSON Schema as the single source of truth.
|
|
307
|
-
|
|
308
|
-
Property defaults are optional authoring and renderer smoke values; they do not
|
|
309
|
-
need to form a complete scene. Named examples must resolve to complete valid
|
|
310
|
-
scenes. They may inherit omitted values from property defaults. Never invent
|
|
311
|
-
media URLs or actions just to supply a default. Put complete scene examples in
|
|
312
|
-
the top-level `examples` array, and do not maintain parallel variable or default
|
|
313
|
-
maps.
|
|
314
|
-
|
|
315
|
-
Useful formats add grounding behavior:
|
|
316
|
-
|
|
317
|
-
- `grounded-stat` accepts numeric or string quantities and requires an exact
|
|
318
|
-
quantity in raw input, preserving its unit;
|
|
319
|
-
- `grounded-quote` requires the quote to exist verbatim in the input;
|
|
320
|
-
- `uri` validates approved media URLs restored by the server;
|
|
321
|
-
- `stock-media-keyword` is only for hosts that resolve stock media before a
|
|
322
|
-
scene is committed.
|
|
323
|
-
|
|
324
|
-
Templates whose core proof needs a real statistic can add
|
|
325
|
-
`"x-vanillasky": { "requiresStat": true }`. See the structured-data reference for a complete example.
|
|
326
|
-
|
|
327
|
-
For media-backed chat scenes, copy the built-in `cinemaMedia` template and keep its
|
|
328
|
-
`mediaKeyword`, `mediaUrl`, and `mediaType` contract. Configure `searchMedia` on
|
|
329
|
-
the chat handler so the server resolves semantic searches into approved assets.
|
|
330
|
-
The chat request does not accept a separate supplied-media input list.
|
|
331
|
-
|
|
332
|
-
The automatic `opening` uses the built-in `chapterTitle` variable `title`.
|
|
333
|
-
If you replace that template while using automatic openings, keep this contract.
|
|
334
|
-
|
|
335
|
-
## What belongs where
|
|
336
|
-
|
|
337
|
-
Your application owns the model, credentials, live context, custom template
|
|
338
|
-
source, authentication, media authorization, and saved `Video` values.
|
|
339
|
-
VanillaSky owns the generated planning instructions, streaming protocol,
|
|
340
|
-
runtime validation, built-in template catalog, and player. The model selects a
|
|
341
|
-
trusted template and fills its declared schema; it never writes executable UI
|
|
342
|
-
code.
|
|
343
|
-
|
|
344
|
-
For the exact request path and source locations, see
|
|
345
|
-
[Architecture](architecture.md). For media policies and provider callbacks,
|
|
346
|
-
see [Media and audio](media-and-audio.md).
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
[← Documentation home](../README.md)
|
|
2
|
-
|
|
3
|
-
# Immersive video chat
|
|
4
|
-
|
|
5
|
-
`VideoChat` provides the complete conversation interface over an adaptive video
|
|
6
|
-
canvas. Import its stylesheet once; no copied example UI or component setup is
|
|
7
|
-
required.
|
|
8
|
-
|
|
9
|
-
```tsx
|
|
10
|
-
import { VideoChat } from "@vanillaskyai/video/react";
|
|
11
|
-
import "@vanillaskyai/video/video-chat.css";
|
|
12
|
-
|
|
13
|
-
export function App() {
|
|
14
|
-
return <VideoChat options={{ endpoint: "/api/video-chat" }} />;
|
|
15
|
-
}
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
The [interactive component reference](reference/design-system.html) uses the
|
|
19
|
-
same packaged stylesheet. It demonstrates navigation, settings, history,
|
|
20
|
-
conversation input, subtitles, suggestions and interaction states without
|
|
21
|
-
requesting a microphone or calling a model.
|
|
22
|
-
|
|
23
|
-
## Watching and asking
|
|
24
|
-
|
|
25
|
-
The video owns the canvas. The navigation contains the VanillaSky logo, new
|
|
26
|
-
session, history, voice and settings. One floating field supports speech and
|
|
27
|
-
text; playback, microphone and send controls stay beside the question.
|
|
28
|
-
|
|
29
|
-
Beginning a question pauses the picture and narration together. Speech becomes
|
|
30
|
-
a draft to review. Sending begins the next answer; canceling returns to the
|
|
31
|
-
previous playback state. Canceling voice input also discards pending
|
|
32
|
-
transcription so a late result cannot replace a new draft.
|
|
33
|
-
|
|
34
|
-
The first subtitle hides the input unless editing, listening or keyboard focus
|
|
35
|
-
requires it. Pointer activity or touch reveals the controls again. They hide
|
|
36
|
-
after two seconds of inactivity during playback; paused playback and active
|
|
37
|
-
controls remain accessible. A stationary pointer left over Send does not hold
|
|
38
|
-
the input open. Settings can keep the input visible.
|
|
39
|
-
|
|
40
|
-
## Subtitles and transcripts
|
|
41
|
-
|
|
42
|
-
Subtitles sit on a dark backing over the picture. The complete current cue
|
|
43
|
-
remains available without a line clamp or ellipsis. When the input appears,
|
|
44
|
-
subtitles move upward; when it disappears, they return to the bottom baseline.
|
|
45
|
-
The transition preserves space for both rows instead of abruptly repositioning
|
|
46
|
-
the subtitle.
|
|
47
|
-
|
|
48
|
-
Subtitle actions fade while inactive and return on hover, touch or keyboard
|
|
49
|
-
focus. Expand opens the answer transcript in the same surface. Hide removes
|
|
50
|
-
subtitles; the Subtitles switch in Settings restores them. The transcript is
|
|
51
|
-
part of the video interface rather than a separate modal.
|
|
52
|
-
|
|
53
|
-
## Settings and history
|
|
54
|
-
|
|
55
|
-
Settings and history share one dark glass treatment. Watching preferences
|
|
56
|
-
control subtitles and input visibility. Video creation and style preferences
|
|
57
|
-
apply to the next question; provider capabilities determine available options.
|
|
58
|
-
History replays saved answers without generating them again. New session
|
|
59
|
-
retains up to ten sessions in memory, preserving completed answers for replay.
|
|
60
|
-
This history does not provide server or durable persistence; storage remains
|
|
61
|
-
application-owned. See [persistence](persistence.md).
|
|
62
|
-
|
|
63
|
-
Suggestions appear in a horizontal media-card rail. Pointer hover and keyboard
|
|
64
|
-
focus select a card; choosing it begins a follow-up answer. Focus outlines and
|
|
65
|
-
hover movement remain inside the rail's available space.
|
|
66
|
-
|
|
67
|
-
## Layout and access
|
|
68
|
-
|
|
69
|
-
The foreground video preserves its scene ratio, so diagrams and text remain
|
|
70
|
-
visible without cropping or distortion. The surrounding viewport remains black during playback.
|
|
71
|
-
Display layout does not rewrite the saved response's orientation. See
|
|
72
|
-
[responsive orientation](responsive-orientation.md) for saved videos and custom
|
|
73
|
-
players.
|
|
74
|
-
|
|
75
|
-
Primary control targets are at least 44px. Bottom spacing includes the device
|
|
76
|
-
safe area. Keyboard focus stays visible, settings retain native switch and
|
|
77
|
-
radio behavior, and popovers support Escape and outside-click dismissal.
|
|
78
|
-
Reduced motion removes movement and fades; increased contrast strengthens
|
|
79
|
-
surface opacity and borders.
|
|
80
|
-
|
|
81
|
-
## Customization
|
|
82
|
-
|
|
83
|
-
Use the existing `welcomeTitle`, `className` and `options` props to customize
|
|
84
|
-
copy, scoped CSS properties and generated footage direction. There is no separate
|
|
85
|
-
light/dark appearance picker. See [customization](customization.md) for examples.
|
|
86
|
-
Use `useVideoChat` when the application needs to own the whole interface.
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
[← Documentation home](../README.md) · [Previous: Custom templates](custom-templates.md) · [Next: Production →](production.md)
|
|
2
|
-
|
|
3
|
-
# Motion and effects
|
|
4
|
-
|
|
5
|
-
VanillaSky motion is deterministic. The model selects from controlled names;
|
|
6
|
-
the SDK calculates the same frame from the same video JSON and playback time.
|
|
7
|
-
No generated CSS, animation code, or arbitrary transition is executed.
|
|
8
|
-
|
|
9
|
-
## Text archetypes
|
|
10
|
-
|
|
11
|
-
Text archetypes own a complete entrance, hold, and exit lifecycle:
|
|
12
|
-
|
|
13
|
-
- `subtle` — quiet supporting copy;
|
|
14
|
-
- `typewriter` — character-by-character reveal;
|
|
15
|
-
- `wordStagger` — sequential word build;
|
|
16
|
-
- `slam` — short, high-energy impact;
|
|
17
|
-
- `cinematic` — depth-led trailer movement;
|
|
18
|
-
- `heroWord` — one dominant word at a time.
|
|
19
|
-
|
|
20
|
-
Templates declare whether they have a tight or open text canvas. VanillaSky
|
|
21
|
-
normalizes incompatible or unknown values to a safe default.
|
|
22
|
-
|
|
23
|
-
## Background effects
|
|
24
|
-
|
|
25
|
-
Templates that support background motion can use:
|
|
26
|
-
|
|
27
|
-
- `static`;
|
|
28
|
-
- `slow-zoom-in`;
|
|
29
|
-
- `slow-zoom-out`;
|
|
30
|
-
- `ken-burns`;
|
|
31
|
-
- `drift`;
|
|
32
|
-
- `pulse`;
|
|
33
|
-
- `breathe`;
|
|
34
|
-
- `slow-tilt`;
|
|
35
|
-
- `camera-shake`.
|
|
36
|
-
|
|
37
|
-
`static` is the default, so a media change cannot restart an implicit camera
|
|
38
|
-
transform. Apply another effect explicitly when a still image or authored scene
|
|
39
|
-
benefits from it; footage keeps its own native motion by default.
|
|
40
|
-
|
|
41
|
-
## Scene continuity
|
|
42
|
-
|
|
43
|
-
Generated videos use `crossfade` by default. Persisted or application-authored
|
|
44
|
-
`Video` values can set `style.defaultTransition` to `crossfade` or `fade`; an
|
|
45
|
-
undefined or unknown value keeps the hard-cut behavior. The player applies a fade
|
|
46
|
-
only when two ranges are contiguous (allowing floating-point arithmetic noise)
|
|
47
|
-
and both templates declare `usesGlobalTransition: true` with valid
|
|
48
|
-
`transitionTiming` metadata. It is also conditional on the effective backdrop:
|
|
49
|
-
the 300 ms outer crossfade runs only when the resolved background media changes.
|
|
50
|
-
Scenes that share the black base, or the same resolved media backdrop, do
|
|
51
|
-
not crossfade. This keeps one stable background visible while each template
|
|
52
|
-
plays its own entrance, hold, and exit choreography.
|
|
53
|
-
|
|
54
|
-
The player owns a fixed black backdrop beneath the scenes. Built-in renderers
|
|
55
|
-
preload through the same component state used for playback. A cold custom
|
|
56
|
-
renderer reveals this black base while loading. Resolved scene media covers it
|
|
57
|
-
only while the media scene is active.
|
|
58
|
-
|
|
59
|
-
During a changed-media overlap, the current scene continues to its exact end.
|
|
60
|
-
The incoming component may be pre-mounted for media readiness, but remains
|
|
61
|
-
frozen at its true initial frame (`progress === motionProgress === 0`) until its
|
|
62
|
-
declared range begins. The current scene remains interactive and exposed to
|
|
63
|
-
assistive technology until the exact timeline boundary; the preview layer
|
|
64
|
-
remains inert throughout the overlap.
|
|
65
|
-
|
|
66
|
-
Templates always receive raw semantic scene time as `progress`. Grounded
|
|
67
|
-
numbers, media time, screen sequences, and other content state must use that
|
|
68
|
-
clock. An opted-in template also receives `motionProgress`; throughout active
|
|
69
|
-
playback it is the same complete `0→1` clock. The player never pre-advances,
|
|
70
|
-
caps, rewinds, or skips a template's entrance, internal motion, exit, or
|
|
71
|
-
terminal frame. `transitionTiming` records audited entry-ready and readable
|
|
72
|
-
checkpoints for verification, but does not remap runtime time. Use
|
|
73
|
-
`motionProgress` only for presentation and fall back to `progress` when it is
|
|
74
|
-
absent. Templates opt out by default.
|
|
75
|
-
|
|
76
|
-
An incoming changed-media fade can expose the template's initial frame while
|
|
77
|
-
its raw semantic clock is still zero.
|
|
78
|
-
Do not show a synthetic `0%`, `0x`, empty total, or another value that could be
|
|
79
|
-
mistaken for sourced content. Keep the grounded frame and CTA visible, but mark
|
|
80
|
-
only a transient value wrapper with
|
|
81
|
-
`visibility: var(--vanillasky-transition-semantic-visibility, visible)`. The
|
|
82
|
-
player hides that wrapper for the incoming preview and reveals it as soon as
|
|
83
|
-
the same mounted scene becomes active. This guard does not change `progress`,
|
|
84
|
-
media time, the component lifecycle, or final values.
|
|
85
|
-
|
|
86
|
-
As soon as a streamed scene arrives, the player starts warming its template and
|
|
87
|
-
backdrop. A changed-media scene is also mounted invisibly before its cut so the
|
|
88
|
-
browser can attach and decode the real element in advance. This media preroll
|
|
89
|
-
also protects intentional hard cuts; it does not pause or otherwise alter the
|
|
90
|
-
visual or soundtrack clocks.
|
|
91
|
-
|
|
92
|
-
Undefined or unknown transition names preserve a hard cut and unmodified local
|
|
93
|
-
motion. Overlapping ranges also hard-cut. A timeline gap renders the fixed black
|
|
94
|
-
background instead of replaying an earlier scene.
|
|
95
|
-
|
|
96
|
-
## Reduced motion
|
|
97
|
-
|
|
98
|
-
The player respects `prefers-reduced-motion`. Applications should keep a
|
|
99
|
-
visible playback control and must not rely on motion alone to communicate a
|
|
100
|
-
fact or state.
|
|
101
|
-
|
|
102
|
-
## Preview the catalog
|
|
103
|
-
|
|
104
|
-
The public [motion and effects gallery](https://vanillasky.ai/motion/) renders
|
|
105
|
-
the real SDK effects with their exact configuration. Use it to choose a
|
|
106
|
-
controlled effect, then keep the initial integration on the defaults unless a
|
|
107
|
-
specific editorial need calls for an override.
|
|
108
|
-
|
|
109
|
-
[← Documentation home](../README.md) · [Previous: Custom templates](custom-templates.md) · [Next: Production →](production.md)
|