@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.
Files changed (89) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/PUBLIC-API.md +83 -79
  3. package/README.md +20 -15
  4. package/dist/assets/vanillasky-logo.svg +151 -0
  5. package/dist/{builtin-server-KB7FKF6A.js → builtin-server-CUYPIDE7.js} +2 -2
  6. package/dist/check-runtime.js +1 -1
  7. package/dist/{chunk-2PYO6VAC.js → chunk-2DOLF4QN.js} +1 -43
  8. package/dist/{chunk-GAIOHGNR.js → chunk-2OKB27TG.js} +42 -45
  9. package/dist/{chunk-K746NUIP.js → chunk-2USVB3CY.js} +80 -29
  10. package/dist/{chunk-RE4IMWJR.js → chunk-3VRMKFM7.js} +87 -14
  11. package/dist/{chunk-JNN3EYVP.js → chunk-4UNKZEAT.js} +46 -46
  12. package/dist/{chunk-2XT4MZ76.js → chunk-APQKY6P3.js} +36 -3
  13. package/dist/{chunk-LLPMVDJZ.js → chunk-L7QGGKJ2.js} +69 -38
  14. package/dist/{chunk-RGF452LL.js → chunk-OWBT45EN.js} +1 -1
  15. package/dist/{chunk-LKBZX7GV.js → chunk-PP3MCPN4.js} +4 -4
  16. package/dist/chunk-ZD2VTUYR.js +28 -0
  17. package/dist/cli.js +131 -24
  18. package/dist/{compose-video-PD6LKKRK.js → compose-video-2NFH4DZY.js} +3 -3
  19. package/dist/{events-B6qS1Lsb.d.ts → events-BQ6z264n.d.ts} +1 -1
  20. package/dist/index.d.ts +5 -67
  21. package/dist/index.js +2 -4
  22. package/dist/{kit-8g46H2RZ.d.ts → kit-tQnCPMOM.d.ts} +1 -1
  23. package/dist/react.d.ts +33 -53
  24. package/dist/react.js +982 -648
  25. package/dist/server.d.ts +11 -13
  26. package/dist/server.js +170 -81
  27. package/dist/template-catalog.js +1 -1
  28. package/dist/templates.d.ts +3 -3
  29. package/dist/test.d.ts +2 -2
  30. package/dist/test.js +3 -3
  31. package/dist/{text-stream-ROTNGSD4.js → text-stream-54LXABJW.js} +1 -1
  32. package/dist/{types-2wHBqtg8.d.ts → types-CEh9eUFu.d.ts} +1 -1
  33. package/dist/{types-DrABlRa7.d.ts → types-DWFO6qca.d.ts} +1 -1
  34. package/docs/agent-integration.md +9 -3
  35. package/docs/architecture.md +8 -10
  36. package/docs/concepts.md +16 -40
  37. package/docs/custom-templates.md +27 -23
  38. package/docs/customization.md +23 -55
  39. package/docs/errors.md +58 -68
  40. package/docs/getting-started.md +21 -14
  41. package/docs/immersive-interface.md +87 -0
  42. package/docs/media-and-audio.md +2 -2
  43. package/docs/performance.md +69 -0
  44. package/docs/persistence.md +12 -27
  45. package/docs/production.md +2 -2
  46. package/docs/provider-integration.md +11 -5
  47. package/docs/reference/design-system.html +115 -0
  48. package/docs/reference/provider-adapters.md +37 -89
  49. package/docs/security.md +1 -1
  50. package/docs/streaming-protocol.md +2 -2
  51. package/examples/custom-template/README.md +6 -6
  52. package/package.json +6 -7
  53. package/registry/items/barChart.json +2 -2
  54. package/registry/items/bigNumber.json +2 -2
  55. package/registry/items/brandMessage.json +2 -2
  56. package/registry/items/cardList.json +2 -2
  57. package/registry/items/codeEditor.json +2 -2
  58. package/registry/items/ctaLogo.json +2 -2
  59. package/registry/items/ctaMedia.json +2 -2
  60. package/registry/items/incomingCall.json +2 -2
  61. package/registry/items/media.json +2 -2
  62. package/registry/items/milestone.json +2 -2
  63. package/registry/items/notification.json +2 -2
  64. package/registry/items/phoneMockup.json +2 -2
  65. package/registry/items/problemSolution.json +2 -2
  66. package/registry/items/progressRing.json +2 -2
  67. package/registry/items/promptInput.json +2 -2
  68. package/registry/items/reaction.json +2 -2
  69. package/registry/items/reviewStack.json +2 -2
  70. package/registry/items/steps.json +2 -2
  71. package/registry/items/terminal.json +2 -2
  72. package/registry/items/testimonial.json +2 -2
  73. package/registry/items/tripleStats.json +2 -2
  74. package/registry/items/tweet.json +2 -2
  75. package/registry/items/webMockup.json +2 -2
  76. package/starters/video-chat/.env.example +4 -2
  77. package/starters/video-chat/README.md +17 -5
  78. package/starters/video-chat/index.html +2 -1
  79. package/starters/video-chat/package.json +2 -4
  80. package/starters/video-chat/providers/speech.ts +20 -0
  81. package/starters/video-chat/providers/video.ts +66 -0
  82. package/starters/video-chat/providers.ts +3 -0
  83. package/starters/video-chat/server.ts +4 -80
  84. package/starters/video-chat/stock.ts +114 -99
  85. package/styles/video-chat.css +650 -246
  86. package/dist/chunk-SKRGRKHY.js +0 -142
  87. package/dist/state-DZcKuS32.d.ts +0 -3
  88. package/docs/branding-and-personalization.md +0 -87
  89. package/examples/custom-template/supplied-media.tsx +0 -92
