@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.
Files changed (127) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/PUBLIC-API.md +47 -438
  3. package/README.md +53 -97
  4. package/dist/builtin-metadata-OT6V7TB4.js +8 -0
  5. package/dist/{chapter-title-2JVDU62E.js → chapter-title-2RCXX7SN.js} +1 -2
  6. package/dist/{chunk-5BSJLT6H.js → chunk-2WIETEL7.js} +16 -29
  7. package/dist/{chunk-3O7OMMMF.js → chunk-35K6IKB2.js} +3 -3
  8. package/dist/{chunk-PDQFQIQW.js → chunk-3EQ6PVWL.js} +1 -1
  9. package/dist/chunk-4G4JBMCM.js +37 -0
  10. package/dist/{chunk-7AA2JWHZ.js → chunk-5DOQTIMD.js} +6 -6
  11. package/dist/chunk-666HGTVZ.js +41 -0
  12. package/dist/{chunk-7M56IUUX.js → chunk-6Z3ID54H.js} +0 -18
  13. package/dist/chunk-AUN4S3YW.js +50 -0
  14. package/dist/chunk-HIQM4J3U.js +30 -0
  15. package/dist/chunk-ISWQ6T5X.js +36 -0
  16. package/dist/{chunk-224QNWRA.js → chunk-K5J7ESRO.js} +1 -10
  17. package/dist/chunk-NM4CXXZY.js +25 -0
  18. package/dist/{chunk-44WND2VP.js → chunk-RFXHLLYU.js} +34 -62
  19. package/dist/{chunk-RXTN2CW6.js → chunk-Z3DLSLAJ.js} +1 -1
  20. package/dist/cinema-media-YZ2UANJG.js +365 -0
  21. package/dist/cli.js +154 -1748
  22. package/dist/{compose-video-BH5K6XWT.js → compose-video-RSLI4CVP.js} +4 -4
  23. package/dist/{events-B4YCc4vc.d.ts → events-BZAfl0Dm.d.ts} +1 -1
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +4 -6
  26. package/dist/preload-media-23JXUFCF.js +77 -0
  27. package/dist/react.d.ts +39 -15
  28. package/dist/react.js +1355 -740
  29. package/dist/scene-validation-SGLLLFY5.js +9 -0
  30. package/dist/server.d.ts +67 -117
  31. package/dist/server.js +296 -626
  32. package/dist/test.d.ts +2 -2
  33. package/dist/test.js +21 -21
  34. package/dist/{text-stream-LD364KBI.js → text-stream-SOVLYR2L.js} +2 -2
  35. package/dist/{types-BqB8zC9u.d.ts → types-CG-kPI81.d.ts} +3 -1
  36. package/dist/{types-DdZw4GRQ.d.ts → types-ht-Zw3Wv.d.ts} +1 -1
  37. package/docs/agent-integration.md +19 -64
  38. package/docs/architecture.md +80 -106
  39. package/docs/customization.md +49 -66
  40. package/docs/development.md +18 -17
  41. package/docs/errors.md +4 -4
  42. package/docs/getting-started.md +74 -93
  43. package/docs/media-and-audio.md +9 -7
  44. package/docs/performance.md +11 -6
  45. package/docs/persistence.md +3 -7
  46. package/docs/production.md +4 -15
  47. package/docs/prompt-and-input.md +1 -2
  48. package/docs/provider-integration.md +156 -181
  49. package/docs/reference/protocol.md +5 -14
  50. package/docs/reference/provider-adapters.md +21 -13
  51. package/docs/security.md +1 -14
  52. package/docs/testing.md +56 -123
  53. package/package.json +4 -25
  54. package/starters/video-chat/.env.example +12 -4
  55. package/starters/video-chat/.env.native.example +13 -0
  56. package/starters/video-chat/README.md +72 -11
  57. package/starters/video-chat/package.json +1 -1
  58. package/starters/video-chat/providers/text-native.ts +94 -0
  59. package/starters/video-chat/providers/text.ts +19 -0
  60. package/starters/video-chat/providers/transcription.ts +32 -0
  61. package/starters/video-chat/providers/video-custom.ts +45 -0
  62. package/starters/video-chat/providers/video-delivery.ts +57 -0
  63. package/starters/video-chat/providers/video-google.ts +48 -0
  64. package/starters/video-chat/providers/video-job.ts +103 -0
  65. package/starters/video-chat/providers/video-runway.ts +45 -0
  66. package/starters/video-chat/providers/video.ts +39 -63
  67. package/starters/video-chat/server.ts +3 -29
  68. package/starters/video-chat/vite.config.ts +2 -8
  69. package/styles/video-chat.css +8 -105
  70. package/dist/builtin-server-W4PLJUZ5.js +0 -8
  71. package/dist/catalog-types-WTbLP6Jh.d.ts +0 -78
  72. package/dist/check-runtime.d.ts +0 -15
  73. package/dist/check-runtime.js +0 -96
  74. package/dist/chunk-2E6T633S.js +0 -27
  75. package/dist/chunk-4YM2M62S.js +0 -13
  76. package/dist/chunk-4ZJLPHBV.js +0 -684
  77. package/dist/chunk-5JBMYQP6.js +0 -156
  78. package/dist/chunk-73NTSFFI.js +0 -81
  79. package/dist/chunk-EGVQODKU.js +0 -83
  80. package/dist/chunk-HFVNAPHZ.js +0 -35
  81. package/dist/chunk-IIN5M5HW.js +0 -697
  82. package/dist/chunk-IQMYK5DX.js +0 -133
  83. package/dist/chunk-IR44XKBI.js +0 -46
  84. package/dist/chunk-JKVOBTRO.js +0 -145
  85. package/dist/chunk-LVM5Q2DL.js +0 -68
  86. package/dist/chunk-M4QTEJTK.js +0 -709
  87. package/dist/chunk-QSBDB4J2.js +0 -16
  88. package/dist/chunk-R3XAOMKP.js +0 -29
  89. package/dist/chunk-SPVTJH3F.js +0 -24
  90. package/dist/chunk-YAHT3LST.js +0 -663
  91. package/dist/chunk-ZD2VTUYR.js +0 -28
  92. package/dist/cinema-media-HYCDG65Z.js +0 -11
  93. package/dist/comparison-XXAP4S4J.js +0 -36
  94. package/dist/editorial-timeline-VUQC6KPA.js +0 -42
  95. package/dist/key-figure-4TJK7HLT.js +0 -29
  96. package/dist/kit-DrRpdn0p.d.ts +0 -79
  97. package/dist/mobile-message-FIHAO6XC.js +0 -49
  98. package/dist/preload-media-LJXWKTWG.js +0 -57
  99. package/dist/quote-GRPIYKQJ.js +0 -32
  100. package/dist/system-prompt-AG26KJAA.js +0 -12
  101. package/dist/template-catalog.d.ts +0 -400
  102. package/dist/template-catalog.js +0 -6
  103. package/dist/templates.d.ts +0 -25
  104. package/dist/templates.js +0 -102
  105. package/dist/validate-4OUD2CLX.js +0 -10
  106. package/docs/concepts.md +0 -107
  107. package/docs/custom-templates.md +0 -346
  108. package/docs/immersive-interface.md +0 -86
  109. package/docs/motion-and-effects.md +0 -109
  110. package/docs/reference/design-system.html +0 -125
  111. package/docs/responsive-orientation.md +0 -37
  112. package/docs/streaming-protocol.md +0 -15
  113. package/examples/custom-template/README.md +0 -19
  114. package/examples/custom-template/minimal-text.tsx +0 -82
  115. package/examples/custom-template/structured-data.tsx +0 -104
  116. package/registry/items/backgrounds.json +0 -70
  117. package/registry/items/chapterTitle.json +0 -80
  118. package/registry/items/cinemaMedia.json +0 -136
  119. package/registry/items/comparison.json +0 -168
  120. package/registry/items/editorialTimeline.json +0 -172
  121. package/registry/items/keyFigure.json +0 -162
  122. package/registry/items/mobileMessage.json +0 -153
  123. package/registry/items/motion.json +0 -45
  124. package/registry/items/quote.json +0 -161
  125. package/registry/items/template-context.json +0 -31
  126. package/registry/items/theme.json +0 -47
  127. package/registry/items/typography.json +0 -47
