@ai-sdk/google 2.0.102 → 2.0.104

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.
@@ -111,6 +111,7 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
111
111
  })[] | null | undefined;
112
112
  } | null | undefined;
113
113
  finishReason?: string | null | undefined;
114
+ continuationToken?: string | null | undefined;
114
115
  safetyRatings?: {
115
116
  category?: string | null | undefined;
116
117
  probability?: string | null | undefined;
@@ -111,6 +111,7 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
111
111
  })[] | null | undefined;
112
112
  } | null | undefined;
113
113
  finishReason?: string | null | undefined;
114
+ continuationToken?: string | null | undefined;
114
115
  safetyRatings?: {
115
116
  category?: string | null | undefined;
116
117
  probability?: string | null | undefined;
@@ -31,6 +31,100 @@ module.exports = __toCommonJS(index_exports);
31
31
  var import_provider_utils4 = require("@ai-sdk/provider-utils");
32
32
  var import_v43 = require("zod/v4");
33
33
 
34
+ // src/add-google-generative-ai-usage-metadata.ts
35
+ function addGoogleGenerativeAIUsageMetadata(a, b) {
36
+ if (a == null || b == null) {
37
+ return b != null ? b : a;
38
+ }
39
+ return {
40
+ ...a,
41
+ ...b,
42
+ promptTokenCount: addCounts(a.promptTokenCount, b.promptTokenCount),
43
+ candidatesTokenCount: addCounts(
44
+ a.candidatesTokenCount,
45
+ b.candidatesTokenCount
46
+ ),
47
+ totalTokenCount: addCounts(a.totalTokenCount, b.totalTokenCount),
48
+ cachedContentTokenCount: addCounts(
49
+ a.cachedContentTokenCount,
50
+ b.cachedContentTokenCount
51
+ ),
52
+ thoughtsTokenCount: addCounts(a.thoughtsTokenCount, b.thoughtsTokenCount),
53
+ promptTokensDetails: addTokenDetails(
54
+ a.promptTokensDetails,
55
+ b.promptTokensDetails
56
+ ),
57
+ candidatesTokensDetails: addTokenDetails(
58
+ a.candidatesTokensDetails,
59
+ b.candidatesTokensDetails
60
+ )
61
+ };
62
+ }
63
+ function addCounts(a, b) {
64
+ return a == null && b == null ? b != null ? b : a : (a != null ? a : 0) + (b != null ? b : 0);
65
+ }
66
+ function addTokenDetails(a, b) {
67
+ var _a;
68
+ if (a == null || b == null) {
69
+ return b != null ? b : a;
70
+ }
71
+ const tokenCounts = /* @__PURE__ */ new Map();
72
+ for (const { modality, tokenCount } of [...a, ...b]) {
73
+ tokenCounts.set(modality, ((_a = tokenCounts.get(modality)) != null ? _a : 0) + tokenCount);
74
+ }
75
+ return Array.from(tokenCounts, ([modality, tokenCount]) => ({
76
+ modality,
77
+ tokenCount
78
+ }));
79
+ }
80
+
81
+ // src/continue-google-stream.ts
82
+ function continueGoogleStream({
83
+ stream,
84
+ getContinuationToken,
85
+ continueStream
86
+ }) {
87
+ let reader = stream.getReader();
88
+ let pendingContinuationToken;
89
+ return new ReadableStream({
90
+ async pull(controller) {
91
+ while (true) {
92
+ const { done, value } = await reader.read();
93
+ if (!done) {
94
+ if (value.success) {
95
+ const token = getContinuationToken(value.value);
96
+ if (token != null) {
97
+ pendingContinuationToken = token;
98
+ }
99
+ }
100
+ controller.enqueue(value);
101
+ return;
102
+ }
103
+ if (pendingContinuationToken == null) {
104
+ controller.close();
105
+ return;
106
+ }
107
+ const continuationToken = pendingContinuationToken;
108
+ pendingContinuationToken = void 0;
109
+ try {
110
+ reader = (await continueStream(continuationToken)).getReader();
111
+ } catch (error) {
112
+ controller.enqueue({
113
+ success: false,
114
+ error,
115
+ rawValue: void 0
116
+ });
117
+ controller.close();
118
+ return;
119
+ }
120
+ }
121
+ },
122
+ async cancel(reason) {
123
+ await reader.cancel(reason);
124
+ }
125
+ });
126
+ }
127
+
34
128
  // src/convert-json-schema-to-openapi-schema.ts
35
129
  var import_provider = require("@ai-sdk/provider");
36
130
  var recursiveReferenceFunctionalityPrefix = "recursive JSON Schema reference:";
@@ -706,7 +800,17 @@ var googleGenerativeAIProviderOptions = (0, import_provider_utils3.lazySchema)(
706
800
  /**
707
801
  * Optional. The service tier to use for the request.
708
802
  */
709
- serviceTier: import_v42.z.enum(["standard", "flex", "priority"]).optional()
803
+ serviceTier: import_v42.z.enum(["standard", "flex", "priority"]).optional(),
804
+ /**
805
+ * Optional. Resumes a response that stopped with `MAX_TOKENS` because it
806
+ * used up its `maxOutputTokens` budget (Gemini 4 long decode). Pass the
807
+ * `continuationToken` from the previous response's provider metadata
808
+ * together with the original prompt and a higher `maxOutputTokens` (the
809
+ * budget is cumulative across requests). Requests that reach the
810
+ * per-request cap while budget remains (`CONTINUATION`) are continued
811
+ * automatically. Sent as the `continuationToken` body field.
812
+ */
813
+ continuationToken: import_v42.z.string().optional()
710
814
  })
