@ai-sdk/google 4.0.98 → 4.0.100
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 +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +43 -9
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +42 -8
- package/dist/internal/index.js.map +1 -1
- package/docs/15-google.mdx +8 -0
- package/package.json +3 -3
- package/src/google-error.ts +9 -6
- package/src/google-language-model.ts +63 -3
- package/src/google-prompt.ts +2 -0
package/docs/15-google.mdx
CHANGED
|
@@ -395,6 +395,14 @@ and long coding or agentic tasks.
|
|
|
395
395
|
- Complex requests can run for several minutes. Make sure your HTTP client
|
|
396
396
|
allows read timeouts of at least 15 to 20 minutes.
|
|
397
397
|
|
|
398
|
+
**Grounding across requests.** When a response is continued automatically,
|
|
399
|
+
`providerMetadata.google.groundingMetadataPerRequest` contains the grounding
|
|
400
|
+
metadata from each request, in order. An entry is `null` if that request did
|
|
401
|
+
not return grounding metadata. This preserves earlier Search results even if
|
|
402
|
+
the final request returns none, and keeps citation indices scoped to their
|
|
403
|
+
original request. The existing `groundingMetadata` field keeps its current
|
|
404
|
+
behavior; use the per-request array when inspecting a continued response.
|
|
405
|
+
|
|
398
406
|
**Usage across requests.** Each continued request re-sends the prompt plus all
|
|
399
407
|
output so far as input, so its prompt token count includes everything
|
|
400
408
|
generated before it. `usage` is the sum of all requests, which matches what
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/google",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.100",
|
|
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.30",
|
|
39
|
+
"@ai-sdk/provider-utils": "5.0.63"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@ai-sdk/test-server": "2.0.4",
|
package/src/google-error.ts
CHANGED
|
@@ -6,15 +6,18 @@ import {
|
|
|
6
6
|
} from '@ai-sdk/provider-utils';
|
|
7
7
|
import { z } from 'zod/v4';
|
|
8
8
|
|
|
9
|
+
export const getGoogleErrorSchema = () =>
|
|
10
|
+
z.object({
|
|
11
|
+
code: z.number().nullable(),
|
|
12
|
+
message: z.string(),
|
|
13
|
+
status: z.string(),
|
|
14
|
+
details: z.array(z.unknown()).nullish(),
|
|
15
|
+
});
|
|
16
|
+
|
|
9
17
|
const googleErrorDataSchema = lazySchema(() =>
|
|
10
18
|
zodSchema(
|
|
11
19
|
z.object({
|
|
12
|
-
error:
|
|
13
|
-
code: z.number().nullable(),
|
|
14
|
-
message: z.string(),
|
|
15
|
-
status: z.string(),
|
|
16
|
-
details: z.array(z.unknown()).nullish(),
|
|
17
|
-
}),
|
|
20
|
+
error: getGoogleErrorSchema(),
|
|
18
21
|
}),
|
|
19
22
|
),
|
|
20
23
|
);
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
createToolNameMapping,
|
|
19
19
|
createEventSourceResponseHandler,
|
|
20
20
|
createJsonResponseHandler,
|
|
21
|
+
createProviderStreamError,
|
|
21
22
|
generateId,
|
|
22
23
|
isCustomReasoning,
|
|
23
24
|
lazySchema,
|
|
@@ -45,7 +46,10 @@ import {
|
|
|
45
46
|
import { convertToGoogleMessages } from './convert-to-google-messages';
|
|
46
47
|
import { downloadToolResultFiles } from './download-tool-result-files';
|
|
47
48
|
import { getModelPath } from './get-model-path';
|
|
48
|
-
import {
|
|
49
|
+
import {
|
|
50
|
+
getGoogleErrorSchema,
|
|
51
|
+
googleFailedResponseHandler,
|
|
52
|
+
} from './google-error';
|
|
49
53
|
import { sanitizeResponseJsonSchema } from './sanitize-response-json-schema';
|
|
50
54
|
import {
|
|
51
55
|
googleLanguageModelOptions,
|
|
@@ -516,6 +520,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
516
520
|
toolNameMapping,
|
|
517
521
|
jsonResponseToolName,
|
|
518
522
|
initialPromptTokenCount,
|
|
523
|
+
groundingMetadataPerRequest,
|
|
519
524
|
}: {
|
|
520
525
|
config: GoogleLanguageModelConfig;
|
|
521
526
|
response: InferSchema<typeof responseSchema>;
|
|
@@ -524,6 +529,7 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
524
529
|
toolNameMapping?: ReturnType<typeof createToolNameMapping>;
|
|
525
530
|
jsonResponseToolName?: string;
|
|
526
531
|
initialPromptTokenCount?: number | null;
|
|
532
|
+
groundingMetadataPerRequest?: Array<GroundingMetadataSchema | null>;
|
|
527
533
|
}): LanguageModelV4GenerateResult {
|
|
528
534
|
const wrapProviderMetadata = (payload: Record<string, unknown>) =>
|
|
529
535
|
Object.fromEntries(
|
|
@@ -714,6 +720,9 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
714
720
|
providerMetadata: wrapProviderMetadata({
|
|
715
721
|
promptFeedback: response.promptFeedback ?? null,
|
|
716
722
|
groundingMetadata: candidate?.groundingMetadata ?? null,
|
|
723
|
+
...(groundingMetadataPerRequest != null
|
|
724
|
+
? { groundingMetadataPerRequest }
|
|
725
|
+
: {}),
|
|
717
726
|
urlContextMetadata: candidate?.urlContextMetadata ?? null,
|
|
718
727
|
safetyRatings: candidate?.safetyRatings ?? null,
|
|
719
728
|
usageMetadata: usageMetadata ?? null,
|
|
@@ -777,12 +786,15 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
777
786
|
// the prompt plus all output so far as input, so the first request's
|
|
778
787
|
// prompt token count is kept separately for context window checks.
|
|
779
788
|
const content: LanguageModelV4Content[] = [];
|
|
789
|
+
const groundingMetadataPerRequest: Array<GroundingMetadataSchema | null> =
|
|
790
|
+
[];
|
|
780
791
|
let usageMetadata: GoogleUsageMetadata | undefined;
|
|
781
792
|
const firstPromptTokenCount = response.usageMetadata?.promptTokenCount;
|
|
782
793
|
let isContinued = false;
|
|
783
794
|
|
|
784
795
|
while (true) {
|
|
785
796
|
const candidate = response.candidates?.[0];
|
|
797
|
+
groundingMetadataPerRequest.push(candidate?.groundingMetadata ?? null);
|
|
786
798
|
const continuationToken =
|
|
787
799
|
candidate?.finishReason === 'CONTINUATION'
|
|
788
800
|
? candidate.continuationToken
|
|
@@ -824,6 +836,9 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
824
836
|
toolNameMapping,
|
|
825
837
|
jsonResponseToolName,
|
|
826
838
|
initialPromptTokenCount: isContinued ? firstPromptTokenCount : undefined,
|
|
839
|
+
groundingMetadataPerRequest: isContinued
|
|
840
|
+
? groundingMetadataPerRequest
|
|
841
|
+
: undefined,
|
|
827
842
|
});
|
|
828
843
|
|
|
829
844
|
const result = {
|
|
@@ -881,6 +896,10 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
881
896
|
const { responseHeaders, value: firstResponse } =
|
|
882
897
|
await streamGenerateContent(args);
|
|
883
898
|
|
|
899
|
+
const groundingMetadataPerRequest: Array<GroundingMetadataSchema | null> =
|
|
900
|
+
[];
|
|
901
|
+
let requestGroundingMetadata: GroundingMetadataSchema | null = null;
|
|
902
|
+
|
|
884
903
|
// Gemini 4 long decode: when a stream reaches the per-request cap while
|
|
885
904
|
// `maxOutputTokens` budget remains, its last chunk finishes with
|
|
886
905
|
// `CONTINUATION`. Resend the same request with the continuation token and
|
|
@@ -889,12 +908,22 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
889
908
|
stream: firstResponse,
|
|
890
909
|
getContinuationToken: chunk => {
|
|
891
910
|
const candidate = chunk.candidates?.[0];
|
|
911
|
+
if (candidate?.groundingMetadata != null) {
|
|
912
|
+
requestGroundingMetadata = candidate.groundingMetadata;
|
|
913
|
+
}
|
|
892
914
|
return candidate?.finishReason === 'CONTINUATION'
|
|
893
915
|
? (candidate.continuationToken ?? undefined)
|
|
894
916
|
: undefined;
|
|
895
917
|
},
|
|
896
|
-
continueStream: async continuationToken =>
|
|
897
|
-
|
|
918
|
+
continueStream: async continuationToken => {
|
|
919
|
+
const { value } = await streamGenerateContent({
|
|
920
|
+
...args,
|
|
921
|
+
continuationToken,
|
|
922
|
+
});
|
|
923
|
+
groundingMetadataPerRequest.push(requestGroundingMetadata);
|
|
924
|
+
requestGroundingMetadata = null;
|
|
925
|
+
return value;
|
|
926
|
+
},
|
|
898
927
|
});
|
|
899
928
|
|
|
900
929
|
let finishReason: LanguageModelV4FinishReason = {
|
|
@@ -995,6 +1024,28 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
995
1024
|
|
|
996
1025
|
const value = chunk.value;
|
|
997
1026
|
|
|
1027
|
+
if (value.error != null) {
|
|
1028
|
+
finishReason = { unified: 'error', raw: undefined };
|
|
1029
|
+
const error = value.error;
|
|
1030
|
+
controller.enqueue({
|
|
1031
|
+
type: 'error',
|
|
1032
|
+
error: createProviderStreamError({
|
|
1033
|
+
message: error.message,
|
|
1034
|
+
type: error.status,
|
|
1035
|
+
code: error.code ?? undefined,
|
|
1036
|
+
statusCode: error.code ?? undefined,
|
|
1037
|
+
isRetryable:
|
|
1038
|
+
error.code != null &&
|
|
1039
|
+
(error.code === 408 ||
|
|
1040
|
+
error.code === 409 ||
|
|
1041
|
+
error.code === 429 ||
|
|
1042
|
+
error.code >= 500),
|
|
1043
|
+
data: error,
|
|
1044
|
+
}),
|
|
1045
|
+
});
|
|
1046
|
+
return;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
998
1049
|
if (!hasEmittedResponseMetadata && value.responseId != null) {
|
|
999
1050
|
hasEmittedResponseMetadata = true;
|
|
1000
1051
|
controller.enqueue({
|
|
@@ -1463,6 +1514,14 @@ export class GoogleLanguageModel implements LanguageModelV4 {
|
|
|
1463
1514
|
providerMetadata: wrapProviderMetadata({
|
|
1464
1515
|
promptFeedback,
|
|
1465
1516
|
groundingMetadata: lastGroundingMetadata,
|
|
1517
|
+
...(groundingMetadataPerRequest.length > 0
|
|
1518
|
+
? {
|
|
1519
|
+
groundingMetadataPerRequest: [
|
|
1520
|
+
...groundingMetadataPerRequest,
|
|
1521
|
+
requestGroundingMetadata,
|
|
1522
|
+
],
|
|
1523
|
+
}
|
|
1524
|
+
: {}),
|
|
1466
1525
|
urlContextMetadata: lastUrlContextMetadata,
|
|
1467
1526
|
safetyRatings: lastSafetyRatings,
|
|
1468
1527
|
usageMetadata: usage ?? null,
|
|
@@ -2012,6 +2071,7 @@ export type UsageMetadataSchema = NonNullable<
|
|
|
2012
2071
|
const chunkSchema = lazySchema(() =>
|
|
2013
2072
|
zodSchema(
|
|
2014
2073
|
z.object({
|
|
2074
|
+
error: getGoogleErrorSchema().nullish(),
|
|
2015
2075
|
responseId: z.string().nullish(),
|
|
2016
2076
|
candidates: z
|
|
2017
2077
|
.array(
|
package/src/google-prompt.ts
CHANGED
|
@@ -94,6 +94,8 @@ export type GoogleUsageMetadata = UsageMetadataSchema;
|
|
|
94
94
|
export interface GoogleProviderMetadata {
|
|
95
95
|
promptFeedback: GooglePromptFeedback | null;
|
|
96
96
|
groundingMetadata: GoogleGroundingMetadata | null;
|
|
97
|
+
/** Grounding from each automatically continued request, in request order. */
|
|
98
|
+
groundingMetadataPerRequest?: Array<GoogleGroundingMetadata | null>;
|
|
97
99
|
urlContextMetadata: GoogleUrlContextMetadata | null;
|
|
98
100
|
safetyRatings: GoogleSafetyRating[] | null;
|
|
99
101
|
usageMetadata: GoogleUsageMetadata | null;
|