@@ -1,197 +1,172 @@
1
- [← Documentation home](../README.md) · [Previous: Getting started](getting-started.md) · [Next: Customization →](customization.md)
2
-
3
1
  # Provider integration
4
2
 
5
- Start from the generated chat so provider work stays confined to the
6
- application-owned server:
7
-
8
- ```bash
9
- npx @vanillaskyai/video init
10
- npx vanillasky doctor
11
- npm run dev
12
- ```
13
-
14
- Init runs doctor automatically. The generated `server.ts` starts with one
15
- `ANTHROPIC_API_KEY`, a template introduction, and browser voice; it installs no
16
- optional speech or video packages.
3
+ Follow [Getting started](getting-started.md) for setup. Keep one `VideoChat`
4
+ client and one `createVideoChatHandler` endpoint. Models, credentials,
5
+ authentication, retrieval, tools, storage and spending belong to the application;
6
+ the SDK owns shot planning, validation, streaming and playback.
17
7
 
18
- Use `npx vanillasky providers add speech` to install xAI speech, or
19
- `npx vanillasky providers add video` to install FAL video and transcription.
20
- Add `XAI_API_KEY` or `FAL_KEY` to `.env.local` and restart the server. Stock media
21
- needs only `PEXELS_API_KEY`, with no extra installation. These app-owned
22
- adapters advertise their capabilities automatically; `src/main.tsx` does not
23
- change. Rerun an interrupted setup command to finish installation.
8
+ The generated `providers/text.ts` is an editable Vercel AI SDK example.
9
+ `init --native` instead installs native Gemini REST callbacks with no `ai` or
10
+ `@ai-sdk/anthropic` dependency. Neither integration is required by the core.
11
+ Any native API, vendor SDK or application service can implement the callbacks.
24
12
 