711
815
  )
712
816
  );
@@ -1004,6 +1108,9 @@ function mapGoogleGenerativeAIFinishReason({
1004
1108
  case "STOP":
1005
1109
  return hasToolCalls ? "tool-calls" : "stop";
1006
1110
  case "MAX_TOKENS":
1111
+ // Gemini 4 long decode: the per-request cap was reached while budget
1112
+ // remains. Continued automatically; only surfaced if continuing fails.
1113
+ case "CONTINUATION":
1007
1114
  return "length";
1008
1115
  case "IMAGE_SAFETY":
1009
1116
  case "RECITATION":
@@ -1178,43 +1285,72 @@ var GoogleGenerativeAILanguageModel = class {
1178
1285
  } : googleToolConfig,
1179
1286
  cachedContent: googleOptions == null ? void 0 : googleOptions.cachedContent,
1180
1287
  labels: googleOptions == null ? void 0 : googleOptions.labels,
1181
- serviceTier: sanitizedServiceTier
1288
+ serviceTier: sanitizedServiceTier,
1289
+ ...(googleOptions == null ? void 0 : googleOptions.continuationToken) != null && {
1290
+ continuationToken: googleOptions.continuationToken
1291
+ }
1182
1292
  },
1183
1293
  warnings: [...warnings, ...toolWarnings]
1184
1294
  };
1185
1295
  }
