@ai-sdk/google 4.0.31 → 4.0.33
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 +24 -0
- package/dist/index.js +99 -79
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/google-video-model.ts +133 -85
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.33",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@ai-sdk/provider": "4.0.
|
|
39
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
38
|
+
"@ai-sdk/provider": "4.0.5",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.20"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/node": "22.19.19",
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AISDKError,
|
|
3
3
|
type Experimental_VideoModelV4,
|
|
4
|
+
type Experimental_VideoModelV4CallOptions as VideoModelV4CallOptions,
|
|
4
5
|
type Experimental_VideoModelV4File,
|
|
6
|
+
type Experimental_VideoModelV4OperationStartResult as VideoModelV4OperationStartResult,
|
|
7
|
+
type Experimental_VideoModelV4OperationStatusResult as VideoModelV4OperationStatusResult,
|
|
8
|
+
type SharedV4ProviderMetadata,
|
|
5
9
|
type SharedV4Warning,
|
|
6
10
|
} from '@ai-sdk/provider';
|
|
7
11
|
import {
|
|
8
12
|
combineHeaders,
|
|
9
13
|
convertUint8ArrayToBase64,
|
|
10
14
|
createJsonResponseHandler,
|
|
11
|
-
delay,
|
|
12
15
|
getFromApi,
|
|
13
16
|
isSameOrigin,
|
|
14
17
|
parseProviderOptions,
|
|
@@ -25,6 +28,8 @@ import {
|
|
|
25
28
|
} from './google-video-model-options';
|
|
26
29
|
import type { GoogleVideoModelId } from './google-video-settings';
|
|
27
30
|
|
|
31
|
+
type VideoModelV4 = Experimental_VideoModelV4;
|
|
32
|
+
|
|
28
33
|
interface GoogleVideoModelConfig {
|
|
29
34
|
provider: string;
|
|
30
35
|
baseURL: string;
|
|
@@ -37,27 +42,27 @@ interface GoogleVideoModelConfig {
|
|
|
37
42
|
}
|
|
38
43
|
|
|
39
44
|
function getFirstFrameImage(
|
|
40
|
-
options:
|
|
45
|
+
options: VideoModelV4CallOptions,
|
|
41
46
|
): Experimental_VideoModelV4File | undefined {
|
|
42
47
|
return options.frameImages?.find(frame => frame.frameType === 'first_frame')
|
|
43
48
|
?.image;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
function resolveStartImage(
|
|
47
|
-
options:
|
|
52
|
+
options: VideoModelV4CallOptions,
|
|
48
53
|
): Experimental_VideoModelV4File | undefined {
|
|
49
54
|
return getFirstFrameImage(options) ?? options.image;
|
|
50
55
|
}
|
|
51
56
|
|
|
52
57
|
function getLastFrameImage(
|
|
53
|
-
options:
|
|
58
|
+
options: VideoModelV4CallOptions,
|
|
54
59
|
): Experimental_VideoModelV4File | undefined {
|
|
55
60
|
return options.frameImages?.find(frame => frame.frameType === 'last_frame')
|
|
56
61
|
?.image;
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
function getInputReferences(
|
|
60
|
-
options:
|
|
65
|
+
options: VideoModelV4CallOptions,
|
|
61
66
|
): Array<Experimental_VideoModelV4File> | undefined {
|
|
62
67
|
if (options.frameImages != null && options.frameImages.length > 0) {
|
|
63
68
|
return undefined;
|
|
@@ -153,10 +158,14 @@ export class GoogleVideoModel implements Experimental_VideoModelV4 {
|
|
|
153
158
|
private readonly config: GoogleVideoModelConfig,
|
|
154
159
|
) {}
|
|
155
160
|
|
|
156
|
-
async
|
|
157
|
-
options: Parameters<
|
|
158
|
-
): Promise<
|
|
159
|
-
|
|
161
|
+
private async buildRequest(
|
|
162
|
+
options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],
|
|
163
|
+
): Promise<{
|
|
164
|
+
instances: Array<Record<string, unknown>>;
|
|
165
|
+
parameters: Record<string, unknown>;
|
|
166
|
+
warnings: SharedV4Warning[];
|
|
167
|
+
googleOptions: GoogleVideoModelOptions | undefined;
|
|
168
|
+
}> {
|
|
160
169
|
const warnings: SharedV4Warning[] = [];
|
|
161
170
|
|
|
162
171
|
const googleOptions = (await parseProviderOptions({
|
|
@@ -254,83 +263,25 @@ export class GoogleVideoModel implements Experimental_VideoModelV4 {
|
|
|
254
263
|
}
|
|
255
264
|
}
|
|
256
265
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
headers: combineHeaders(
|
|
260
|
-
await resolve(this.config.headers),
|
|
261
|
-
options.headers,
|
|
262
|
-
),
|
|
263
|
-
body: {
|
|
264
|
-
instances,
|
|
265
|
-
parameters,
|
|
266
|
-
},
|
|
267
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
268
|
-
googleOperationSchema,
|
|
269
|
-
),
|
|
270
|
-
failedResponseHandler: googleFailedResponseHandler,
|
|
271
|
-
abortSignal: options.abortSignal,
|
|
272
|
-
fetch: this.config.fetch,
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
const operationName = operation.name;
|
|
276
|
-
if (!operationName) {
|
|
277
|
-
throw new AISDKError({
|
|
278
|
-
name: 'GOOGLE_VIDEO_GENERATION_ERROR',
|
|
279
|
-
message: 'No operation name returned from API',
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const pollIntervalMs = googleOptions?.pollIntervalMs ?? 10000; // 10 seconds (per Google docs)
|
|
284
|
-
const pollTimeoutMs = googleOptions?.pollTimeoutMs ?? 600000; // 10 minutes
|
|
285
|
-
|
|
286
|
-
const startTime = Date.now();
|
|
287
|
-
let finalOperation = operation;
|
|
288
|
-
let responseHeaders: Record<string, string> | undefined;
|
|
289
|
-
|
|
290
|
-
while (!finalOperation.done) {
|
|
291
|
-
if (Date.now() - startTime > pollTimeoutMs) {
|
|
292
|
-
throw new AISDKError({
|
|
293
|
-
name: 'GOOGLE_VIDEO_GENERATION_TIMEOUT',
|
|
294
|
-
message: `Video generation timed out after ${pollTimeoutMs}ms`,
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
await delay(pollIntervalMs);
|
|
299
|
-
|
|
300
|
-
if (options.abortSignal?.aborted) {
|
|
301
|
-
throw new AISDKError({
|
|
302
|
-
name: 'GOOGLE_VIDEO_GENERATION_ABORTED',
|
|
303
|
-
message: 'Video generation request was aborted',
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const { value: statusOperation, responseHeaders: pollHeaders } =
|
|
308
|
-
await getFromApi({
|
|
309
|
-
url: `${this.config.baseURL}/${operationName}`,
|
|
310
|
-
validateUrl: false,
|
|
311
|
-
headers: combineHeaders(
|
|
312
|
-
await resolve(this.config.headers),
|
|
313
|
-
options.headers,
|
|
314
|
-
),
|
|
315
|
-
successfulResponseHandler: createJsonResponseHandler(
|
|
316
|
-
googleOperationSchema,
|
|
317
|
-
),
|
|
318
|
-
failedResponseHandler: googleFailedResponseHandler,
|
|
319
|
-
abortSignal: options.abortSignal,
|
|
320
|
-
fetch: this.config.fetch,
|
|
321
|
-
});
|
|
322
|
-
|
|
323
|
-
finalOperation = statusOperation;
|
|
324
|
-
responseHeaders = pollHeaders;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (finalOperation.error) {
|
|
328
|
-
throw new AISDKError({
|
|
329
|
-
name: 'GOOGLE_VIDEO_GENERATION_FAILED',
|
|
330
|
-
message: `Video generation failed: ${finalOperation.error.message}`,
|
|
331
|
-
});
|
|
332
|
-
}
|
|
266
|
+
return { instances, parameters, warnings, googleOptions };
|
|
267
|
+
}
|
|
333
268
|
|
|
269
|
+
private async buildCompletedResult(
|
|
270
|
+
finalOperation: z.infer<typeof googleOperationSchema>,
|
|
271
|
+
responseHeaders: Record<string, string> | undefined,
|
|
272
|
+
warnings: SharedV4Warning[],
|
|
273
|
+
currentDate: Date,
|
|
274
|
+
): Promise<{
|
|
275
|
+
status: 'completed';
|
|
276
|
+
videos: Array<{ type: 'url'; url: string; mediaType: string }>;
|
|
277
|
+
warnings: SharedV4Warning[];
|
|
278
|
+
providerMetadata: SharedV4ProviderMetadata;
|
|
279
|
+
response: {
|
|
280
|
+
timestamp: Date;
|
|
281
|
+
modelId: string;
|
|
282
|
+
headers: Record<string, string> | undefined;
|
|
283
|
+
};
|
|
284
|
+
}> {
|
|
334
285
|
const response = finalOperation.response;
|
|
335
286
|
if (
|
|
336
287
|
!response?.generateVideoResponse?.generatedSamples ||
|
|
@@ -379,6 +330,7 @@ export class GoogleVideoModel implements Experimental_VideoModelV4 {
|
|
|
379
330
|
}
|
|
380
331
|
|
|
381
332
|
return {
|
|
333
|
+
status: 'completed',
|
|
382
334
|
videos,
|
|
383
335
|
warnings,
|
|
384
336
|
response: {
|
|
@@ -393,6 +345,102 @@ export class GoogleVideoModel implements Experimental_VideoModelV4 {
|
|
|
393
345
|
},
|
|
394
346
|
};
|
|
395
347
|
}
|
|
348
|
+
|
|
349
|
+
async doStart(
|
|
350
|
+
options: Parameters<NonNullable<VideoModelV4['doStart']>>[0],
|
|
351
|
+
): Promise<VideoModelV4OperationStartResult> {
|
|
352
|
+
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
353
|
+
const { instances, parameters, warnings } =
|
|
354
|
+
await this.buildRequest(options);
|
|
355
|
+
|
|
356
|
+
const { value: operation, responseHeaders } = await postJsonToApi({
|
|
357
|
+
url: `${this.config.baseURL}/models/${this.modelId}:predictLongRunning`,
|
|
358
|
+
headers: combineHeaders(
|
|
359
|
+
await resolve(this.config.headers),
|
|
360
|
+
options.headers,
|
|
361
|
+
),
|
|
362
|
+
body: {
|
|
363
|
+
instances,
|
|
364
|
+
parameters,
|
|
365
|
+
},
|
|
366
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
367
|
+
googleOperationSchema,
|
|
368
|
+
),
|
|
369
|
+
failedResponseHandler: googleFailedResponseHandler,
|
|
370
|
+
abortSignal: options.abortSignal,
|
|
371
|
+
fetch: this.config.fetch,
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
const operationName = operation.name;
|
|
375
|
+
if (!operationName) {
|
|
376
|
+
throw new AISDKError({
|
|
377
|
+
name: 'GOOGLE_VIDEO_GENERATION_ERROR',
|
|
378
|
+
message: 'No operation name returned from API',
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
operation: { operationName },
|
|
384
|
+
warnings,
|
|
385
|
+
response: {
|
|
386
|
+
timestamp: currentDate,
|
|
387
|
+
modelId: this.modelId,
|
|
388
|
+
headers: responseHeaders,
|
|
389
|
+
},
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async doStatus(
|
|
394
|
+
options: Parameters<NonNullable<VideoModelV4['doStatus']>>[0],
|
|
395
|
+
): Promise<VideoModelV4OperationStatusResult> {
|
|
396
|
+
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
397
|
+
const { operationName } = options.operation as { operationName: string };
|
|
398
|
+
|
|
399
|
+
const { value: statusOperation, responseHeaders } = await getFromApi({
|
|
400
|
+
url: `${this.config.baseURL}/${operationName}`,
|
|
401
|
+
validateUrl: false,
|
|
402
|
+
headers: combineHeaders(
|
|
403
|
+
await resolve(this.config.headers),
|
|
404
|
+
options.headers,
|
|
405
|
+
),
|
|
406
|
+
successfulResponseHandler: createJsonResponseHandler(
|
|
407
|
+
googleOperationSchema,
|
|
408
|
+
),
|
|
409
|
+
failedResponseHandler: googleFailedResponseHandler,
|
|
410
|
+
abortSignal: options.abortSignal,
|
|
411
|
+
fetch: this.config.fetch,
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
if (!statusOperation.done) {
|
|
415
|
+
return {
|
|
416
|
+
status: 'pending',
|
|
417
|
+
response: {
|
|
418
|
+
timestamp: currentDate,
|
|
419
|
+
modelId: this.modelId,
|
|
420
|
+
headers: responseHeaders,
|
|
421
|
+
},
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (statusOperation.error) {
|
|
426
|
+
return {
|
|
427
|
+
status: 'error' as const,
|
|
428
|
+
error: `Video generation failed: ${statusOperation.error.message}`,
|
|
429
|
+
response: {
|
|
430
|
+
timestamp: currentDate,
|
|
431
|
+
modelId: this.modelId,
|
|
432
|
+
headers: responseHeaders,
|
|
433
|
+
},
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return this.buildCompletedResult(
|
|
438
|
+
statusOperation,
|
|
439
|
+
responseHeaders,
|
|
440
|
+
[],
|
|
441
|
+
currentDate,
|
|
442
|
+
);
|
|
443
|
+
}
|
|
396
444
|
}
|
|
397
445
|
|
|
398
446
|
const googleOperationSchema = z.object({
|