@ai-sdk/google 4.0.0-beta.1 → 4.0.0-beta.11
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 +66 -0
- package/dist/index.d.mts +31 -14
- package/dist/index.d.ts +31 -14
- package/dist/index.js +97 -31
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +94 -28
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +11 -7
- package/dist/internal/index.d.ts +11 -7
- package/dist/internal/index.js +49 -18
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +46 -15
- package/dist/internal/index.mjs.map +1 -1
- package/docs/15-google-generative-ai.mdx +30 -3
- package/package.json +3 -3
- package/src/convert-google-generative-ai-usage.ts +2 -2
- package/src/convert-to-google-generative-ai-messages.ts +23 -2
- package/src/google-generative-ai-embedding-model.ts +42 -13
- package/src/google-generative-ai-embedding-options.ts +24 -0
- package/src/google-generative-ai-image-model.ts +14 -14
- package/src/google-generative-ai-language-model.ts +65 -44
- package/src/google-generative-ai-prompt.ts +9 -0
- package/src/google-generative-ai-video-model.ts +7 -7
- package/src/google-prepare-tools.ts +6 -6
- package/src/google-provider.ts +18 -18
- package/src/map-google-generative-ai-finish-reason.ts +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LanguageModelV4Usage } from '@ai-sdk/provider';
|
|
2
2
|
|
|
3
3
|
export type GoogleGenerativeAIUsageMetadata = {
|
|
4
4
|
promptTokenCount?: number | null;
|
|
@@ -11,7 +11,7 @@ export type GoogleGenerativeAIUsageMetadata = {
|
|
|
11
11
|
|
|
12
12
|
export function convertGoogleGenerativeAIUsage(
|
|
13
13
|
usage: GoogleGenerativeAIUsageMetadata | undefined | null,
|
|
14
|
-
):
|
|
14
|
+
): LanguageModelV4Usage {
|
|
15
15
|
if (usage == null) {
|
|
16
16
|
return {
|
|
17
17
|
inputTokens: {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
LanguageModelV4Prompt,
|
|
3
3
|
UnsupportedFunctionalityError,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import { convertToBase64 } from '@ai-sdk/provider-utils';
|
|
11
11
|
|
|
12
12
|
export function convertToGoogleGenerativeAIMessages(
|
|
13
|
-
prompt:
|
|
13
|
+
prompt: LanguageModelV4Prompt,
|
|
14
14
|
options?: { isGemmaModel?: boolean; providerOptionsName?: string },
|
|
15
15
|
): GoogleGenerativeAIPrompt {
|
|
16
16
|
const systemInstructionParts: Array<{ text: string }> = [];
|
|
@@ -112,6 +112,24 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
+
case 'reasoning-file': {
|
|
116
|
+
if (part.data instanceof URL) {
|
|
117
|
+
throw new UnsupportedFunctionalityError({
|
|
118
|
+
functionality:
|
|
119
|
+
'File data URLs in assistant messages are not supported',
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
inlineData: {
|
|
125
|
+
mimeType: part.mediaType,
|
|
126
|
+
data: convertToBase64(part.data),
|
|
127
|
+
},
|
|
128
|
+
thought: true,
|
|
129
|
+
thoughtSignature,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
115
133
|
case 'file': {
|
|
116
134
|
if (part.data instanceof URL) {
|
|
117
135
|
throw new UnsupportedFunctionalityError({
|
|
@@ -125,6 +143,9 @@ export function convertToGoogleGenerativeAIMessages(
|
|
|
125
143
|
mimeType: part.mediaType,
|
|
126
144
|
data: convertToBase64(part.data),
|
|
127
145
|
},
|
|
146
|
+
...(providerOpts?.thought === true
|
|
147
|
+
? { thought: true }
|
|
148
|
+
: {}),
|
|
128
149
|
thoughtSignature,
|
|
129
150
|
};
|
|
130
151
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
EmbeddingModelV4,
|
|
3
3
|
TooManyEmbeddingValuesForCallError,
|
|
4
4
|
} from '@ai-sdk/provider';
|
|
5
5
|
import {
|
|
@@ -26,8 +26,8 @@ type GoogleGenerativeAIEmbeddingConfig = {
|
|
|
26
26
|
fetch?: FetchFunction;
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export class GoogleGenerativeAIEmbeddingModel implements
|
|
30
|
-
readonly specificationVersion = '
|
|
29
|
+
export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV4 {
|
|
30
|
+
readonly specificationVersion = 'v4';
|
|
31
31
|
readonly modelId: GoogleGenerativeAIEmbeddingModelId;
|
|
32
32
|
readonly maxEmbeddingsPerCall = 2048;
|
|
33
33
|
readonly supportsParallelCalls = true;
|
|
@@ -50,8 +50,8 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
50
50
|
headers,
|
|
51
51
|
abortSignal,
|
|
52
52
|
providerOptions,
|
|
53
|
-
}: Parameters<
|
|
54
|
-
Awaited<ReturnType<
|
|
53
|
+
}: Parameters<EmbeddingModelV4['doEmbed']>[0]): Promise<
|
|
54
|
+
Awaited<ReturnType<EmbeddingModelV4['doEmbed']>>
|
|
55
55
|
> {
|
|
56
56
|
// Parse provider options
|
|
57
57
|
const googleOptions = await parseProviderOptions({
|
|
@@ -74,8 +74,26 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
74
74
|
headers,
|
|
75
75
|
);
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
const multimodalContent = googleOptions?.content;
|
|
78
|
+
|
|
79
|
+
if (
|
|
80
|
+
multimodalContent != null &&
|
|
81
|
+
multimodalContent.length !== values.length
|
|
82
|
+
) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`The number of multimodal content entries (${multimodalContent.length}) must match the number of values (${values.length}).`,
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// For single embeddings, use the single endpoint
|
|
78
89
|
if (values.length === 1) {
|
|
90
|
+
const valueParts = multimodalContent?.[0];
|
|
91
|
+
const textPart = values[0] ? [{ text: values[0] }] : [];
|
|
92
|
+
const parts =
|
|
93
|
+
valueParts != null
|
|
94
|
+
? [...textPart, ...valueParts]
|
|
95
|
+
: [{ text: values[0] }];
|
|
96
|
+
|
|
79
97
|
const {
|
|
80
98
|
responseHeaders,
|
|
81
99
|
value: response,
|
|
@@ -86,7 +104,7 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
86
104
|
body: {
|
|
87
105
|
model: `models/${this.modelId}`,
|
|
88
106
|
content: {
|
|
89
|
-
parts
|
|
107
|
+
parts,
|
|
90
108
|
},
|
|
91
109
|
outputDimensionality: googleOptions?.outputDimensionality,
|
|
92
110
|
taskType: googleOptions?.taskType,
|
|
@@ -107,6 +125,7 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
107
125
|
};
|
|
108
126
|
}
|
|
109
127
|
|
|
128
|
+
// For multiple values, use the batch endpoint
|
|
110
129
|
const {
|
|
111
130
|
responseHeaders,
|
|
112
131
|
value: response,
|
|
@@ -115,12 +134,22 @@ export class GoogleGenerativeAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
115
134
|
url: `${this.config.baseURL}/models/${this.modelId}:batchEmbedContents`,
|
|
116
135
|
headers: mergedHeaders,
|
|
117
136
|
body: {
|
|
118
|
-
requests: values.map(value =>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
137
|
+
requests: values.map((value, index) => {
|
|
138
|
+
const valueParts = multimodalContent?.[index];
|
|
139
|
+
const textPart = value ? [{ text: value }] : [];
|
|
140
|
+
return {
|
|
141
|
+
model: `models/${this.modelId}`,
|
|
142
|
+
content: {
|
|
143
|
+
role: 'user',
|
|
144
|
+
parts:
|
|
145
|
+
valueParts != null
|
|
146
|
+
? [...textPart, ...valueParts]
|
|
147
|
+
: [{ text: value }],
|
|
148
|
+
},
|
|
149
|
+
outputDimensionality: googleOptions?.outputDimensionality,
|
|
150
|
+
taskType: googleOptions?.taskType,
|
|
151
|
+
};
|
|
152
|
+
}),
|
|
124
153
|
},
|
|
125
154
|
failedResponseHandler: googleFailedResponseHandler,
|
|
126
155
|
successfulResponseHandler: createJsonResponseHandler(
|
|
@@ -7,8 +7,19 @@ import { z } from 'zod/v4';
|
|
|
7
7
|
|
|
8
8
|
export type GoogleGenerativeAIEmbeddingModelId =
|
|
9
9
|
| 'gemini-embedding-001'
|
|
10
|
+
| 'gemini-embedding-2-preview'
|
|
10
11
|
| (string & {});
|
|
11
12
|
|
|
13
|
+
const googleEmbeddingContentPartSchema = z.union([
|
|
14
|
+
z.object({ text: z.string() }),
|
|
15
|
+
z.object({
|
|
16
|
+
inlineData: z.object({
|
|
17
|
+
mimeType: z.string(),
|
|
18
|
+
data: z.string(),
|
|
19
|
+
}),
|
|
20
|
+
}),
|
|
21
|
+
]);
|
|
22
|
+
|
|
12
23
|
export const googleEmbeddingModelOptions = lazySchema(() =>
|
|
13
24
|
zodSchema(
|
|
14
25
|
z.object({
|
|
@@ -42,6 +53,19 @@ export const googleEmbeddingModelOptions = lazySchema(() =>
|
|
|
42
53
|
'CODE_RETRIEVAL_QUERY',
|
|
43
54
|
])
|
|
44
55
|
.optional(),
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Optional. Per-value multimodal content parts for embedding non-text
|
|
59
|
+
* content (images, video, PDF, audio). Each entry corresponds to the
|
|
60
|
+
* embedding value at the same index and its parts are merged with the
|
|
61
|
+
* text value in the request. Use `null` for entries that are text-only.
|
|
62
|
+
*
|
|
63
|
+
* The array length must match the number of values being embedded. In
|
|
64
|
+
* the case of a single embedding, the array length must be 1.
|
|
65
|
+
*/
|
|
66
|
+
content: z
|
|
67
|
+
.array(z.array(googleEmbeddingContentPartSchema).min(1).nullable())
|
|
68
|
+
.optional(),
|
|
45
69
|
}),
|
|
46
70
|
),
|
|
47
71
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
ImageModelV4,
|
|
3
|
+
LanguageModelV4Prompt,
|
|
4
|
+
SharedV4Warning,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
6
|
import {
|
|
7
7
|
combineHeaders,
|
|
@@ -37,8 +37,8 @@ interface GoogleGenerativeAIImageModelConfig {
|
|
|
37
37
|
};
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
export class GoogleGenerativeAIImageModel implements
|
|
41
|
-
readonly specificationVersion = '
|
|
40
|
+
export class GoogleGenerativeAIImageModel implements ImageModelV4 {
|
|
41
|
+
readonly specificationVersion = 'v4';
|
|
42
42
|
|
|
43
43
|
get maxImagesPerCall(): number {
|
|
44
44
|
if (this.settings.maxImagesPerCall != null) {
|
|
@@ -63,8 +63,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
63
63
|
) {}
|
|
64
64
|
|
|
65
65
|
async doGenerate(
|
|
66
|
-
options: Parameters<
|
|
67
|
-
): Promise<Awaited<ReturnType<
|
|
66
|
+
options: Parameters<ImageModelV4['doGenerate']>[0],
|
|
67
|
+
): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
|
|
68
68
|
// Gemini image models use the language model API internally
|
|
69
69
|
if (isGeminiModel(this.modelId)) {
|
|
70
70
|
return this.doGenerateGemini(options);
|
|
@@ -73,8 +73,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
private async doGenerateImagen(
|
|
76
|
-
options: Parameters<
|
|
77
|
-
): Promise<Awaited<ReturnType<
|
|
76
|
+
options: Parameters<ImageModelV4['doGenerate']>[0],
|
|
77
|
+
): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
|
|
78
78
|
const {
|
|
79
79
|
prompt,
|
|
80
80
|
n = 1,
|
|
@@ -87,7 +87,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
87
87
|
files,
|
|
88
88
|
mask,
|
|
89
89
|
} = options;
|
|
90
|
-
const warnings: Array<
|
|
90
|
+
const warnings: Array<SharedV4Warning> = [];
|
|
91
91
|
|
|
92
92
|
// Imagen API endpoints do not support image editing
|
|
93
93
|
if (files != null && files.length > 0) {
|
|
@@ -181,8 +181,8 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
181
181
|
}
|
|
182
182
|
|
|
183
183
|
private async doGenerateGemini(
|
|
184
|
-
options: Parameters<
|
|
185
|
-
): Promise<Awaited<ReturnType<
|
|
184
|
+
options: Parameters<ImageModelV4['doGenerate']>[0],
|
|
185
|
+
): Promise<Awaited<ReturnType<ImageModelV4['doGenerate']>>> {
|
|
186
186
|
const {
|
|
187
187
|
prompt,
|
|
188
188
|
n,
|
|
@@ -195,7 +195,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
195
195
|
files,
|
|
196
196
|
mask,
|
|
197
197
|
} = options;
|
|
198
|
-
const warnings: Array<
|
|
198
|
+
const warnings: Array<SharedV4Warning> = [];
|
|
199
199
|
|
|
200
200
|
// Gemini does not support mask-based inpainting
|
|
201
201
|
if (mask != null) {
|
|
@@ -253,7 +253,7 @@ export class GoogleGenerativeAIImageModel implements ImageModelV3 {
|
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
const languageModelPrompt:
|
|
256
|
+
const languageModelPrompt: LanguageModelV4Prompt = [
|
|
257
257
|
{ role: 'user', content: userContent },
|
|
258
258
|
];
|
|
259
259
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
LanguageModelV4,
|
|
3
|
+
LanguageModelV4CallOptions,
|
|
4
|
+
LanguageModelV4Content,
|
|
5
|
+
LanguageModelV4FinishReason,
|
|
6
|
+
LanguageModelV4GenerateResult,
|
|
7
|
+
LanguageModelV4Source,
|
|
8
|
+
LanguageModelV4StreamPart,
|
|
9
|
+
LanguageModelV4StreamResult,
|
|
10
|
+
SharedV4ProviderMetadata,
|
|
11
|
+
SharedV4Warning,
|
|
12
12
|
} from '@ai-sdk/provider';
|
|
13
13
|
import {
|
|
14
14
|
combineHeaders,
|
|
@@ -38,7 +38,10 @@ import {
|
|
|
38
38
|
GoogleGenerativeAIModelId,
|
|
39
39
|
googleLanguageModelOptions,
|
|
40
40
|
} from './google-generative-ai-options';
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
GoogleGenerativeAIContentPart,
|
|
43
|
+
GoogleGenerativeAIProviderMetadata,
|
|
44
|
+
} from './google-generative-ai-prompt';
|
|
42
45
|
import { prepareTools } from './google-prepare-tools';
|
|
43
46
|
import { mapGoogleGenerativeAIFinishReason } from './map-google-generative-ai-finish-reason';
|
|
44
47
|
|
|
@@ -52,11 +55,11 @@ type GoogleGenerativeAIConfig = {
|
|
|
52
55
|
/**
|
|
53
56
|
* The supported URLs for the model.
|
|
54
57
|
*/
|
|
55
|
-
supportedUrls?: () =>
|
|
58
|
+
supportedUrls?: () => LanguageModelV4['supportedUrls'];
|
|
56
59
|
};
|
|
57
60
|
|
|
58
|
-
export class GoogleGenerativeAILanguageModel implements
|
|
59
|
-
readonly specificationVersion = '
|
|
61
|
+
export class GoogleGenerativeAILanguageModel implements LanguageModelV4 {
|
|
62
|
+
readonly specificationVersion = 'v4';
|
|
60
63
|
|
|
61
64
|
readonly modelId: GoogleGenerativeAIModelId;
|
|
62
65
|
|
|
@@ -94,8 +97,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
94
97
|
tools,
|
|
95
98
|
toolChoice,
|
|
96
99
|
providerOptions,
|
|
97
|
-
}:
|
|
98
|
-
const warnings:
|
|
100
|
+
}: LanguageModelV4CallOptions) {
|
|
101
|
+
const warnings: SharedV4Warning[] = [];
|
|
99
102
|
|
|
100
103
|
const providerOptionsName = this.config.provider.includes('vertex')
|
|
101
104
|
? 'vertex'
|
|
@@ -206,8 +209,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
async doGenerate(
|
|
209
|
-
options:
|
|
210
|
-
): Promise<
|
|
212
|
+
options: LanguageModelV4CallOptions,
|
|
213
|
+
): Promise<LanguageModelV4GenerateResult> {
|
|
211
214
|
const { args, warnings, providerOptionsName } = await this.getArgs(options);
|
|
212
215
|
|
|
213
216
|
const mergedHeaders = combineHeaders(
|
|
@@ -232,7 +235,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
232
235
|
});
|
|
233
236
|
|
|
234
237
|
const candidate = response.candidates[0];
|
|
235
|
-
const content: Array<
|
|
238
|
+
const content: Array<LanguageModelV4Content> = [];
|
|
236
239
|
|
|
237
240
|
// map ordered parts to content:
|
|
238
241
|
const parts = candidate.content?.parts ?? [];
|
|
@@ -304,11 +307,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
304
307
|
: undefined,
|
|
305
308
|
});
|
|
306
309
|
} else if ('inlineData' in part) {
|
|
310
|
+
const hasThought = part.thought === true;
|
|
311
|
+
const hasThoughtSignature = !!part.thoughtSignature;
|
|
307
312
|
content.push({
|
|
308
|
-
type: 'file'
|
|
313
|
+
type: hasThought ? 'reasoning-file' : 'file',
|
|
309
314
|
data: part.inlineData.data,
|
|
310
315
|
mediaType: part.inlineData.mimeType,
|
|
311
|
-
providerMetadata:
|
|
316
|
+
providerMetadata: hasThoughtSignature
|
|
312
317
|
? {
|
|
313
318
|
[providerOptionsName]: {
|
|
314
319
|
thoughtSignature: part.thoughtSignature,
|
|
@@ -349,7 +354,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
349
354
|
urlContextMetadata: candidate.urlContextMetadata ?? null,
|
|
350
355
|
safetyRatings: candidate.safetyRatings ?? null,
|
|
351
356
|
usageMetadata: usageMetadata ?? null,
|
|
352
|
-
|
|
357
|
+
finishMessage: candidate.finishMessage ?? null,
|
|
358
|
+
} satisfies GoogleGenerativeAIProviderMetadata,
|
|
353
359
|
},
|
|
354
360
|
request: { body: args },
|
|
355
361
|
response: {
|
|
@@ -361,8 +367,8 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
361
367
|
}
|
|
362
368
|
|
|
363
369
|
async doStream(
|
|
364
|
-
options:
|
|
365
|
-
): Promise<
|
|
370
|
+
options: LanguageModelV4CallOptions,
|
|
371
|
+
): Promise<LanguageModelV4StreamResult> {
|
|
366
372
|
const { args, warnings, providerOptionsName } = await this.getArgs(options);
|
|
367
373
|
|
|
368
374
|
const headers = combineHeaders(
|
|
@@ -382,12 +388,14 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
382
388
|
fetch: this.config.fetch,
|
|
383
389
|
});
|
|
384
390
|
|
|
385
|
-
let finishReason:
|
|
391
|
+
let finishReason: LanguageModelV4FinishReason = {
|
|
386
392
|
unified: 'other',
|
|
387
393
|
raw: undefined,
|
|
388
394
|
};
|
|
389
395
|
let usage: GoogleGenerativeAIUsageMetadata | undefined = undefined;
|
|
390
|
-
let providerMetadata:
|
|
396
|
+
let providerMetadata: SharedV4ProviderMetadata | undefined = undefined;
|
|
397
|
+
let lastGroundingMetadata: GroundingMetadataSchema | null = null;
|
|
398
|
+
let lastUrlContextMetadata: UrlContextMetadataSchema | null = null;
|
|
391
399
|
|
|
392
400
|
const generateId = this.config.generateId;
|
|
393
401
|
let hasToolCalls = false;
|
|
@@ -406,7 +414,7 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
406
414
|
stream: response.pipeThrough(
|
|
407
415
|
new TransformStream<
|
|
408
416
|
ParseResult<ChunkSchema>,
|
|
409
|
-
|
|
417
|
+
LanguageModelV4StreamPart
|
|
410
418
|
>({
|
|
411
419
|
start(controller) {
|
|
412
420
|
controller.enqueue({ type: 'stream-start', warnings });
|
|
@@ -439,6 +447,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
439
447
|
|
|
440
448
|
const content = candidate.content;
|
|
441
449
|
|
|
450
|
+
if (candidate.groundingMetadata != null) {
|
|
451
|
+
lastGroundingMetadata = candidate.groundingMetadata;
|
|
452
|
+
}
|
|
453
|
+
if (candidate.urlContextMetadata != null) {
|
|
454
|
+
lastUrlContextMetadata = candidate.urlContextMetadata;
|
|
455
|
+
}
|
|
456
|
+
|
|
442
457
|
const sources = extractSources({
|
|
443
458
|
groundingMetadata: candidate.groundingMetadata,
|
|
444
459
|
generateId,
|
|
@@ -581,8 +596,9 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
581
596
|
currentReasoningBlockId = null;
|
|
582
597
|
}
|
|
583
598
|
|
|
584
|
-
|
|
585
|
-
const
|
|
599
|
+
const hasThought = part.thought === true;
|
|
600
|
+
const hasThoughtSignature = !!part.thoughtSignature;
|
|
601
|
+
const fileMeta = hasThoughtSignature
|
|
586
602
|
? {
|
|
587
603
|
[providerOptionsName]: {
|
|
588
604
|
thoughtSignature: part.thoughtSignature,
|
|
@@ -590,10 +606,10 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
590
606
|
}
|
|
591
607
|
: undefined;
|
|
592
608
|
controller.enqueue({
|
|
593
|
-
type: 'file',
|
|
609
|
+
type: hasThought ? 'reasoning-file' : 'file',
|
|
594
610
|
mediaType: part.inlineData.mimeType,
|
|
595
611
|
data: part.inlineData.data,
|
|
596
|
-
providerMetadata:
|
|
612
|
+
providerMetadata: fileMeta,
|
|
597
613
|
});
|
|
598
614
|
}
|
|
599
615
|
}
|
|
@@ -651,19 +667,13 @@ export class GoogleGenerativeAILanguageModel implements LanguageModelV3 {
|
|
|
651
667
|
providerMetadata = {
|
|
652
668
|
[providerOptionsName]: {
|
|
653
669
|
promptFeedback: value.promptFeedback ?? null,
|
|
654
|
-
groundingMetadata:
|
|
655
|
-
urlContextMetadata:
|
|
670
|
+
groundingMetadata: lastGroundingMetadata,
|
|
671
|
+
urlContextMetadata: lastUrlContextMetadata,
|
|
656
672
|
safetyRatings: candidate.safetyRatings ?? null,
|
|
657
|
-
|
|
673
|
+
usageMetadata: usageMetadata ?? null,
|
|
674
|
+
finishMessage: candidate.finishMessage ?? null,
|
|
675
|
+
} satisfies GoogleGenerativeAIProviderMetadata,
|
|
658
676
|
};
|
|
659
|
-
if (usageMetadata != null) {
|
|
660
|
-
(
|
|
661
|
-
providerMetadata[providerOptionsName] as Record<
|
|
662
|
-
string,
|
|
663
|
-
unknown
|
|
664
|
-
>
|
|
665
|
-
).usageMetadata = usageMetadata;
|
|
666
|
-
}
|
|
667
677
|
}
|
|
668
678
|
},
|
|
669
679
|
|
|
@@ -737,12 +747,12 @@ function extractSources({
|
|
|
737
747
|
}: {
|
|
738
748
|
groundingMetadata: GroundingMetadataSchema | undefined | null;
|
|
739
749
|
generateId: () => string;
|
|
740
|
-
}): undefined |
|
|
750
|
+
}): undefined | LanguageModelV4Source[] {
|
|
741
751
|
if (!groundingMetadata?.groundingChunks) {
|
|
742
752
|
return undefined;
|
|
743
753
|
}
|
|
744
754
|
|
|
745
|
-
const sources:
|
|
755
|
+
const sources: LanguageModelV4Source[] = [];
|
|
746
756
|
|
|
747
757
|
for (const chunk of groundingMetadata.groundingChunks) {
|
|
748
758
|
if (chunk.web != null) {
|
|
@@ -926,6 +936,7 @@ const getContentSchema = () =>
|
|
|
926
936
|
mimeType: z.string(),
|
|
927
937
|
data: z.string(),
|
|
928
938
|
}),
|
|
939
|
+
thought: z.boolean().nullish(),
|
|
929
940
|
thoughtSignature: z.string().nullish(),
|
|
930
941
|
}),
|
|
931
942
|
z.object({
|
|
@@ -991,6 +1002,7 @@ const responseSchema = lazySchema(() =>
|
|
|
991
1002
|
z.object({
|
|
992
1003
|
content: getContentSchema().nullish().or(z.object({}).strict()),
|
|
993
1004
|
finishReason: z.string().nullish(),
|
|
1005
|
+
finishMessage: z.string().nullish(),
|
|
994
1006
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
995
1007
|
groundingMetadata: getGroundingMetadataSchema().nullish(),
|
|
996
1008
|
urlContextMetadata: getUrlContextMetadataSchema().nullish(),
|
|
@@ -1026,6 +1038,14 @@ export type SafetyRatingSchema = NonNullable<
|
|
|
1026
1038
|
InferSchema<typeof responseSchema>['candidates'][number]['safetyRatings']
|
|
1027
1039
|
>[number];
|
|
1028
1040
|
|
|
1041
|
+
export type PromptFeedbackSchema = NonNullable<
|
|
1042
|
+
InferSchema<typeof responseSchema>['promptFeedback']
|
|
1043
|
+
>;
|
|
1044
|
+
|
|
1045
|
+
export type UsageMetadataSchema = NonNullable<
|
|
1046
|
+
InferSchema<typeof responseSchema>['usageMetadata']
|
|
1047
|
+
>;
|
|
1048
|
+
|
|
1029
1049
|
// limited version of the schema, focussed on what is needed for the implementation
|
|
1030
1050
|
// this approach limits breakages when the API changes and increases efficiency
|
|
1031
1051
|
const chunkSchema = lazySchema(() =>
|
|
@@ -1036,6 +1056,7 @@ const chunkSchema = lazySchema(() =>
|
|
|
1036
1056
|
z.object({
|
|
1037
1057
|
content: getContentSchema().nullish(),
|
|
1038
1058
|
finishReason: z.string().nullish(),
|
|
1059
|
+
finishMessage: z.string().nullish(),
|
|
1039
1060
|
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1040
1061
|
groundingMetadata: getGroundingMetadataSchema().nullish(),
|
|
1041
1062
|
urlContextMetadata: getUrlContextMetadataSchema().nullish(),
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
GroundingMetadataSchema,
|
|
3
|
+
PromptFeedbackSchema,
|
|
3
4
|
UrlContextMetadataSchema,
|
|
5
|
+
UsageMetadataSchema,
|
|
4
6
|
} from './google-generative-ai-language-model';
|
|
5
7
|
import { type SafetyRatingSchema } from './google-generative-ai-language-model';
|
|
6
8
|
|
|
@@ -31,8 +33,15 @@ export type GoogleGenerativeAIUrlContextMetadata = UrlContextMetadataSchema;
|
|
|
31
33
|
|
|
32
34
|
export type GoogleGenerativeAISafetyRating = SafetyRatingSchema;
|
|
33
35
|
|
|
36
|
+
export type GoogleGenerativeAIPromptFeedback = PromptFeedbackSchema;
|
|
37
|
+
|
|
38
|
+
export type GoogleGenerativeAIUsageMetadata = UsageMetadataSchema;
|
|
39
|
+
|
|
34
40
|
export interface GoogleGenerativeAIProviderMetadata {
|
|
41
|
+
promptFeedback: GoogleGenerativeAIPromptFeedback | null;
|
|
35
42
|
groundingMetadata: GoogleGenerativeAIGroundingMetadata | null;
|
|
36
43
|
urlContextMetadata: GoogleGenerativeAIUrlContextMetadata | null;
|
|
37
44
|
safetyRatings: GoogleGenerativeAISafetyRating[] | null;
|
|
45
|
+
usageMetadata: GoogleGenerativeAIUsageMetadata | null;
|
|
46
|
+
finishMessage: string | null;
|
|
38
47
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AISDKError,
|
|
3
|
-
type
|
|
4
|
-
type
|
|
3
|
+
type Experimental_VideoModelV4,
|
|
4
|
+
type SharedV4Warning,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
6
|
import {
|
|
7
7
|
combineHeaders,
|
|
@@ -50,8 +50,8 @@ interface GoogleGenerativeAIVideoModelConfig {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
export class GoogleGenerativeAIVideoModel implements
|
|
54
|
-
readonly specificationVersion = '
|
|
53
|
+
export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV4 {
|
|
54
|
+
readonly specificationVersion = 'v4';
|
|
55
55
|
|
|
56
56
|
get provider(): string {
|
|
57
57
|
return this.config.provider;
|
|
@@ -68,10 +68,10 @@ export class GoogleGenerativeAIVideoModel implements Experimental_VideoModelV3 {
|
|
|
68
68
|
) {}
|
|
69
69
|
|
|
70
70
|
async doGenerate(
|
|
71
|
-
options: Parameters<
|
|
72
|
-
): Promise<Awaited<ReturnType<
|
|
71
|
+
options: Parameters<Experimental_VideoModelV4['doGenerate']>[0],
|
|
72
|
+
): Promise<Awaited<ReturnType<Experimental_VideoModelV4['doGenerate']>>> {
|
|
73
73
|
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
|
|
74
|
-
const warnings:
|
|
74
|
+
const warnings: SharedV4Warning[] = [];
|
|
75
75
|
|
|
76
76
|
const googleOptions = (await parseProviderOptions({
|
|
77
77
|
provider: 'google',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
LanguageModelV4CallOptions,
|
|
3
|
+
SharedV4Warning,
|
|
4
4
|
UnsupportedFunctionalityError,
|
|
5
5
|
} from '@ai-sdk/provider';
|
|
6
6
|
import { convertJSONSchemaToOpenAPISchema } from './convert-json-schema-to-openapi-schema';
|
|
@@ -11,8 +11,8 @@ export function prepareTools({
|
|
|
11
11
|
toolChoice,
|
|
12
12
|
modelId,
|
|
13
13
|
}: {
|
|
14
|
-
tools:
|
|
15
|
-
toolChoice?:
|
|
14
|
+
tools: LanguageModelV4CallOptions['tools'];
|
|
15
|
+
toolChoice?: LanguageModelV4CallOptions['toolChoice'];
|
|
16
16
|
modelId: GoogleGenerativeAIModelId;
|
|
17
17
|
}): {
|
|
18
18
|
tools:
|
|
@@ -35,12 +35,12 @@ export function prepareTools({
|
|
|
35
35
|
allowedFunctionNames?: string[];
|
|
36
36
|
};
|
|
37
37
|
};
|
|
38
|
-
toolWarnings:
|
|
38
|
+
toolWarnings: SharedV4Warning[];
|
|
39
39
|
} {
|
|
40
40
|
// when the tools array is empty, change it to undefined to prevent errors:
|
|
41
41
|
tools = tools?.length ? tools : undefined;
|
|
42
42
|
|
|
43
|
-
const toolWarnings:
|
|
43
|
+
const toolWarnings: SharedV4Warning[] = [];
|
|
44
44
|
|
|
45
45
|
const isLatest = (
|
|
46
46
|
[
|