25
- For the full chat experience, mount one `createVideoChatHandler` and keep every
26
- provider choice in its callbacks:
13
+ ## Text callbacks
27
14
 
28
- ```ts
29
- import "server-only";
30
- import { anthropic } from "@ai-sdk/anthropic";
31
- import { generateText, streamText } from "ai";
32
- import { createVideoChatHandler } from "@vanillaskyai/video/server";
15
+ `streamText` receives the SDK's `systemPrompt`, `userPrompt` and `signal`.
16
+ Return an `AsyncIterable<string>` directly, or an AI SDK-shaped object with a
17
+ `textStream`. The stream contains the model's answer brief and shot records,
18
+ not React components or pre-generated MP4 bytes.
33
19
 
34
- export const handler = createVideoChatHandler({
35
- authorize: verifySession,
36
- streamText: ({ systemPrompt, userPrompt, signal }) => streamText({
37
- model: anthropic(process.env.TEXT_MODEL ?? "claude-sonnet-5"),
38
- system: systemPrompt,
39
- prompt: userPrompt,
40
- abortSignal: signal,
41
- }),
42
- generateText: async ({ systemPrompt, userPrompt, maxOutputTokens, signal }) => {
43
- const result = await generateText({
44
- model: anthropic(process.env.TEXT_MODEL ?? "claude-sonnet-5"),
45
- system: systemPrompt,
46
- prompt: userPrompt,
47
- maxOutputTokens,
48
- abortSignal: signal,
49
- });
50
- return result.text;
51
- },
52
- });
53
- ```
54
-
55
- That one text provider gives the browser templated video responses and local
56
- browser speech. Supplying `generateSpeech`, `transcribe`, `searchMedia`, or
57
- `generateVideo` enables those capabilities automatically. The callbacks are
58
- structural and provider-neutral; their SDKs and credentials remain application
59
- dependencies and never enter the browser bundle.
60
-
61
- The planner emits a short spoken opening, then continues the answer in the same
62
- stream. The default UI shows a chapter immediately. A welcome card can carry a
63
- prewritten `opening`, whose narration starts without waiting for the model.
64
- Each authored body beat prepares speech and selected footage together. Playback
65
- starts after its contiguous preparation cushion, without requiring the entire
66
- plan or a second model call for narration.
67
-
68
- The matching complete React interface is one component and one scoped style
69
- import:
70
-
71
- ```tsx
72
- import { VideoChat } from "@vanillaskyai/video/react";
73
- import "@vanillaskyai/video/video-chat.css";
74
-
75
- export function App() {
76
- return <VideoChat />;
77
- }
78
- ```
20
+ `generateText` handles bounded helper tasks. Honor its `systemPrompt`,
21
+ `userPrompt`, `maxOutputTokens` and `signal`; return a string. If you dispatch by
22
+ `task`, handle `narration`, `narration-rewrite` and `suggestions`. The rewrite
23
+ task is an intentional part of the speech/clip budget, not a second answer.
79
24
 
