Skip to content

Commit 1bfbe33

Browse files
tombeckenhamclaude
andcommitted
feat(examples): provider optgroups in video model dropdown, use grok-imagine-video-1.5-preview
Groups the video model dropdown by provider (fal.ai / xAI direct) the same way the image generator does, adds the model version to the direct-xAI entry names, and switches them to the grok-imagine-video-1.5-preview model. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 62be2d7 commit 1bfbe33

3 files changed

Lines changed: 39 additions & 18 deletions

File tree

examples/ts-react-media/src/components/VideoGenerator.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ export default function VideoGenerator({
4242
const pollingRefs = useRef<Map<string, NodeJS.Timeout>>(new Map())
4343

4444
const filteredModels = VIDEO_MODELS.filter((m) => m.mode === mode)
45+
const falModels = filteredModels.filter((m) => m.provider === 'fal')
46+
const xaiModels = filteredModels.filter((m) => m.provider === 'xai')
4547

4648
useEffect(() => {
4749
if (initialImageUrl) {
@@ -166,8 +168,8 @@ export default function VideoGenerator({
166168
}))
167169

168170
// Poll keyed by the UI model id, not result.model: the direct-xAI
169-
// entries share one adapter model ('grok-imagine-video'), so
170-
// result.model wouldn't identify the card (or the adapter) uniquely.
171+
// entries share one adapter model ('grok-imagine-video-1.5-preview'),
172+
// so result.model wouldn't identify the card (or the adapter) uniquely.
171173
const interval = setInterval(() => {
172174
pollStatus(result.jobId, modelId)
173175
}, 4000)
@@ -253,11 +255,20 @@ export default function VideoGenerator({
253255
className="w-full px-4 py-3 bg-gray-800 border border-gray-700 rounded-lg text-white focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent disabled:opacity-50"
254256
>
255257
<option value="all">All Models</option>
256-
{filteredModels.map((model) => (
257-
<option key={model.id} value={model.id}>
258-
{model.name}
259-
</option>
260-
))}
258+
<optgroup label="fal.ai">
259+
{falModels.map((model) => (
260+
<option key={model.id} value={model.id}>
261+
{model.name}
262+
</option>
263+
))}
264+
</optgroup>
265+
<optgroup label="xAI (direct)">
266+
{xaiModels.map((model) => (
267+
<option key={model.id} value={model.id}>
268+
{model.name}
269+
</option>
270+
))}
271+
</optgroup>
261272
</select>
262273
</div>
263274

examples/ts-react-media/src/lib/models.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,60 +79,70 @@ export const VIDEO_MODELS = [
7979
name: 'Kling 3 Pro (Text-to-Video)',
8080
description: 'High-quality text-to-video generation',
8181
mode: 'text-to-video' as const,
82+
provider: 'fal' as const,
8283
},
8384
{
8485
id: 'fal-ai/kling-video/v3/pro/image-to-video',
8586
name: 'Kling 3 Pro (Image-to-Video)',
8687
description: 'Animate images with Kling',
8788
mode: 'image-to-video' as const,
89+
provider: 'fal' as const,
8890
},
8991
{
9092
id: 'fal-ai/veo3.1',
9193
name: 'Veo 3.1 (Text-to-Video)',
9294
description: 'Google Veo text-to-video',
9395
mode: 'text-to-video' as const,
96+
provider: 'fal' as const,
9497
},
9598
{
9699
id: 'fal-ai/veo3.1/image-to-video',
97100
name: 'Veo 3.1 (Image-to-Video)',
98101
description: 'Google Veo image-to-video',
99102
mode: 'image-to-video' as const,
103+
provider: 'fal' as const,
100104
},
101105
{
102106
id: 'xai/grok-imagine-video/text-to-video',
103107
name: 'Grok Imagine Video (Text-to-Video)',
104108
description: 'xAI video generation from text',
105109
mode: 'text-to-video' as const,
110+
provider: 'fal' as const,
106111
},
107112
{
108113
id: 'xai/grok-imagine-video/image-to-video',
109114
name: 'Grok Imagine Video (Image-to-Video)',
110115
description: 'xAI animate images to video',
111116
mode: 'image-to-video' as const,
117+
provider: 'fal' as const,
112118
},
113119
{
114-
id: 'grok-imagine-video',
115-
name: 'Grok Imagine Video (xAI Direct, Text-to-Video)',
120+
id: 'grok-imagine-video-1.5-preview',
121+
name: 'Grok Imagine Video 1.5 (Text-to-Video)',
116122
description: 'xAI Imagine API via the native grokVideo adapter',
117123
mode: 'text-to-video' as const,
124+
provider: 'xai' as const,
118125
},
119126
{
120-
id: 'grok-imagine-video/image-to-video',
121-
name: 'Grok Imagine Video (xAI Direct, Image-to-Video)',
127+
id: 'grok-imagine-video-1.5-preview/image-to-video',
128+
name: 'Grok Imagine Video 1.5 (Image-to-Video)',
122129
description: 'Animate a starting frame via the native grokVideo adapter',
123130
mode: 'image-to-video' as const,
131+
provider: 'xai' as const,
124132
},
125133
{
126134
id: 'fal-ai/ltx-2.3/text-to-video/fast',
127135
name: 'LTX-2.3 Fast (Text-to-Video)',
128136
description: 'Fast text-to-video generation',
129137
mode: 'text-to-video' as const,
138+
provider: 'fal' as const,
130139
},
131140
{
132141
id: 'fal-ai/ltx-2.3/image-to-video/fast',
133142
name: 'LTX-2.3 Fast (Image-to-Video)',
134143
description: 'Fast image-to-video animation',
135144
mode: 'image-to-video' as const,
145+
provider: 'fal' as const,
136146
},
137147
] as const
138148

examples/ts-react-media/src/lib/server-functions.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ function asImageToVideoPrompt(
7474
*/
7575
function videoAdapterForModel(model: string) {
7676
if (
77-
model === 'grok-imagine-video' ||
78-
model === 'grok-imagine-video/image-to-video'
77+
model === 'grok-imagine-video-1.5-preview' ||
78+
model === 'grok-imagine-video-1.5-preview/image-to-video'
7979
) {
80-
return grokVideo('grok-imagine-video')
80+
return grokVideo('grok-imagine-video-1.5-preview')
8181
}
8282
return falVideo(model)
8383
}
@@ -229,13 +229,13 @@ export const createVideoJobFn = createServerFn({ method: 'POST' })
229229
},
230230
})
231231
}
232-
case 'grok-imagine-video': {
232+
case 'grok-imagine-video-1.5-preview': {
233233
// Direct xAI Imagine API (XAI_API_KEY) — no fal in between. Sizing is
234234
// an "aspectRatio_resolution" template; durations are 1-15 integer
235235
// seconds. Completed jobs report usage.unitsBilled (billed seconds)
236236
// and usage.cost (exact USD).
237237
return generateVideo({
238-
adapter: grokVideo('grok-imagine-video'),
238+
adapter: grokVideo('grok-imagine-video-1.5-preview'),
239239
prompt: asTextPrompt(data.prompt),
240240
size: '16:9_720p',
241241
duration: 5,
@@ -279,12 +279,12 @@ export const createVideoJobFn = createServerFn({ method: 'POST' })
279279
},
280280
})
281281
}
282-
case 'grok-imagine-video/image-to-video': {
282+
case 'grok-imagine-video-1.5-preview/image-to-video': {
283283
// Direct xAI Imagine API. The starting frame is supplied as an image
284284
// prompt part (asImageToVideoPrompt requires one); the grokVideo
285285
// adapter forwards it to the Imagine endpoint as the start frame.
286286
return generateVideo({
287-
adapter: grokVideo('grok-imagine-video'),
287+
adapter: grokVideo('grok-imagine-video-1.5-preview'),
288288
prompt: asImageToVideoPrompt(data.prompt),
289289
size: '16:9_720p',
290290
duration: 5,

0 commit comments

Comments
 (0)