1186
1296
  async doGenerate(options) {
1187
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
1297
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
1188
1298
  const { args, warnings } = await this.getArgs(options);
1189
1299
  const body = JSON.stringify(args);
1190
1300
  const mergedHeaders = (0, import_provider_utils4.combineHeaders)(
1191
1301
  await (0, import_provider_utils4.resolve)(this.config.headers),
1192
1302
  options.headers
1193
1303
  );
1194
- const {
1195
- responseHeaders,
1196
- value: response,
1197
- rawValue: rawResponse
1198
- } = await (0, import_provider_utils4.postJsonToApi)({
1304
+ const generateContent = (body2) => (0, import_provider_utils4.postJsonToApi)({
1199
1305
  url: `${this.config.baseURL}/${getModelPath(
1200
1306
  this.modelId
1201
1307
  )}:generateContent`,
1202
1308
  headers: mergedHeaders,
1203
- body: args,
1309
+ body: body2,
1204
1310
  failedResponseHandler: googleFailedResponseHandler,
1205
1311
  successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)(responseSchema),
1206
1312
  abortSignal: options.abortSignal,
1207
1313
  fetch: this.config.fetch
1208
1314
  });
1209
- const candidate = (_a = response.candidates) == null ? void 0 : _a[0];
1210
- const promptBlockReason = (_b = response.promptFeedback) == null ? void 0 : _b.blockReason;
1315
+ let {
1316
+ responseHeaders,
1317
+ value: response,
1318
+ rawValue: rawResponse
1319
+ } = await generateContent(args);
1320
+ const continuedParts = [];
1321
+ const groundingMetadataPerRequest = [];
1322
+ let continuedUsageMetadata;
1323
+ const firstPromptTokenCount = (_a = response.usageMetadata) == null ? void 0 : _a.promptTokenCount;
1324
+ while (true) {
1325
+ const candidate2 = (_b = response.candidates) == null ? void 0 : _b[0];
1326
+ groundingMetadataPerRequest.push((_c = candidate2 == null ? void 0 : candidate2.groundingMetadata) != null ? _c : null);
1327
+ const continuationToken = (candidate2 == null ? void 0 : candidate2.finishReason) === "CONTINUATION" ? candidate2.continuationToken : void 0;
1328
+ if (continuationToken == null) {
1329
+ break;
1330
+ }
1331
+ continuedParts.push(...(_e = (_d = candidate2 == null ? void 0 : candidate2.content) == null ? void 0 : _d.parts) != null ? _e : []);
1332
+ continuedUsageMetadata = addGoogleGenerativeAIUsageMetadata(
1333
+ continuedUsageMetadata,
1334
+ (_f = response.usageMetadata) != null ? _f : void 0
1335
+ );
1336
+ ({
1337
+ responseHeaders,
1338
+ value: response,
1339
+ rawValue: rawResponse
1340
+ } = await generateContent({ ...args, continuationToken }));
1341
+ }
1342
+ const candidate = (_g = response.candidates) == null ? void 0 : _g[0];
1343
+ const promptBlockReason = (_h = response.promptFeedback) == null ? void 0 : _h.blockReason;
1211
1344
  const isPromptBlocked = (candidate == null ? void 0 : candidate.finishReason) == null && promptBlockReason != null;
1212
1345
  const content = [];
1213
- const parts = (_d = (_c = candidate == null ? void 0 : candidate.content) == null ? void 0 : _c.parts) != null ? _d : [];
1214
- const usageMetadata = response.usageMetadata;
1346
+ const parts = [...continuedParts, ...(_j = (_i = candidate == null ? void 0 : candidate.content) == null ? void 0 : _i.parts) != null ? _j : []];
1347
+ const usageMetadata = addGoogleGenerativeAIUsageMetadata(
1348
+ continuedUsageMetadata,
1349
+ (_k = response.usageMetadata) != null ? _k : void 0
1350
+ );
1215
1351
  let lastCodeExecutionToolCallId;
1216
1352
  for (const part of parts) {
1217
- if ("executableCode" in part && ((_e = part.executableCode) == null ? void 0 : _e.code)) {
1353
+ if ("executableCode" in part && ((_l = part.executableCode) == null ? void 0 : _l.code)) {
1218
1354
  const toolCallId = this.config.generateId();
1219
1355
  lastCodeExecutionToolCallId = toolCallId;
1220
1356
  content.push({
@@ -1255,7 +1391,7 @@ var GoogleGenerativeAILanguageModel = class {
1255
1391
  } else if ("functionCall" in part) {
1256
1392
  content.push({
1257
1393
  type: "tool-call",
1258
- toolCallId: (_f = part.functionCall.id) != null ? _f : this.config.generateId(),
1394
+ toolCallId: (_m = part.functionCall.id) != null ? _m : this.config.generateId(),
1259
1395
  toolName: part.functionCall.name,
1260
1396
  input: JSON.stringify(part.functionCall.args),
1261
1397
  providerMetadata: part.thoughtSignature ? { google: { thoughtSignature: part.thoughtSignature } } : void 0
@@ -1268,10 +1404,10 @@ var GoogleGenerativeAILanguageModel = class {
1268
1404
  });
1269
1405
  }
1270
1406
  }
1271
- const sources = (_g = extractSources({
1407
+ const sources = (_n = extractSources({
1272
1408
  groundingMetadata: candidate == null ? void 0 : candidate.groundingMetadata,
1273
1409
  generateId: this.config.generateId
1274
- })) != null ? _g : [];
1410
+ })) != null ? _n : [];
1275
1411
  for (const source of sources) {
1276
1412
  content.push(source);
1277
1413
  }
@@ -1282,20 +1418,23 @@ var GoogleGenerativeAILanguageModel = class {
1282
1418
  hasToolCalls: content.some((part) => part.type === "tool-call")
1283
1419
  }),
1284
1420
  usage: {
1285
- inputTokens: (_h = usageMetadata == null ? void 0 : usageMetadata.promptTokenCount) != null ? _h : void 0,
1286
- outputTokens: (_i = usageMetadata == null ? void 0 : usageMetadata.candidatesTokenCount) != null ? _i : void 0,
1287
- totalTokens: (_j = usageMetadata == null ? void 0 : usageMetadata.totalTokenCount) != null ? _j : void 0,
1288
- reasoningTokens: (_k = usageMetadata == null ? void 0 : usageMetadata.thoughtsTokenCount) != null ? _k : void 0,
1289
- cachedInputTokens: (_l = usageMetadata == null ? void 0 : usageMetadata.cachedContentTokenCount) != null ? _l : void 0
1421
+ inputTokens: (_o = usageMetadata == null ? void 0 : usageMetadata.promptTokenCount) != null ? _o : void 0,
1422
+ outputTokens: (_p = usageMetadata == null ? void 0 : usageMetadata.candidatesTokenCount) != null ? _p : void 0,
1423
+ totalTokens: (_q = usageMetadata == null ? void 0 : usageMetadata.totalTokenCount) != null ? _q : void 0,
1424
+ reasoningTokens: (_r = usageMetadata == null ? void 0 : usageMetadata.thoughtsTokenCount) != null ? _r : void 0,
1425
+ cachedInputTokens: (_s = usageMetadata == null ? void 0 : usageMetadata.cachedContentTokenCount) != null ? _s : void 0
1290
1426
  },
1291
1427
  warnings,
1292
1428
  providerMetadata: {
1293
1429
  google: {
1294
- promptFeedback: (_m = response.promptFeedback) != null ? _m : null,
1295
- groundingMetadata: (_n = candidate == null ? void 0 : candidate.groundingMetadata) != null ? _n : null,
1296
- urlContextMetadata: (_o = candidate == null ? void 0 : candidate.urlContextMetadata) != null ? _o : null,
1297
- safetyRatings: (_p = candidate == null ? void 0 : candidate.safetyRatings) != null ? _p : null,
1298
- serviceTier: (_q = response.serviceTier) != null ? _q : null,
1430
+ promptFeedback: (_t = response.promptFeedback) != null ? _t : null,
1431
+ groundingMetadata: (_u = candidate == null ? void 0 : candidate.groundingMetadata) != null ? _u : null,
1432
+ ...groundingMetadataPerRequest.length > 1 ? { groundingMetadataPerRequest } : {},
1433
+ urlContextMetadata: (_v = candidate == null ? void 0 : candidate.urlContextMetadata) != null ? _v : null,
1434
+ safetyRatings: (_w = candidate == null ? void 0 : candidate.safetyRatings) != null ? _w : null,
1435
+ serviceTier: (_x = response.serviceTier) != null ? _x : null,
1436
+ ...(candidate == null ? void 0 : candidate.continuationToken) != null && candidate.finishReason === "MAX_TOKENS" ? { continuationToken: candidate.continuationToken } : {},
1437
+ ...continuedUsageMetadata != null && firstPromptTokenCount != null ? { initialPromptTokenCount: firstPromptTokenCount } : {},
1299
1438
  usageMetadata: usageMetadata != null ? usageMetadata : null
1300
1439
  }
1301
1440
  },
@@ -1314,17 +1453,40 @@ var GoogleGenerativeAILanguageModel = class {
1314
1453
  await (0, import_provider_utils4.resolve)(this.config.headers),
1315
1454
  options.headers
1316
1455
  );
1317
- const { responseHeaders, value: response } = await (0, import_provider_utils4.postJsonToApi)({
1456
+ const streamGenerateContent = (body2) => (0, import_provider_utils4.postJsonToApi)({
1318
1457
  url: `${this.config.baseURL}/${getModelPath(
1319
1458
  this.modelId
1320
1459
  )}:streamGenerateContent?alt=sse`,
1321
1460
  headers,
1322
- body: args,
1461
+ body: body2,
1323
1462
  failedResponseHandler: googleFailedResponseHandler,
1324
1463
  successfulResponseHandler: (0, import_provider_utils4.createEventSourceResponseHandler)(chunkSchema),
1325
1464
  abortSignal: options.abortSignal,
1326
1465
  fetch: this.config.fetch
1327
1466
  });
1467
+ const { responseHeaders, value: firstResponse } = await streamGenerateContent(args);
1468
+ const groundingMetadataPerRequest = [];
1469
+ let requestGroundingMetadata = null;
1470
+ const response = continueGoogleStream({
1471
+ stream: firstResponse,
1472
+ getContinuationToken: (chunk) => {
1473
+ var _a, _b;
1474
+ const candidate = (_a = chunk.candidates) == null ? void 0 : _a[0];
1475
+ if ((candidate == null ? void 0 : candidate.groundingMetadata) != null) {
1476
+ requestGroundingMetadata = candidate.groundingMetadata;
1477
+ }
1478
+ return (candidate == null ? void 0 : candidate.finishReason) === "CONTINUATION" ? (_b = candidate.continuationToken) != null ? _b : void 0 : void 0;
1479
+ },
1480
+ continueStream: async (continuationToken) => {
1481
+ const { value } = await streamGenerateContent({
1482
+ ...args,
1483
+ continuationToken
1484
+ });
1485
+ groundingMetadataPerRequest.push(requestGroundingMetadata);
1486
+ requestGroundingMetadata = null;
1487
+ return value;
1488
+ }
1489
+ });
1328
1490
  let finishReason = "unknown";
1329
1491
  const usage = {
1330
1492
  inputTokens: void 0,
@@ -1335,6 +1497,10 @@ var GoogleGenerativeAILanguageModel = class {
1335
1497
  let lastGroundingMetadata = null;
1336
1498
  let lastUrlContextMetadata = null;
1337
1499
  let serviceTier = null;
1500
+ let requestUsageMetadata;
1501
+ let continuedUsageMetadata;
1502
+ let lastContinuationToken = null;
1503
+ let initialPromptTokenCount = void 0;
1338
1504
  const generateId2 = this.config.generateId;
1339
1505
  let hasToolCalls = false;
1340
1506
  let currentTextBlockId = null;
@@ -1358,7 +1524,13 @@ var GoogleGenerativeAILanguageModel = class {
1358
1524
  return;
1359
1525
  }
1360
1526
  const value = chunk.value;
1361
- const usageMetadata = value.usageMetadata;
1527
+ if (value.usageMetadata != null) {
1528
+ requestUsageMetadata = value.usageMetadata;
1529
+ }
1530
+ const usageMetadata = value.usageMetadata == null ? void 0 : addGoogleGenerativeAIUsageMetadata(
1531
+ continuedUsageMetadata,
1532
+ requestUsageMetadata
1533
+ );
1362
1534
  if (usageMetadata != null) {
1363
1535
  usage.inputTokens = (_a = usageMetadata.promptTokenCount) != null ? _a : void 0;
1364
1536
  usage.outputTokens = (_b = usageMetadata.candidatesTokenCount) != null ? _b : void 0;
@@ -1370,6 +1542,19 @@ var GoogleGenerativeAILanguageModel = class {
1370
1542
  serviceTier = value.serviceTier;
1371
1543
  }
1372
1544
  const candidate = (_f = value.candidates) == null ? void 0 : _f[0];
1545
+ if ((candidate == null ? void 0 : candidate.continuationToken) != null) {
1546
+ lastContinuationToken = candidate.continuationToken;
1547
+ }
1548
+ if ((candidate == null ? void 0 : candidate.finishReason) === "CONTINUATION") {
1549
+ if (continuedUsageMetadata == null) {
1550
+ initialPromptTokenCount = requestUsageMetadata == null ? void 0 : requestUsageMetadata.promptTokenCount;
1551
+ }
1552
+ continuedUsageMetadata = addGoogleGenerativeAIUsageMetadata(
1553
+ continuedUsageMetadata,
1554
+ requestUsageMetadata
1555
+ );
1556
+ requestUsageMetadata = void 0;
1557
+ }
1373
1558
  if (candidate == null) {
1374
1559
  const promptBlockReason2 = (_g = value.promptFeedback) == null ? void 0 : _g.blockReason;
1375
1560
  if (promptBlockReason2 != null) {
@@ -1552,7 +1737,12 @@ var GoogleGenerativeAILanguageModel = class {
1552
1737
  groundingMetadata: lastGroundingMetadata,
1553
1738
  urlContextMetadata: lastUrlContextMetadata,
1554
1739
  safetyRatings: (_o = candidate.safetyRatings) != null ? _o : null,
1555
- serviceTier
1740
+ serviceTier,
1741
+ // Only surface the token when the response stopped early
1742
+ // (budget used up, or continuing failed), not for the
1743
+ // checkpoint tokens of a stream that finished normally.
1744
+ ...lastContinuationToken != null && (rawFinishReason === "MAX_TOKENS" || rawFinishReason === "CONTINUATION") ? { continuationToken: lastContinuationToken } : {},
1745
+ ...initialPromptTokenCount != null ? { initialPromptTokenCount } : {}
1556
1746
  }
1557
1747
  };
1558
1748
  if (usageMetadata != null) {
@@ -1573,6 +1763,18 @@ var GoogleGenerativeAILanguageModel = class {
1573
1763
  id: currentReasoningBlockId
1574
1764
  });
1575
1765
  }
1766
+ if (groundingMetadataPerRequest.length > 0) {
1767
+ providerMetadata = {
1768
+ ...providerMetadata,
1769
+ google: {
1770
+ ...providerMetadata == null ? void 0 : providerMetadata.google,
1771
+ groundingMetadataPerRequest: [
1772
+ ...groundingMetadataPerRequest,
1773
+ requestGroundingMetadata
1774
+ ]
1775
+ }
1776
+ };
1777
+ }
1576
1778
  controller.enqueue({
1577
1779
  type: "finish",
1578
1780
  finishReason,
@@ -1823,6 +2025,7 @@ var responseSchema = (0, import_provider_utils4.lazySchema)(
1823
2025
  import_v43.z.object({
1824
2026
  content: getContentSchema().nullish().or(import_v43.z.object({}).strict()),
1825
2027
  finishReason: import_v43.z.string().nullish(),
2028
+ continuationToken: import_v43.z.string().nullish(),
1826
2029
  safetyRatings: import_v43.z.array(getSafetyRatingSchema()).nullish(),
1827
2030
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1828
2031
  urlContextMetadata: getUrlContextMetadataSchema().nullish()
@@ -1844,6 +2047,7 @@ var chunkSchema = (0, import_provider_utils4.lazySchema)(
1844
2047
  import_v43.z.object({
1845
2048
  content: getContentSchema().nullish(),
1846
2049
  finishReason: import_v43.z.string().nullish(),
2050
+ continuationToken: import_v43.z.string().nullish(),
1847
2051
  safetyRatings: import_v43.z.array(getSafetyRatingSchema()).nullish(),
1848
2052
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1849
2053
  urlContextMetadata: getUrlContextMetadataSchema().nullish()