80
- ## Custom interface
25
+ Model IDs, reasoning effort, sampling, prompt caching and provider timeouts
26
+ remain in the adapter. Measure first usable scene and answer quality, not only
27
+ time to first token. Keep credentials and raw provider metadata server-side.
28
+ See the [adapter reference](reference/provider-adapters.md) for lower-level
29
+ text stream and completion fields.
81
30
 
82
- For a custom interface, use `useVideoChat` and render its `turns`, `welcome`,
83
- `suggestions`, `caption`, and `status`; the hook owns their network and playback
84
- lifecycle. Pass a selected card through
85
- `chat.ask(card.prompt, { opening: card.opening })` to start its hook immediately.
86
- Custom interfaces can still pass and render `openingMedia`; the default UI uses
87
- the chapter. Typed prompts receive their authored opening through the stream.
31
+ ## Use an existing assistant
88
32
 
89
- Any AI SDK `LanguageModel` works in both `streamText` and `generateText`. Keep
90
- selection in one server-only module when an application supports several text
91
- providers. The chat route and React component stay unchanged; only the model
92
- passed to those callbacks changes. The AI SDK result can be returned directly:
93
- its text stream, finish reason, usage, warnings, and response metadata match the
94
- structural callback contract. See the
95
- [provider adapter reference](reference/provider-adapters.md) for native provider
96
- alternatives.
97
-
98
- ## Planning effort and reasoning modes
99
-
100
- Planning is a structured emit against a trusted catalog, not a reasoning task.
101
- Where a provider exposes a reasoning or effort control, a host that wants a
102
- video to start quickly should turn extended reasoning off and keep effort low
103
- to moderate. The default matters: several current models reason by default, and
104
- that reasoning happens before the first plan part is emitted, so it is added
105
- directly to time to first generated scene.
106
-
107
- With the Vercel AI SDK and a current Anthropic model, that is one option object:
33
+ Add `resolveAnswer` when your application already decides what the assistant
34
+ should say. For example, in your generated `server.ts`:
108
35
 
109
36
  ```ts
110
- streamText: ({ systemPrompt, userPrompt, signal }) => streamText({
111
- model,
112
- system: systemPrompt,
113
- prompt: userPrompt,
114
- abortSignal: signal,
115
- providerOptions: {
116
- anthropic: { thinking: { type: "disabled" }, effort: "medium" },
117
- },
118
- }),
119
- ```
120
-
121
- Reasoning settings can substantially affect startup latency. Measure them with
122
- your installed catalog and representative requests. Compare first-scene timing,
123
- rejected scenes and factual accuracy; the fastest token stream is not useful if
124
- its scenes cannot be rendered. Keep these settings in the provider adapter.
125
-
126
- VanillaSky never sets these controls. Provider selection, sampling parameters,
127
- and credentials stay with the application.
128
-
129
- ## Completion and usage
130
-
131
- Use `onComplete` for server-side cost and completion measurement:
37
+ import { createVideoChatHandler } from "@vanillaskyai/video/server";
38
+ import { textProvider } from "./providers/text";
39
+ import { providers } from "./providers";
40
+ import { answerQuestion } from "./assistant";
41
+ import { verifySession } from "./auth";
132
42
 
133
- ```ts
134
- createVideoChatHandler({
43
+ export const handleVideoChat = createVideoChatHandler({
135
44
  authorize: verifySession,
136
- streamText: ({ systemPrompt, userPrompt, signal }) => streamText({
137
- model,
138
- system: systemPrompt,
139
- prompt: userPrompt,
140
- abortSignal: signal,
141
- }),
142
- generateText: runSmallTextTask,
143
- onWarning: (warning) => logSafeWarning(warning.code, warning.category),
144
- onComplete: (summary) => recordGeneration({
145
- finishReason: summary.finishReason,
146
- usage: summary.usage,
147
- requestedModelId: summary.requestedModelId,
148
- resolvedModelId: summary.resolvedModelId,
149
- totalDurationMs: summary.totalDurationMs,
150
- }),
151
- onError: (error) => recordPrivateFailure(error),
45
+ ...textProvider,
46
+ ...providers,
47
+ resolveAnswer: ({ prompt, conversation, signal }) =>
48
+ answerQuestion({ prompt, conversation, signal }),
152
49
  });
153
50
  ```
154
51
 