@@ -1,11 +1,11 @@
1
1
  # Secure LLM provider adapters
2
2
 
3
3
  This page covers the planner boundary. For Pexels and other visual providers,
4
- read [Media and audio](../media-and-audio.md#media-providers).
4
+ 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
- Your server owns the model and credentials; `createVideoHandler` accepts one
8
- small `streamText` callback. The recommended adapter is the [AI SDK](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text),
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),
9
9
  which gives the application one `LanguageModel` interface across official,
10
10
  community, AI Gateway, OpenAI-compatible, and custom providers.
11
11
 
@@ -19,14 +19,23 @@ npm install ai @ai-sdk/anthropic
19
19
 
20
20
  ```ts
21
21
  import { anthropic } from "@ai-sdk/anthropic";
22
- import { streamText } from "ai";
23
- import { createVideoHandler } from "@vanillaskyai/video/server";
22
+ import { generateText, streamText } from "ai";
23
+ import { createVideoChatHandler } from "@vanillaskyai/video/server";
24
24
 
25
25
  const modelId = process.env.ANTHROPIC_MODEL;
26
26
  if (!modelId) throw new Error("Set ANTHROPIC_MODEL in the server environment");
27
27
 
28
- export const POST = createVideoHandler({
28
+ export const POST = createVideoChatHandler({
29
29
  authorize: verifySession,
30
+ generateText: async ({ systemPrompt, userPrompt, signal }) => {
31
+ const result = await generateText({
32
+ model: anthropic(modelId),
33
+ system: systemPrompt,
34
+ prompt: userPrompt,
35
+ abortSignal: signal,
36
+ });
37
+ return result.text;
38
+ },
30
39
  streamText: ({ systemPrompt, userPrompt, signal }) => streamText({
31
40
  model: anthropic(modelId),
32
41
  system: systemPrompt,
@@ -67,92 +76,31 @@ replace that per-line validator with whole-response structured output: motion
67
76
  streaming intentionally renders the first scene before the full composition is
68
77
  complete.
69
78
 
70
- ## Advanced: native provider loops
71
-
72
- Use the lower-level callback directly when the AI SDK does not expose a
73
- provider-specific feature you need. `streamText` may return either an
74
- `AsyncIterable<string>` or an object with `textStream` plus optional
75
- `finishReason`, `rawFinishReason`, `usage`, `providerMetadata`, and
76
- response/final-step metadata. Requested model IDs are read from the final
77
- step's `model.modelId`; resolved IDs are read from response metadata. Prefer the
78
- richer form when the native provider exposes completion metadata.
79
-
80
- Provider retries remain host-owned. Retry only within an explicit request and
81
- time budget, and never silently restart after visible output unless the host
82
- has validated durable resume storage.
83
-
84
- ### OpenAI Responses API
85
-
86
- ```ts
87
- import OpenAI from "openai";
88
- import { createVideoHandler } from "@vanillaskyai/video/server";
89
-
90
- const apiKey = process.env.OPENAI_API_KEY;
91
- const model = process.env.OPENAI_MODEL;
92
- if (!apiKey || !model) throw new Error("Set OPENAI_API_KEY and OPENAI_MODEL");
79
+ ## Native or self-hosted providers
93
80
 
