@ai-sdk/google 4.0.54 → 4.0.56
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 +21 -6
- package/dist/index.js +82 -43
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +21 -6
- package/dist/internal/index.js +81 -42
- package/dist/internal/index.js.map +1 -1
- package/package.json +1 -1
- package/src/convert-google-usage.ts +3 -0
- package/src/google-language-model.ts +119 -53
package/package.json
CHANGED
|
@@ -9,13 +9,16 @@ export type GoogleTokenDetail = {
|
|
|
9
9
|
export type GoogleUsageMetadata = {
|
|
10
10
|
promptTokenCount?: number | null;
|
|
11
11
|
candidatesTokenCount?: number | null;
|
|
12
|
+
toolUsePromptTokenCount?: number | null;
|
|
12
13
|
totalTokenCount?: number | null;
|
|
13
14
|
cachedContentTokenCount?: number | null;
|
|
14
15
|
thoughtsTokenCount?: number | null;
|
|
15
16
|
trafficType?: string | null;
|
|
16
17
|
serviceTier?: string | null;
|
|
17
18
|
promptTokensDetails?: GoogleTokenDetail[] | null;
|
|
19
|
+
cacheTokensDetails?: GoogleTokenDetail[] | null;
|
|
18
20
|
candidatesTokensDetails?: GoogleTokenDetail[] | null;
|
|
21
|
+
toolUsePromptTokensDetails?: GoogleTokenDetail[] | null;
|
|
19
22
|
};
|
|
20
23
|
|
|
21
24
|
export function convertGoogleUsage(
|
|
@@ -62,6 +62,8 @@ const configurableSafetySettingCategories = [
|
|
|
62
62
|
'HARM_CATEGORY_SEXUALLY_EXPLICIT',
|
|
63
63
|
] as const;
|
|
64
64
|
|
|
65
|
+
const gemini25ModelPattern = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
|
|
66
|
+
|
|
65
67
|
export type GoogleLanguageModelConfig = {
|
|
66
68
|
provider: string;
|
|
67
69
|
baseURL: string;
|
|
@@ -258,6 +260,22 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
258
260
|
}
|
|
259
261
|
|
|
260
262
|
const isGemmaModel = this.modelId.toLowerCase().startsWith('gemma-');
|
|
263
|
+
const isGemini25DeveloperApiModel =
|
|
264
|
+
!isVertexProvider && gemini25ModelPattern.test(this.modelId);
|
|
265
|
+
|
|
266
|
+
if (isGemini25DeveloperApiModel && frequencyPenalty != null) {
|
|
267
|
+
warnings.push({
|
|
268
|
+
type: 'unsupported',
|
|
269
|
+
feature: 'frequencyPenalty',
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (isGemini25DeveloperApiModel && presencePenalty != null) {
|
|
273
|
+
warnings.push({
|
|
274
|
+
type: 'unsupported',
|
|
275
|
+
feature: 'presencePenalty',
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
261
279
|
const { usesGemini3Features } = getGoogleModelCapabilities(this.modelId);
|
|
262
280
|
|
|
263
281
|
const { contents, systemInstruction } = convertToGoogleMessages(prompt, {
|
|
@@ -331,8 +349,12 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
331
349
|
temperature,
|
|
332
350
|
topK,
|
|
333
351
|
topP,
|
|
334
|
-
frequencyPenalty
|
|
335
|
-
|
|
352
|
+
frequencyPenalty: isGemini25DeveloperApiModel
|
|
353
|
+
? undefined
|
|
354
|
+
: frequencyPenalty,
|
|
355
|
+
presencePenalty: isGemini25DeveloperApiModel
|
|
356
|
+
? undefined
|
|
357
|
+
: presencePenalty,
|
|
336
358
|
stopSequences,
|
|
337
359
|
seed,
|
|
338
360
|
|
|
@@ -388,11 +410,16 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
388
410
|
Object.fromEntries(
|
|
389
411
|
providerOptionsNames.map(name => [name, payload]),
|
|
390
412
|
) as SharedV4ProviderMetadata;
|
|
391
|
-
const candidate = response.candidates[0];
|
|
413
|
+
const candidate = response.candidates?.[0];
|
|
414
|
+
const promptBlockReason = response.promptFeedback?.blockReason;
|
|
415
|
+
const isPromptBlocked =
|
|
416
|
+
candidate?.finishReason == null && promptBlockReason != null;
|
|
417
|
+
const rawFinishReason =
|
|
418
|
+
candidate?.finishReason ?? promptBlockReason ?? undefined;
|
|
392
419
|
const content: Array<LanguageModelV4Content> = [];
|
|
393
420
|
|
|
394
421
|
// map ordered parts to content:
|
|
395
|
-
const parts = candidate
|
|
422
|
+
const parts = candidate?.content?.parts ?? [];
|
|
396
423
|
|
|
397
424
|
const usageMetadata = response.usageMetadata;
|
|
398
425
|
|
|
@@ -517,7 +544,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
517
544
|
|
|
518
545
|
const sources =
|
|
519
546
|
extractSources({
|
|
520
|
-
groundingMetadata: candidate
|
|
547
|
+
groundingMetadata: candidate?.groundingMetadata,
|
|
521
548
|
generateId: this.config.generateId,
|
|
522
549
|
}) ?? [];
|
|
523
550
|
for (const source of sources) {
|
|
@@ -527,24 +554,26 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
527
554
|
return {
|
|
528
555
|
content,
|
|
529
556
|
finishReason: {
|
|
530
|
-
unified:
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
557
|
+
unified: isPromptBlocked
|
|
558
|
+
? 'content-filter'
|
|
559
|
+
: mapGoogleFinishReason({
|
|
560
|
+
finishReason: rawFinishReason,
|
|
561
|
+
// Only count client-executed tool calls for finish reason determination.
|
|
562
|
+
hasToolCalls: content.some(
|
|
563
|
+
part => part.type === 'tool-call' && !part.providerExecuted,
|
|
564
|
+
),
|
|
565
|
+
}),
|
|
566
|
+
raw: rawFinishReason,
|
|
538
567
|
},
|
|
539
568
|
usage: convertGoogleUsage(usageMetadata),
|
|
540
569
|
warnings,
|
|
541
570
|
providerMetadata: wrapProviderMetadata({
|
|
542
571
|
promptFeedback: response.promptFeedback ?? null,
|
|
543
|
-
groundingMetadata: candidate
|
|
544
|
-
urlContextMetadata: candidate
|
|
545
|
-
safetyRatings: candidate
|
|
572
|
+
groundingMetadata: candidate?.groundingMetadata ?? null,
|
|
573
|
+
urlContextMetadata: candidate?.urlContextMetadata ?? null,
|
|
574
|
+
safetyRatings: candidate?.safetyRatings ?? null,
|
|
546
575
|
usageMetadata: usageMetadata ?? null,
|
|
547
|
-
finishMessage: candidate
|
|
576
|
+
finishMessage: candidate?.finishMessage ?? null,
|
|
548
577
|
serviceTier: usageMetadata?.serviceTier ?? null,
|
|
549
578
|
} satisfies GoogleProviderMetadata),
|
|
550
579
|
response: {
|
|
@@ -735,6 +764,22 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
735
764
|
|
|
736
765
|
// sometimes the API returns an empty candidates array
|
|
737
766
|
if (candidate == null) {
|
|
767
|
+
const promptBlockReason = value.promptFeedback?.blockReason;
|
|
768
|
+
if (promptBlockReason != null) {
|
|
769
|
+
finishReason = {
|
|
770
|
+
unified: 'content-filter',
|
|
771
|
+
raw: promptBlockReason,
|
|
772
|
+
};
|
|
773
|
+
providerMetadata = wrapProviderMetadata({
|
|
774
|
+
promptFeedback: value.promptFeedback ?? null,
|
|
775
|
+
groundingMetadata: lastGroundingMetadata,
|
|
776
|
+
urlContextMetadata: lastUrlContextMetadata,
|
|
777
|
+
safetyRatings: null,
|
|
778
|
+
usageMetadata: usageMetadata ?? null,
|
|
779
|
+
finishMessage: null,
|
|
780
|
+
serviceTier: usage?.serviceTier ?? null,
|
|
781
|
+
} satisfies GoogleProviderMetadata);
|
|
782
|
+
}
|
|
738
783
|
return;
|
|
739
784
|
}
|
|
740
785
|
|
|
@@ -1110,13 +1155,21 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
1110
1155
|
}
|
|
1111
1156
|
}
|
|
1112
1157
|
|
|
1113
|
-
|
|
1158
|
+
const promptBlockReason = value.promptFeedback?.blockReason;
|
|
1159
|
+
const isPromptBlocked =
|
|
1160
|
+
candidate.finishReason == null && promptBlockReason != null;
|
|
1161
|
+
const rawFinishReason =
|
|
1162
|
+
candidate.finishReason ?? promptBlockReason ?? undefined;
|
|
1163
|
+
|
|
1164
|
+
if (rawFinishReason != null) {
|
|
1114
1165
|
finishReason = {
|
|
1115
|
-
unified:
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1166
|
+
unified: isPromptBlocked
|
|
1167
|
+
? 'content-filter'
|
|
1168
|
+
: mapGoogleFinishReason({
|
|
1169
|
+
finishReason: rawFinishReason,
|
|
1170
|
+
hasToolCalls,
|
|
1171
|
+
}),
|
|
1172
|
+
raw: rawFinishReason,
|
|
1120
1173
|
};
|
|
1121
1174
|
|
|
1122
1175
|
providerMetadata = wrapProviderMetadata({
|
|
@@ -1552,26 +1605,33 @@ const getSafetyRatingSchema = () =>
|
|
|
1552
1605
|
|
|
1553
1606
|
const tokenDetailsSchema = z
|
|
1554
1607
|
.array(
|
|
1555
|
-
z
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1608
|
+
z
|
|
1609
|
+
.object({
|
|
1610
|
+
modality: z.string(),
|
|
1611
|
+
tokenCount: z.number(),
|
|
1612
|
+
})
|
|
1613
|
+
.loose(),
|
|
1559
1614
|
)
|
|
1560
1615
|
.nullish();
|
|
1561
1616
|
|
|
1562
|
-
const usageSchema = z
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1617
|
+
const usageSchema = z
|
|
1618
|
+
.object({
|
|
1619
|
+
cachedContentTokenCount: z.number().nullish(),
|
|
1620
|
+
thoughtsTokenCount: z.number().nullish(),
|
|
1621
|
+
promptTokenCount: z.number().nullish(),
|
|
1622
|
+
candidatesTokenCount: z.number().nullish(),
|
|
1623
|
+
toolUsePromptTokenCount: z.number().nullish(),
|
|
1624
|
+
totalTokenCount: z.number().nullish(),
|
|
1625
|
+
// https://cloud.google.com/vertex-ai/generative-ai/docs/reference/rest/v1/GenerateContentResponse#TrafficType
|
|
1626
|
+
trafficType: z.string().nullish(),
|
|
1627
|
+
serviceTier: z.string().nullish(),
|
|
1628
|
+
// https://ai.google.dev/api/generate-content#Modality
|
|
1629
|
+
promptTokensDetails: tokenDetailsSchema,
|
|
1630
|
+
cacheTokensDetails: tokenDetailsSchema,
|
|
1631
|
+
candidatesTokensDetails: tokenDetailsSchema,
|
|
1632
|
+
toolUsePromptTokensDetails: tokenDetailsSchema,
|
|
1633
|
+
})
|
|
1634
|
+
.loose();
|
|
1575
1635
|
|
|
1576
1636
|
// https://ai.google.dev/api/generate-content#UrlRetrievalMetadata
|
|
1577
1637
|
export const getUrlContextMetadataSchema = () =>
|
|
@@ -1590,16 +1650,18 @@ export const responseSchema = lazySchema(() =>
|
|
|
1590
1650
|
zodSchema(
|
|
1591
1651
|
z.object({
|
|
1592
1652
|
responseId: z.string().nullish(),
|
|
1593
|
-
candidates: z
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1653
|
+
candidates: z
|
|
1654
|
+
.array(
|
|
1655
|
+
z.object({
|
|
1656
|
+
content: getContentSchema().nullish().or(z.object({}).strict()),
|
|
1657
|
+
finishReason: z.string().nullish(),
|
|
1658
|
+
finishMessage: z.string().nullish(),
|
|
1659
|
+
safetyRatings: z.array(getSafetyRatingSchema()).nullish(),
|
|
1660
|
+
groundingMetadata: getGroundingMetadataSchema().nullish(),
|
|
1661
|
+
urlContextMetadata: getUrlContextMetadataSchema().nullish(),
|
|
1662
|
+
}),
|
|
1663
|
+
)
|
|
1664
|
+
.nullish(),
|
|
1603
1665
|
usageMetadata: usageSchema.nullish(),
|
|
1604
1666
|
promptFeedback: z
|
|
1605
1667
|
.object({
|
|
@@ -1611,16 +1673,20 @@ export const responseSchema = lazySchema(() =>
|
|
|
1611
1673
|
),
|
|
1612
1674
|
);
|
|
1613
1675
|
|
|
1676
|
+
type CandidateSchema = NonNullable<
|
|
1677
|
+
InferSchema<typeof responseSchema>['candidates']
|
|
1678
|
+
>[number];
|
|
1679
|
+
|
|
1614
1680
|
export type GroundingMetadataSchema = NonNullable<
|
|
1615
|
-
|
|
1681
|
+
CandidateSchema['groundingMetadata']
|
|
1616
1682
|
>;
|
|
1617
1683
|
|
|
1618
1684
|
export type UrlContextMetadataSchema = NonNullable<
|
|
1619
|
-
|
|
1685
|
+
CandidateSchema['urlContextMetadata']
|
|
1620
1686
|
>;
|
|
1621
1687
|
|
|
1622
1688
|
export type SafetyRatingSchema = NonNullable<
|
|
1623
|
-
|
|
1689
|
+
CandidateSchema['safetyRatings']
|
|
1624
1690
|
>[number];
|
|
1625
1691
|
|
|
1626
1692
|
export type PromptFeedbackSchema = NonNullable<
|