155
- `onComplete` fires once only after `response.complete`. It does not fire for a
156
- terminal error, abort, disconnect, or timeout. Callback failures are isolated
157
- from the event stream. Normalized token usage and model IDs remain server-only;
158
- they never enter SSE or the persisted `Video`. Set `includeRawProviderData:
159
- true` only when the host deliberately needs bounded provider-native usage and
160
- metadata and has an appropriate retention policy.
161
-
162
- `acceptedSceneCount`, `rejectedSceneCount`, and `timeToFirstSceneMs` describe
163
- model-generated scene additions; the streamed opening hook is not counted.
164
- Their sum is the proposed scene count. `videoDurationSec` is the duration
165
- actually committed. These fields provide a server-side quality signal without
166
- exposing model metadata in the browser.
167
- Warnings include the same bounded typed warnings emitted to the client.
168
- `plan_incomplete` identifies a playable partial response whose planner reported
169
- a length limit; applications should show that result as incomplete and may
170
- offer a bounded retry with a larger output or duration budget.
171
- `plan_missing_closer` identifies a playable answer that ended without its
172
- explicit final scene. For non-interactive evaluation, define an application
173
- threshold and retry a bounded number of times. Keep the best accepted result
174
- rather than treating `finishReason: "stop"` alone as a quality score.
175
-
176
- The generated system prompt includes the selected trusted-template catalog and
177
- is intentionally substantial. It is stable for the same SDK version, template
178
- kit, media policy, and base prompt. Record input-token usage, keep the selected
179
- kit no broader than the product needs, and enable provider-side prompt caching
180
- where the chosen provider/model supports it. VanillaSky does not assume one
181
- provider's cache controls in its provider-neutral adapter. Default chat streams an answer brief and shot directions rather than the template catalog; use provider-reported token
182
- usage as the authoritative measurement rather than a character estimate.
183
-
184
- Provider finish reasons `error` and `tool-calls` are terminal failures.
185
- `length` and `content-filter` may complete with already accepted scenes; a
186
- truncation before the first generated scene fails instead of returning an empty
187
- success. The request signal is forwarded to the provider. Configure route and
188
- provider timeouts with that signal, and keep retries host-owned and within the
189
- same explicit request budget.
190
-
191
- ## Product-level planner guidance
192
-
193
- `createVideoChatHandler` constructs the planner prompt from the trusted template
194
- registry. Normal integrations do not build prompts or capabilities. Use the
195
- handler's `instructions` option for durable product-level direction such as a
196
- character, audience, domain, or answer style. The current user prompt and
197
- bounded prior turns are supplied separately by the SDK.
52
+ `answerQuestion` and `verifySession` above are functions supplied by **your app**.
53
+ Keep tenant lookup, retrieval, tool execution and answer policy there. The
54
+ callback receives the validated prompt, bounded prior conversation and an
55
+ abort signal. It must return one completed, nonempty string of at most 32,000
56
+ characters after trimming—not an event stream, agent object or partial answer.
57
+
58
+ The SDK waits up to 30 seconds and forwards cancellation. A failed, empty,
59
+ oversized or timed-out answer returns HTTP 502 with `answer_unavailable`;
60
+ request cancellation returns `aborted`. It does not silently replace your
61
+ assistant's failure with a different answer. Provider work that ignores the
62
+ signal may continue, so your assistant adapter must honor it.
63
+
64
+ The completed answer becomes the planner's sole factual source in input-only
65
+ mode. Planning still uses `streamText` to present that source as video; it is
66
+ not a second retrieval/tool run or a fact-checking guarantee. The video plan
67
+ streams after the answer has completed. Without `resolveAnswer`, the normal
68
+ planner answers from the prompt and conversation directly.
69
+
70
+ ## Video, speech and transcription
71
+
72
+ `generateVideo`, `searchMedia`, `generateSpeech` and `transcribe` are separate
73
+ optional callbacks. Their availability advertises the relevant capabilities;
74
+ changing providers does not require a new React interface.
75
+
76
+ `providers add video fal`, `google` or `runway` copies an app-owned REST reference
77
+ into `providers/video.ts`. `custom` supplies a callback skeleton. These names
78
+ are onboarding examples, not a core allowlist. Keep any other SDK dependency
79
+ inside your application's adapter.
80
+
81
+ Setup never overwrites an edited adapter. To switch an existing vendor, edit
82
+ `providers/video.ts` and the app manifest's `vanillasky.videoVendor` deliberately;
83
+ keep duration, timeout, concurrency and delivery settings together. No client
84
+ edit or SDK release is needed. Doctor follows that selected configuration.
85
+
86
+ The video callback receives the visual query plus `requestedDurationSec`,
87
+ `shotDirection`, orientation, `generatedLook`, `signal`, and an absolute
88
+ epoch-millisecond `deadlineAt`. Return browser-safe media such as
89
+ `{ type: "video", url, durationSec }`; report the actual delivered duration when
90
+ known. Keep `generatedClipDurationSec`, `mediaConcurrency` and
91
+ `generateVideoTimeoutMs` aligned with the adapter's model, supported duration,
92
+ resolution and account limits. A model-name change alone is not always enough.
93
+
94
+ The planner targets speech ending at least 0.8 seconds before each clip ends.
95
+ First-pass writing leaves additional headroom: a five-second clip targets six
96
+ ordinary words and one distinct idea, while repair can use up to eight words
97
+ when needed for meaning. These are authoring guides, not guarantees from a
98
+ text or voice model; the duration checks remain authoritative.
99
+ Compact numeric measurements get a conservative expansion estimate. Authoring
100
+ and repair request spoken numbers and units so short notation cannot conceal
101
+ long speech; the SDK does not translate or alter the provider's spoken text.
102
+ An oversized beat gets at most one bounded `narration-rewrite` call before
103
+ footage generation. If the rewrite fails or still cannot fit, no video job is
104
+ submitted for that beat: its complete original narration plays over a chapter.
105
+ Rewrites are instructed to preserve facts and qualifications; applications
106
+ should still evaluate meaning and timing with their actual models and voices.
107
+ Measured speech can overrun the estimate; playback recovers to a chapter
108
+ rather than looping or cutting off the sentence. Requested duration constrains
109
+ the paid submission; a valid returned duration describes the footage actually
110
+ available for playback. The mounted decoder also checks its physical duration.
111
+ Without reported duration, generated footage keeps its requested budget.
112
+
113
+ Stock search has its own bounded lookup deadline and no generated-video duration
114
+ cap. Return `durationSec` when known: the SDK selects footage first, then checks
115
+ the spoken beat against that duration. Unknown stock duration is checked by the
116
+ mounted decoder, not replaced with an unrelated video vendor's clip setting.
117
+ Neither path submits another video job to make narration fit.
118
+
119
+ `onDiagnostic` includes a `narration-rewrite` phase with elapsed work time, clip
120
+ budget and a fixed `rewritten`, `empty`, `oversized`, `timeout`, `provider-error`
121
+ or `cancelled` reason. It never includes the original or rewritten text. Keep
122
+ normal rewrite latency within its 2.5-second bound; shortening the first-pass
123
+ plan avoids that additional call in the common path.
124
+
125
+ Speech setup uses the optional xAI/AI SDK adapter. Transcription setup uses
126
+ Whisper via fal REST independently of the selected video vendor. Stock footage
127
+ uses `searchMedia`; AI-video mode never silently calls stock, and stock mode
128
+ does not spend on generated video.
129
+
130
+ ## Video delivery and cancellation
131
+
132
+ Direct references require an app-owned delivery callback. The starter's
133
+ `providers/video-delivery.ts` receives downloaded video bytes, job ID, duration
134
+ and signal. Replace it with your storage code, or implement its example upload
135
+ endpoint: `PUT` MP4 bytes to `VIDEO_UPLOAD_URL` with `VIDEO_STORAGE_TOKEN`, then
136
+ return a public HTTPS `{ url }`. VanillaSky does not host that endpoint.
137
+
138
+ Google video downloads require a private API key. Keep it server-side, strip
139
+ credentials when following off-origin redirects, and never pass the private
140
+ provider URI to the player. Copy temporary vendor outputs into storage with an
141
+ appropriate replay lifetime. Deliver H.264 MP4 with the moov atom first,
142
+ Content-Type/Content-Length, byte ranges and CORS. Access rules, retention and
143
+ deletion remain application responsibilities.
144
+
145
+ The references submit each paid job once, retain its ID and poll to a deadline.
146
+ Persist the ID through the helper's `onSubmitted` callback if jobs must survive
147
+ server restarts. Never automatically resubmit an ambiguous network failure;
148
+ check the provider dashboard first. Cancellation is best effort for fal and
149
+ Runway. Gemini Veo has no documented cancellation operation: accepted work may
150
+ finish and be billed even after local polling stops. No cancellation promises
151
+ a refund.
152
+
153
+ Initial policies are fal: 5s/480P, concurrency 3, 120s deadline; Google:
154
+ 6s/720p, concurrency 2, 360s; Runway: 5s/720p, concurrency 2, 180s. These are
155
+ editable settings, not measured latency guarantees. Google and Runway may take
156
+ minutes. Early media preparation enables progressive scene playback, not
157
+ real-time streaming from a provider that only returns completed jobs.
158
+
159
+ ## Completion and integration scope
160
+
161
+ Use `onComplete` for successful server-side completion and usage summaries;
162
+ it does not fire for terminal failure or cancellation. Use safe diagnostics
163
+ and `onError` for failures without exposing raw provider payloads to browsers.
164
+ Stored completed responses can be validated with `parseVideo` and replayed
165
+ without another generation.
166
+
167
+ This is a beta npm SDK with [best-effort support](../SUPPORT.md), not a hosted
168
+ generation service or a guarantee for every vendor/model combination. Offline
169
+ fixtures establish callback contracts; live model availability, output quality,
170
+ cost and latency require an explicitly budgeted check in your own account.
171
+ See [production](production.md) before exposing the endpoint publicly and
172
+ [customization](customization.md) for branding or application-owned controls.
@@ -75,20 +75,11 @@ planning uses an internal answer brief and shot descriptions. The runtime
75
75
  translates them into footage scenes and completes the answer at stream end,