94
- const openai = new OpenAI({ apiKey });
81
+ The same chat contract supports a native provider without an AI SDK dependency.
82
+ Return an `AsyncIterable<string>` from `streamText`, or an object with
83
+ `textStream` and optional completion metadata. Implement `generateText` for the
84
+ small welcome, suggestion, and fallback narration tasks and return its text.
85
+ Infer each callback from `VideoChatHandlerOptions` so the adapter stays aligned
86
+ with the public contract.
95
87
 
96
- export const POST = createVideoHandler({
97
- authorize: verifySession,
98
- streamText: async function* ({ systemPrompt, userPrompt, signal }) {
99
- const stream = await openai.responses.create({
100
- model,
101
- input: [
102
- { role: "system", content: systemPrompt },
103
- { role: "user", content: userPrompt },
104
- ],
105
- stream: true,
106
- }, { signal });
107
-
108
- for await (const event of stream) {
109
- if (event.type === "response.output_text.delta") yield event.delta;
110
- }
111
- },
112
- });
113
- ```
88
+ Forward the supplied signal, preserve both prompt strings, and keep provider
89
+ errors and credentials on the server. Retry only within an explicit time and
90
+ spend budget before output is visible. The chat does not expose a durable
91
+ stream-reconnect contract.
114
92
 
115
- OpenAI documents the typed `response.output_text.delta` event in its
116
- [Responses streaming guide](https://developers.openai.com/api/docs/guides/streaming-responses).
117
-
118
- ### Anthropic Messages API
119
-
120
- ```ts
121
- import Anthropic from "@anthropic-ai/sdk";
122
- import { createVideoHandler } from "@vanillaskyai/video/server";
123
-
124
- const apiKey = process.env.ANTHROPIC_API_KEY;
125
- const model = process.env.ANTHROPIC_MODEL;
126
- if (!apiKey || !model) throw new Error("Set ANTHROPIC_API_KEY and ANTHROPIC_MODEL");
127
-
128
- const anthropic = new Anthropic({ apiKey });
129
-
130
- export const POST = createVideoHandler({
131
- authorize: verifySession,
132
- streamText: async function* ({ systemPrompt, userPrompt, signal }) {
133
- const stream = anthropic.messages.stream({
134
- model,
135
- max_tokens: 4096,
136
- system: systemPrompt,
137
- messages: [{ role: "user", content: userPrompt }],
138
- }, { signal });
139
-
140
- for await (const event of stream) {
141
- if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
142
- yield event.delta.text;
143
- }
144
- }
145
- },
146
- });
147
- ```
93
+ ## Generated-video budget
148
94
 
149
- Anthropic documents `content_block_delta` and `text_delta` in its
150
- [Messages streaming guide](https://platform.claude.com/docs/en/build-with-claude/streaming).
95
+ Set `maxGeneratedVideos` on `createVideoChatHandler` to a nonnegative safe integer
96
+ (default `5`). This is a per-response attempt limit for full mode, including the
97
+ reserved first shot and failures. Use `0` to keep the configured full mode on
98
+ stock footage. Stock lookup is independent of this limit. Retries inside your
99
+ provider callback can incur additional charges; bound those separately. Never
100
+ copy an untrusted request value into this application-owned option.
151
101
 
152
- ## Optional web fetch and other tools
102
+ ## Application retrieval
153
103
 
154
- Keep tools server-side and outside the SDK core. Fetch or search before motion
155
- generation, append only the approved grounded result to `input`, and
156
- record provenance separately. Apply domain allowlists, SSRF protection,
157
- timeouts, redirect limits, and response-size limits. Do not give a model a
158
- general-purpose fetch tool unless the application truly needs one.
104
+ Fetch or search approved context in the application before asking the chat.
105
+ Include only authorized facts in the prompt or conversation and record
106
+ provenance separately. Keep retrieval tools and private URLs server-side.
package/docs/security.md CHANGED
@@ -7,7 +7,7 @@ The SDK validates protocol shape; your application still owns identity, authoriz
7
7
  ## Required server controls
8
8
 
9
9
  - Authenticate the user and tenant before reading the prompt body.
10
- - `createVideoChatHandler` and the lower-level `createVideoHandler` require an
10
+ - `createVideoChatHandler` requires an
11
11
  explicit `authorize` policy. The
12
12
  `authorize: "none"` escape hatch is for intentionally non-public in-process
13
13
  tests only; do not use it on a billable generation route.
@@ -2,7 +2,7 @@
2
2
 
3
3
  # Streaming protocol
4
4
 
5
- `createVideoHandler` returns validated server-sent events and `useVideo` consumes
5
+ `createVideoChatHandler` returns validated server-sent events and `useVideoChat` consumes
6
6
  them. Normal applications do not parse SSE or reduce events themselves.
7
7
 
8
8
  The internal protocol is deterministic and versioned. A run starts once, adds or
@@ -10,6 +10,6 @@ patches only complete validated scenes, and terminates exactly once as complete,
10
10
  error, or aborted. Every event has a run ID and sequence. Completion carries the
11
11
  authoritative snapshot and drift-detection checksum.
12
12
 
13
- Persist `video.video` when replay, editing, or export is required. Played scenes
13
+ Persist completed `chat.turns` video values when replay is required. Played scenes
14
14
  are immutable; patches may affect only future scenes. See the [protocol reference](reference/protocol.md)
15
15
  when implementing infrastructure rather than an ordinary SDK integration.
@@ -8,12 +8,12 @@ templates sync` and `npx vanillasky templates check`.
8
8
  | --- | --- |
