@ai-sdk/google 4.0.67 → 4.0.68
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 +13 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +305 -170
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/google-batch.ts +193 -12
- package/src/google-provider.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.68",
|
|
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.14",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.40"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.1",
|
package/src/google-batch.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InvalidArgumentError,
|
|
3
3
|
InvalidResponseDataError,
|
|
4
|
+
UnsupportedFunctionalityError,
|
|
4
5
|
type Experimental_BatchV4 as BatchV4,
|
|
5
6
|
type Experimental_BatchV4CancelResult as BatchV4CancelResult,
|
|
6
7
|
type Experimental_BatchV4Error as BatchV4Error,
|
|
@@ -10,9 +11,12 @@ import {
|
|
|
10
11
|
type Experimental_BatchV4OperationOptions as BatchV4OperationOptions,
|
|
11
12
|
type Experimental_BatchV4StartResult as BatchV4StartResult,
|
|
12
13
|
type Experimental_BatchV4Status as BatchV4Status,
|
|
13
|
-
type
|
|
14
|
+
type Experimental_ImageBatchV4Request as ImageBatchV4Request,
|
|
14
15
|
type Experimental_BatchV4StartOptions as BatchV4StartOptions,
|
|
15
16
|
type LanguageModelV4GenerateResult,
|
|
17
|
+
type ImageModelV4Result,
|
|
18
|
+
type LanguageModelV4Prompt,
|
|
19
|
+
type SharedV4Warning,
|
|
16
20
|
} from '@ai-sdk/provider';
|
|
17
21
|
import {
|
|
18
22
|
combineHeaders,
|
|
@@ -23,11 +27,13 @@ import {
|
|
|
23
27
|
getFromApi,
|
|
24
28
|
lazySchema,
|
|
25
29
|
normalizeBatchRequestCounts,
|
|
30
|
+
parseProviderOptions,
|
|
26
31
|
postJsonToApi,
|
|
27
32
|
postToApi,
|
|
28
33
|
resolve,
|
|
29
34
|
safeValidateTypes,
|
|
30
35
|
zodSchema,
|
|
36
|
+
convertToBase64,
|
|
31
37
|
type InferSchema,
|
|
32
38
|
type ResponseHandler,
|
|
33
39
|
} from '@ai-sdk/provider-utils';
|
|
@@ -39,7 +45,12 @@ import {
|
|
|
39
45
|
responseSchema,
|
|
40
46
|
type GoogleLanguageModelConfig,
|
|
41
47
|
} from './google-language-model';
|
|
42
|
-
import
|
|
48
|
+
import {
|
|
49
|
+
googleLanguageModelOptions,
|
|
50
|
+
type GoogleModelId,
|
|
51
|
+
} from './google-language-model-options';
|
|
52
|
+
import type { GoogleImageModelId } from './google-image-settings';
|
|
53
|
+
import { googleImageModelOptionsSchema } from './google-image-model-options';
|
|
43
54
|
|
|
44
55
|
const googleBatchInputFileMaxBytes = 2 * 1024 * 1024 * 1024;
|
|
45
56
|
const googleBatchInlineCreationMaxBytes = 20_000_000;
|
|
@@ -47,7 +58,25 @@ const supportedGoogleBatchContentTypes = new Set<
|
|
|
47
58
|
LanguageModelV4GenerateResult['content'][number]['type']
|
|
48
59
|
>(['text', 'reasoning', 'source', 'tool-call', 'tool-result']);
|
|
49
60
|
|
|
50
|
-
type
|
|
61
|
+
type GoogleImageBatchRequest = ImageBatchV4Request<GoogleImageModelId>;
|
|
62
|
+
type GoogleBatchModelIds = {
|
|
63
|
+
readonly text: GoogleModelId;
|
|
64
|
+
readonly image: GoogleImageModelId;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function assertSupportedBatchRequests(
|
|
68
|
+
requests: BatchV4StartOptions<GoogleBatchModelIds>['requests'],
|
|
69
|
+
) {
|
|
70
|
+
for (const request of requests) {
|
|
71
|
+
const requestType = request.type;
|
|
72
|
+
if (requestType !== 'text' && requestType !== 'image') {
|
|
73
|
+
throw new UnsupportedFunctionalityError({
|
|
74
|
+
functionality: `batch request type: ${requestType}`,
|
|
75
|
+
message: `The Google Batch API does not support batch requests with type "${requestType}".`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
51
80
|
|
|
52
81
|
const googleRpcStatusSchema = z.object({
|
|
53
82
|
code: z.union([z.number(), z.string()]).nullish(),
|
|
@@ -150,7 +179,7 @@ const googleBatchResponsePreviewSchema = lazySchema(() =>
|
|
|
150
179
|
),
|
|
151
180
|
);
|
|
152
181
|
|
|
153
|
-
export class GoogleBatch implements BatchV4<
|
|
182
|
+
export class GoogleBatch implements BatchV4<GoogleBatchModelIds> {
|
|
154
183
|
readonly specificationVersion = 'v4' as const;
|
|
155
184
|
readonly provider: string;
|
|
156
185
|
readonly supportedUrls: Record<string, RegExp[]>;
|
|
@@ -169,8 +198,9 @@ export class GoogleBatch implements BatchV4<{ readonly text: GoogleModelId }> {
|
|
|
169
198
|
}
|
|
170
199
|
|
|
171
200
|
async doStartBatch(
|
|
172
|
-
options: BatchV4StartOptions<
|
|
201
|
+
options: BatchV4StartOptions<GoogleBatchModelIds>,
|
|
173
202
|
): Promise<BatchV4StartResult> {
|
|
203
|
+
assertSupportedBatchRequests(options.requests);
|
|
174
204
|
const modelId = getGoogleBatchModelId(options.requests);
|
|
175
205
|
const warnings: BatchV4StartResult['warnings'] = [];
|
|
176
206
|
const displayName = `ai-sdk-batch-${this.batchGenerateId()}`;
|
|
@@ -196,11 +226,14 @@ export class GoogleBatch implements BatchV4<{ readonly text: GoogleModelId }> {
|
|
|
196
226
|
let fileParts: string[] | undefined;
|
|
197
227
|
|
|
198
228
|
for (const request of options.requests) {
|
|
199
|
-
const preparedRequest =
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
229
|
+
const preparedRequest =
|
|
230
|
+
request.type === 'text'
|
|
231
|
+
? await GoogleLanguageModel.prepareRequest({
|
|
232
|
+
modelId: request.modelId,
|
|
233
|
+
config: this.batchConfig,
|
|
234
|
+
options: request.options,
|
|
235
|
+
})
|
|
236
|
+
: await this.prepareImageRequest(request);
|
|
204
237
|
const inlinedRequest = {
|
|
205
238
|
request: preparedRequest.args,
|
|
206
239
|
metadata: { key: request.id },
|
|
@@ -602,6 +635,16 @@ export class GoogleBatch implements BatchV4<{ readonly text: GoogleModelId }> {
|
|
|
602
635
|
warnings: [],
|
|
603
636
|
providerOptionsNames: ['google'],
|
|
604
637
|
});
|
|
638
|
+
const imageResult = convertGoogleImageBatchResult(result);
|
|
639
|
+
if (imageResult != null) {
|
|
640
|
+
yield {
|
|
641
|
+
type: 'image',
|
|
642
|
+
id: line.key,
|
|
643
|
+
status: 'succeeded',
|
|
644
|
+
result: imageResult,
|
|
645
|
+
};
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
605
648
|
const unsupportedPart = result.content.find(
|
|
606
649
|
part => !supportedGoogleBatchContentTypes.has(part.type),
|
|
607
650
|
);
|
|
@@ -625,6 +668,108 @@ export class GoogleBatch implements BatchV4<{ readonly text: GoogleModelId }> {
|
|
|
625
668
|
}
|
|
626
669
|
}
|
|
627
670
|
|
|
671
|
+
private async prepareImageRequest(request: GoogleImageBatchRequest) {
|
|
672
|
+
const { prompt, n, size, aspectRatio, seed, files, mask, providerOptions } =
|
|
673
|
+
request.options;
|
|
674
|
+
const warnings: SharedV4Warning[] = [];
|
|
675
|
+
|
|
676
|
+
if (mask != null) {
|
|
677
|
+
throw new UnsupportedFunctionalityError({
|
|
678
|
+
functionality: 'mask-based image editing in Google batches',
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
if (n > 1) {
|
|
682
|
+
throw new UnsupportedFunctionalityError({
|
|
683
|
+
functionality: 'multiple images per Google batch request',
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (size != null) {
|
|
687
|
+
warnings.push({
|
|
688
|
+
type: 'unsupported',
|
|
689
|
+
feature: 'size',
|
|
690
|
+
details:
|
|
691
|
+
'This model does not support the `size` option. Use `aspectRatio` instead.',
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const userContent: Extract<
|
|
696
|
+
LanguageModelV4Prompt[number],
|
|
697
|
+
{ role: 'user' }
|
|
698
|
+
>['content'] = [];
|
|
699
|
+
if (prompt != null) userContent.push({ type: 'text', text: prompt });
|
|
700
|
+
for (const file of files ?? []) {
|
|
701
|
+
userContent.push(
|
|
702
|
+
file.type === 'url'
|
|
703
|
+
? {
|
|
704
|
+
type: 'file',
|
|
705
|
+
data: { type: 'url', url: new URL(file.url) },
|
|
706
|
+
mediaType: 'image/*',
|
|
707
|
+
}
|
|
708
|
+
: {
|
|
709
|
+
type: 'file',
|
|
710
|
+
data: { type: 'data', data: file.data },
|
|
711
|
+
mediaType: file.mediaType,
|
|
712
|
+
},
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const googleImageOptions = await parseProviderOptions({
|
|
717
|
+
provider: 'google',
|
|
718
|
+
providerOptions,
|
|
719
|
+
schema: googleImageModelOptionsSchema,
|
|
720
|
+
});
|
|
721
|
+
const {
|
|
722
|
+
responseModalities: _responseModalities,
|
|
723
|
+
imageConfig: userImageConfig,
|
|
724
|
+
...passthroughGoogleOptions
|
|
725
|
+
} = (await parseProviderOptions({
|
|
726
|
+
provider: 'google',
|
|
727
|
+
providerOptions,
|
|
728
|
+
schema: googleLanguageModelOptions,
|
|
729
|
+
})) ?? {};
|
|
730
|
+
const preparedGoogleOptions = await parseProviderOptions({
|
|
731
|
+
provider: 'google',
|
|
732
|
+
providerOptions: {
|
|
733
|
+
google: {
|
|
734
|
+
...passthroughGoogleOptions,
|
|
735
|
+
responseModalities: ['IMAGE'],
|
|
736
|
+
imageConfig:
|
|
737
|
+
aspectRatio != null || userImageConfig != null
|
|
738
|
+
? {
|
|
739
|
+
...userImageConfig,
|
|
740
|
+
...(aspectRatio != null ? { aspectRatio } : {}),
|
|
741
|
+
}
|
|
742
|
+
: undefined,
|
|
743
|
+
},
|
|
744
|
+
},
|
|
745
|
+
schema: googleLanguageModelOptions,
|
|
746
|
+
});
|
|
747
|
+
|
|
748
|
+
const prepared = await GoogleLanguageModel.prepareRequest({
|
|
749
|
+
modelId: request.modelId,
|
|
750
|
+
config: this.batchConfig,
|
|
751
|
+
options: {
|
|
752
|
+
prompt: [{ role: 'user', content: userContent }],
|
|
753
|
+
seed,
|
|
754
|
+
providerOptions: {
|
|
755
|
+
google: preparedGoogleOptions ?? { responseModalities: ['IMAGE'] },
|
|
756
|
+
},
|
|
757
|
+
tools:
|
|
758
|
+
googleImageOptions?.googleSearch != null
|
|
759
|
+
? [
|
|
760
|
+
{
|
|
761
|
+
type: 'provider',
|
|
762
|
+
id: 'google.google_search',
|
|
763
|
+
name: 'google_search',
|
|
764
|
+
args: googleImageOptions.googleSearch,
|
|
765
|
+
},
|
|
766
|
+
]
|
|
767
|
+
: undefined,
|
|
768
|
+
},
|
|
769
|
+
});
|
|
770
|
+
return { ...prepared, warnings: [...warnings, ...prepared.warnings] };
|
|
771
|
+
}
|
|
772
|
+
|
|
628
773
|
private async getHeaders(headers?: Record<string, string | undefined>) {
|
|
629
774
|
return combineHeaders(
|
|
630
775
|
this.batchConfig.headers
|
|
@@ -748,8 +893,8 @@ const googleUploadUrlResponseHandler: ResponseHandler<string> = async ({
|
|
|
748
893
|
};
|
|
749
894
|
|
|
750
895
|
function getGoogleBatchModelId(
|
|
751
|
-
requests:
|
|
752
|
-
): GoogleModelId {
|
|
896
|
+
requests: BatchV4StartOptions<GoogleBatchModelIds>['requests'],
|
|
897
|
+
): GoogleModelId | GoogleImageModelId {
|
|
753
898
|
const modelId = requests[0]?.modelId;
|
|
754
899
|
|
|
755
900
|
if (modelId == null) {
|
|
@@ -771,3 +916,39 @@ function getGoogleBatchModelId(
|
|
|
771
916
|
|
|
772
917
|
return modelId;
|
|
773
918
|
}
|
|
919
|
+
|
|
920
|
+
function convertGoogleImageBatchResult(
|
|
921
|
+
result: LanguageModelV4GenerateResult,
|
|
922
|
+
): ImageModelV4Result | undefined {
|
|
923
|
+
const images = result.content.flatMap(part =>
|
|
924
|
+
part.type === 'file' &&
|
|
925
|
+
part.mediaType.startsWith('image/') &&
|
|
926
|
+
part.data.type === 'data'
|
|
927
|
+
? [convertToBase64(part.data.data)]
|
|
928
|
+
: [],
|
|
929
|
+
);
|
|
930
|
+
if (images.length === 0) return undefined;
|
|
931
|
+
|
|
932
|
+
const googleMetadata =
|
|
933
|
+
(result.providerMetadata?.google as Record<string, unknown> | undefined) ??
|
|
934
|
+
{};
|
|
935
|
+
return {
|
|
936
|
+
images,
|
|
937
|
+
warnings: result.warnings,
|
|
938
|
+
providerMetadata: {
|
|
939
|
+
google: { ...googleMetadata, images: images.map(() => ({})) },
|
|
940
|
+
},
|
|
941
|
+
response: {
|
|
942
|
+
timestamp: new Date(),
|
|
943
|
+
modelId: result.response?.modelId ?? '',
|
|
944
|
+
headers: result.response?.headers,
|
|
945
|
+
},
|
|
946
|
+
usage: {
|
|
947
|
+
inputTokens: result.usage.inputTokens.total,
|
|
948
|
+
outputTokens: result.usage.outputTokens.total,
|
|
949
|
+
totalTokens:
|
|
950
|
+
(result.usage.inputTokens.total ?? 0) +
|
|
951
|
+
(result.usage.outputTokens.total ?? 0),
|
|
952
|
+
},
|
|
953
|
+
};
|
|
954
|
+
}
|
package/src/google-provider.ts
CHANGED
|
@@ -61,7 +61,10 @@ export interface GoogleProvider extends ProviderV4 {
|
|
|
61
61
|
|
|
62
62
|
chat(modelId: GoogleModelId): LanguageModelV4;
|
|
63
63
|
|
|
64
|
-
experimental_batch(): BatchV4<{
|
|
64
|
+
experimental_batch(): BatchV4<{
|
|
65
|
+
text: GoogleModelId;
|
|
66
|
+
image: GoogleImageModelId;
|
|
67
|
+
}>;
|
|
65
68
|
|
|
66
69
|
/**
|
|
67
70
|
* Creates a model for image generation.
|