76
76
  without asking the model for lifecycle commands.
77
77
 
78
- Handlers with an explicit custom `templates` registry keep the existing
79
- composition planner contract. A server-only planner emits
80
- validated `scene.add` or `plan.complete` parts. The runtime assigns sequences,
81
- IDs, terminal snapshots, and checksums. Generated HTML, React, JavaScript, CSS, component
82
- source, audio events, protocol envelopes, and unknown part types are rejected.
83
-
84
- A planner may add `placement: "closer"` to exactly one `scene.add`. The
85
- standard handler requires that closer by default, holds it outside the public
86
- event stream while body scenes continue, and commits it as the final scene.
87
- Only templates advertised for `jobs:[ask]` or `jobs:[payoff]` qualify. The
88
- placement marker is not part of `VideoScene` and never enters a replay
89
- snapshot. If the planner completes without a valid closer, the handler emits
90
- `plan_missing_closer` and uses `finishReason: "other"`; provider `length` and
91
- `content-filter` reasons remain unchanged.
78
+ The runtime owns validated scene additions, sequence IDs, terminal snapshots,
79
+ and checksums. The planned ending is reserved and committed after the body.
80
+ If no valid ending is available, the response reports a safe incomplete-plan
81
+ warning. Generated HTML, React, JavaScript, CSS, protocol envelopes, and unknown
82
+ planning parts are rejected.
92
83
 