9
9
  | [Minimal text](minimal-text.tsx) | One short, grounded idea should fill the scene. |
10
10
  | [Structured data](structured-data.tsx) | An exact metric and its change are the central proof. |
11
- | [Supplied media](supplied-media.tsx) | An image already supplied by the application is the strongest evidence. |
12
11
 
13
- All three use only `defineTemplate` from the public
12
+ Both use only `defineTemplate` from the public
14
13
  `@vanillaskyai/video/templates` entry point. They include selection guidance,
15
14
  JSON Schema defaults, a named example, deterministic progress-based motion,
16
- safe-zone layout, and portrait/landscape handling. The media reference uses
17
- `format: "supplied-image"` for an image that must appear in
18
- `VideoInput.suppliedMedia`; use `format: "uri"` for another approved media or
19
- link URL governed by the same server media policy.
15
+ safe-zone layout, and portrait/landscape handling. Connect the generated browser
16
+ registry through `VideoChat` options and the server registry through
17
+ `createVideoChatHandler`, as shown in [Custom templates](../../docs/custom-templates.md).
18
+ For media-backed answers, start from a built-in template using
19
+ `npx vanillasky templates add media` and configure the handler's `searchMedia`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vanillaskyai/video",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "description": "Open-source voice-and-video chat SDK for AI applications.",
5
5
  "keywords": [
6
6
  "video-chat",
@@ -36,6 +36,9 @@
36
36
  "starters/video-chat/index.html",
37
37
  "starters/video-chat/package.json",
38
38
  "starters/video-chat/server.ts",
39
+ "starters/video-chat/providers.ts",
40
+ "starters/video-chat/providers/speech.ts",
41
+ "starters/video-chat/providers/video.ts",
39
42
  "starters/video-chat/src/main.tsx",
40
43
  "starters/video-chat/stock.ts",
41
44
  "starters/video-chat/tsconfig.json",
@@ -90,9 +93,6 @@
90
93
  "./video-chat.css": "./styles/video-chat.css"
91
94
  },