93
84
  ## Resume
94
85
 
@@ -5,11 +5,11 @@ read [Media and voice](../media-and-audio.md).
5
5
 
6
6
  VanillaSky deliberately does not depend on a model provider or AI framework.
7
7
  Your server owns the model and credentials; `createVideoChatHandler` accepts
8
- `streamText` and `generateText` callbacks. The recommended adapter is the [AI SDK](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text),
8
+ `streamText` and `generateText` callbacks. One optional adapter is the [AI SDK](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text),
9
9
  which gives the application one `LanguageModel` interface across official,
10
10
  community, AI Gateway, OpenAI-compatible, and custom providers.
11
11
 
12
- ## Recommended: AI SDK
12
+ ## Optional: AI SDK
13
13
 
14
14
  Install the AI SDK plus the provider package your application chooses:
15
15
 
@@ -81,15 +81,17 @@ complete.
81
81
  ## Native or self-hosted providers
82
82
 
83
83
  The same chat contract supports a native provider without an AI SDK dependency.
84
+ `npx @vanillaskyai/video init --native` creates an editable Gemini REST example.
84
85
  Return an `AsyncIterable<string>` from `streamText`, or an object with
85
86
  `textStream` and optional completion metadata. Implement `generateText` for the
86
- small welcome, suggestion, and fallback narration tasks and return its text.
87
+ small welcome, suggestion, fallback narration, and bounded `narration-rewrite`
88
+ tasks and return its text.
87
89
  Infer each callback from `VideoChatHandlerOptions` so the adapter stays aligned
88
90
  with the public contract.
89
91
 
90
92
  Forward the supplied signal, preserve both prompt strings, and keep provider
91
- errors and credentials on the server. Retry only within an explicit time and
92
- spend budget before output is visible. The chat does not expose a durable
93
+ errors and credentials on the server. Do not automatically resubmit ambiguous
94
+ paid requests. The chat does not expose a durable
93
95
  stream-reconnect contract.
94
96
 
95
97
  ## Generated-video budget
@@ -105,18 +107,24 @@ never consumes the generated-video allowance. Retries inside your
105
107
  provider callback can incur additional charges; bound those separately. Never
106
108
  copy an untrusted request value into this application-owned option.
107
109
 
108
- Use `generateVideoTimeoutMs` for slower providers (integer `1`–`120000`, default
110
+ Use `generateVideoTimeoutMs` for slower providers (integer `1`–`600000`, default
109
111
  `15000`). Poll queued jobs only until the supplied signal aborts; submit once,
110
112
  record the provider job identifier, and cancel that job best-effort on abort.
111
113
  A disconnected browser or timed-out request does not prove the job was free.
112
114
  Reserve host-owned quotas before submission and retain uncertain attempts.
113
- Keep the host request deadline and client `timeoutMs` longer than the provider
114
- deadline. The SDK does not resume a completed queued job into a finished answer.
115
-
116
- For a limited offering, `VideoChat` accepts `generatedVideoLabel` and
117
- `generatedVideoDescription` to explain the generated-video choice in Settings.
118
- Set `showRecoveryNotice` to opt into a brief dismissible message when generated
119
- visuals fall back. These presentation props do not enforce limits or enable
115
+ Keep the host request deadline longer than the provider deadline. The default
116
+ client `timeoutMs` is `660000`; an explicit shorter override remains authoritative.
117
+ The SDK does not resume a completed queued job into a finished answer.
118
+
119
+ The video callback receives `requestedDurationSec`, `shotDirection`, `deadlineAt`
120
+ (epoch milliseconds), and `signal`. Return `durationSec` when known. Keep model,
121
+ duration, resolution, concurrency and timeout together in your editable adapter.
122
+ These longer deadlines accommodate queued providers; they do not make generation
123
+ real-time. The SDK streams ready scenes and prepares upcoming media progressively.
124
+
125
+ Set `VideoChat`'s `showRecoveryNotice` to opt into a brief dismissible message
126
+ when generated visuals fall back. Use an application-owned interface for custom
127
+ plan labels or controls. Presentation does not enforce spending limits or enable
120
128
  provider capabilities; the server remains authoritative.
121
129
 
122
130
  ## Application retrieval
package/docs/security.md CHANGED
@@ -1,4 +1,4 @@
1
- [← Documentation home](../README.md) · [Previous: Streaming protocol](streaming-protocol.md) · [Next: Errors and recovery →](errors.md)
1
+ [← Documentation home](../README.md) · [Previous: Streaming protocol](reference/protocol.md) · [Next: Errors and recovery →](errors.md)
2
2
 
3
3
  # Security
4
4
 
@@ -14,19 +14,6 @@ The SDK validates protocol shape; your application still owns identity, authoriz
14
14
  - Allowlist browser origins; CORS is not authentication.
15
15
  - Bound request bytes, media count, scene count, duration, tokens, concurrency, and cost.
16
16
  - Keep provider keys, system prompts, tools, signed-URL credentials, and admin tokens server-side.
17
- - Use the same generated template registry on the server and in React; the handler infers validation.
18
- - Treat every project-owned template as trusted application build code and
19
- review it before using the CLI. Normal `vanillasky templates list`,
20
- `vanillasky templates describe`, `vanillasky templates add`, `vanillasky templates sync`, and
21
- `vanillasky templates check` commands execute project template modules locally. This
22
- includes `vanillasky templates add` previews with `--dry-run` or `--diff`, because the
23
- CLI must derive the proposed browser and server registries. Resource and
24
- environment boundaries reduce accidental damage but are not a portable
25
- JavaScript sandbox.
26
- - Use `--builtin` with `list` or `describe` when you need the packaged catalog
27
- only. That view does not execute project template modules. Project template
28
- execution requires macOS, Linux, or WSL because Windows cannot provide the
29
- process-group cleanup guarantee used by these commands.
30
17
  - Restrict media domains, types, dimensions, bytes, redirects, and fetch timeouts.
31
18
  - Propagate cancellation and use timeouts for provider, media, persistence, and export work.
32
19
  - Return safe typed errors while logging private causes only in protected observability.