92
95
  "scripts": {
93
- "acceptance:live": "tsx scripts/acceptance/run-live.ts",
94
- "acceptance:review": "tsx scripts/acceptance/review.ts",
95
- "acceptance:replay": "tsx scripts/acceptance/run-replay.ts",
96
96
  "browser:install": "playwright install chromium firefox webkit",
97
97
  "browser:test": "playwright test",
98
98
  "build": "tsup",
@@ -112,7 +112,8 @@
112
112
  "verify:package-size": "tsx scripts/verify-package-size.ts",
113
113
  "verify:api": "npm run build && node scripts/verify-public-api-surface.mjs",
114
114
  "verify:package": "npm run build && node scripts/verify-packed-package.mjs",
115
- "release:build": "node scripts/release-build.mjs"
115
+ "release:build": "node scripts/release-build.mjs",
116
+ "acceptance:chat": "tsx scripts/acceptance/run.ts"
116
117
  },
117
118
  "peerDependencies": {
118
119
  "react": ">=18 <20",
@@ -131,7 +132,6 @@
131
132
  }
132
133
  },
133
134
  "devDependencies": {
134
- "@anthropic-ai/sdk": "^0.120.0",
135
135
  "@eslint/js": "^9.39.1",
136
136
  "@playwright/test": "1.62.0",
137
137
  "@testing-library/react": "^16.3.0",
@@ -142,7 +142,6 @@
142
142
  "eslint": "^9.39.1",
143
143
  "globals": "^16.5.0",
144
144
  "jsdom": "^26.1.0",
145
- "openai": "^7.5.0",
146
145
  "react": "^19.2.8",
147
146
  "react-dom": "^19.2.8",
148
147
  "tsup": "^8.5.1",
@@ -164,7 +164,7 @@
164
164
  "mediaKeyword": {
165
165
  "type": "string",
166
166
  "title": "Background search keyword",
167
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
167
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
168
168
  "format": "stock-media-keyword",
169
169
  "default": ""
170
170
  },
@@ -183,7 +183,7 @@
183
183
  "mediaPoster": {
184
184
  "type": "string",
185
185
  "title": "Background poster image",
186
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
186
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
187
187
  "format": "uri",
188
188
  "default": ""
189
189
  },
@@ -149,7 +149,7 @@
149
149
  "mediaKeyword": {
150
150
  "type": "string",
151
151
  "title": "Background search keyword",
152
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
152
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
153
153
  "format": "stock-media-keyword",
154
154
  "default": ""
155
155
  },
@@ -168,7 +168,7 @@
168
168
  "mediaPoster": {
169
169
  "type": "string",
170
170
  "title": "Background poster image",
171
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
171
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
172
172
  "format": "uri",
173
173
  "default": ""
174
174
  },
@@ -89,7 +89,7 @@
89
89
  "mediaKeyword": {
90
90
  "type": "string",
91
91
  "title": "Background search keyword",
92
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
92
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
93
93
  "format": "stock-media-keyword",
94
94
  "default": ""
95
95
  },
@@ -108,7 +108,7 @@
108
108
  "mediaPoster": {
109
109
  "type": "string",
110
110
  "title": "Background poster image",
111
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
111
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
112
112
  "format": "uri",
113
113
  "default": ""
114
114
  },
@@ -134,7 +134,7 @@
134
134
  "mediaKeyword": {
135
135
  "type": "string",
136
136
  "title": "Background search keyword",
137
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
137
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
138
138
  "format": "stock-media-keyword",
139
139
  "default": ""
140
140
  },
@@ -153,7 +153,7 @@
153
153
  "mediaPoster": {
154
154
  "type": "string",
155
155
  "title": "Background poster image",
156
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
156
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
157
157
  "format": "uri",
158
158
  "default": ""
159
159
  },
@@ -110,7 +110,7 @@
110
110
  "mediaKeyword": {
111
111
  "type": "string",
112
112
  "title": "Background search keyword",
113
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
113
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
114
114
  "format": "stock-media-keyword",
115
115
  "default": ""
116
116
  },
@@ -129,7 +129,7 @@
129
129
  "mediaPoster": {
130
130
  "type": "string",
131
131
  "title": "Background poster image",
132
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
132
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
133
133
  "format": "uri",
134
134
  "default": ""
135
135
  },
@@ -86,7 +86,7 @@
86
86
  "mediaKeyword": {
87
87
  "type": "string",
88
88
  "title": "Background search keyword",
89
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
89
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
90
90
  "default": ""
91
91
  },
92
92
  "mediaType": {
@@ -104,7 +104,7 @@
104
104
  "mediaPoster": {
105
105
  "type": "string",
106
106
  "title": "Background poster image",
107
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
107
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
108
108
  "format": "uri",
109
109
  "default": ""
110
110
  },
@@ -110,7 +110,7 @@
110
110
  "mediaKeyword": {
111
111
  "type": "string",
112
112
  "title": "Background search keyword",
113
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
113
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
114
114
  "format": "stock-media-keyword",
115
115
  "default": ""
116
116
  },
@@ -129,7 +129,7 @@
129
129
  "mediaPoster": {
130
130
  "type": "string",
131
131
  "title": "Background poster image",
132
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
132
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
133
133
  "format": "uri",
134
134
  "default": ""
135
135
  },
@@ -101,7 +101,7 @@
101
101
  "mediaKeyword": {
102
102
  "type": "string",
103
103
  "title": "Background search keyword",
104
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
104
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
105
105
  "format": "stock-media-keyword",
106
106
  "default": ""
107
107
  },
@@ -120,7 +120,7 @@
120
120
  "mediaPoster": {
121
121
  "type": "string",
122
122
  "title": "Background poster image",
123
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
123
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
124
124
  "format": "uri",
125
125
  "default": ""
126
126
  },
@@ -102,7 +102,7 @@
102
102
  "mediaKeyword": {
103
103
  "type": "string",
104
104
  "title": "Background search keyword",
105
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
105
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
106
106
  "format": "stock-media-keyword",
107
107
  "default": ""
108
108
  },
@@ -121,7 +121,7 @@
121
121
  "mediaPoster": {
122
122
  "type": "string",
123
123
  "title": "Background poster image",
124
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
124
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
125
125
  "format": "uri",
126
126
  "default": ""
127
127
  },
@@ -134,7 +134,7 @@
134
134
  "mediaKeyword": {
135
135
  "type": "string",
136
136
  "title": "Background search keyword",
137
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
137
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
138
138
  "format": "stock-media-keyword",
139
139
  "default": ""
140
140
  },
@@ -153,7 +153,7 @@
153
153
  "mediaPoster": {
154
154
  "type": "string",
155
155
  "title": "Background poster image",
156
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
156
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
157
157
  "format": "uri",
158
158
  "default": ""
159
159
  },
@@ -108,7 +108,7 @@
108
108
  "mediaKeyword": {
109
109
  "type": "string",
110
110
  "title": "Background search keyword",
111
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
111
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
112
112
  "format": "stock-media-keyword",
113
113
  "default": ""
114
114
  },
@@ -127,7 +127,7 @@
127
127
  "mediaPoster": {
128
128
  "type": "string",
129
129
  "title": "Background poster image",
130
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
130
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
131
131
  "format": "uri",
132
132
  "default": ""
133
133
  },
@@ -185,7 +185,7 @@
185
185
  "mediaKeyword": {
186
186
  "type": "string",
187
187
  "title": "Background search keyword",
188
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
188
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
189
189
  "default": ""
190
190
  },
191
191
  "mediaType": {
@@ -203,7 +203,7 @@
203
203
  "mediaPoster": {
204
204
  "type": "string",
205
205
  "title": "Background poster image",
206
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
206
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
207
207
  "format": "uri",
208
208
  "default": ""
209
209
  },
@@ -116,7 +116,7 @@
116
116
  "mediaKeyword": {
117
117
  "type": "string",
118
118
  "title": "Background search keyword",
119
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
119
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
120
120
  "format": "stock-media-keyword",
121
121
  "default": ""
122
122
  },
@@ -135,7 +135,7 @@
135
135
  "mediaPoster": {
136
136
  "type": "string",
137
137
  "title": "Background poster image",
138
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
138
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
139
139
  "format": "uri",
140
140
  "default": ""
141
141
  },
@@ -123,7 +123,7 @@
123
123
  "mediaKeyword": {
124
124
  "type": "string",
125
125
  "title": "Background search keyword",
126
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
126
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
127
127
  "format": "stock-media-keyword",
128
128
  "default": ""
129
129
  },
@@ -142,7 +142,7 @@
142
142
  "mediaPoster": {
143
143
  "type": "string",
144
144
  "title": "Background poster image",
145
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
145
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
146
146
  "format": "uri",
147
147
  "default": ""
148
148
  },
@@ -80,7 +80,7 @@
80
80
  "mediaKeyword": {
81
81
  "type": "string",
82
82
  "title": "Background search keyword",
83
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
83
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
84
84
  "format": "stock-media-keyword",
85
85
  "default": ""
86
86
  },
@@ -99,7 +99,7 @@
99
99
  "mediaPoster": {
100
100
  "type": "string",
101
101
  "title": "Background poster image",
102
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
102
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
103
103
  "format": "uri",
104
104
  "default": ""
105
105
  },
@@ -82,7 +82,7 @@
82
82
  "reactionTag": {
83
83
  "type": "string",
84
84
  "title": "Reaction tag",
85
- "description": "Pexels meme search intent. Pick from the punchline/problem copy first, then the overall video topic.",
85
+ "description": "Stock-media search intent. Pick from the punchline/problem copy first, then the overall video topic.",
86
86
  "enum": [
87
87
  "launch",
88
88
  "productLaunch",
@@ -123,7 +123,7 @@
123
123
  "mediaUrl": {
124
124
  "type": "string",
125
125
  "title": "Reaction clip",
126
- "description": "Resolved Pexels MP4 URL.",
126
+ "description": "Resolved stock-video URL.",
127
127
  "format": "uri",
128
128
  "default": ""
129
129
  },
@@ -149,7 +149,7 @@
149
149
  "mediaKeyword": {
150
150
  "type": "string",
151
151
  "title": "Background search keyword",
152
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
152
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
153
153
  "format": "stock-media-keyword",
154
154
  "default": ""
155
155
  },
@@ -168,7 +168,7 @@
168
168
  "mediaPoster": {
169
169
  "type": "string",
170
170
  "title": "Background poster image",
171
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
171
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
172
172
  "format": "uri",
173
173
  "default": ""
174
174
  },
@@ -135,7 +135,7 @@
135
135
  "mediaKeyword": {
136
136
  "type": "string",
137
137
  "title": "Background search keyword",
138
- "description": "2-4 word English term for Pexels stock-footage search (auto-fills mediaUrl).",
138
+ "description": "2-4 word English term for stock-media search (auto-fills mediaUrl).",
139
139
  "format": "stock-media-keyword",
140
140
  "default": ""
141
141
  },
@@ -154,7 +154,7 @@
154
154
  "mediaPoster": {
155
155
  "type": "string",
156
156
  "title": "Background poster image",
157
- "description": "Still image URL shown while a video backdrop is decoding its first frame. Auto-filled from Pexels' thumbnail when fillPexelsUrls sets a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
157
+ "description": "Still image URL shown while a video backdrop is decoding its first frame. A media resolver can supply a poster alongside a video mediaUrl. Hides the gradient flash that would otherwise appear in the ~50–400ms gap between a <video> mounting and decoding its first frame.",
158
158
  "format": "uri",
159
159
  "default": ""
160
160
  },