@ai-sdk/google 3.0.59 → 3.0.61

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @ai-sdk/google
2
2
 
3
+ ## 3.0.61
4
+
5
+ ### Patch Changes
6
+
7
+ - 03a04f6: feat(google-vertex): add support for streaming tool arguments input
8
+
9
+ ## 3.0.60
10
+
11
+ ### Patch Changes
12
+
13
+ - d42076d: Add AI Gateway hint to provider READMEs
14
+
3
15
  ## 3.0.59
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  The **[Google Generative AI provider](https://ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for the [Google Generative AI](https://ai.google/discover/generativeai/) APIs.
4
4
 
5
+ > **Deploying to Vercel?** With Vercel's AI Gateway you can access Google (and hundreds of models from other providers) — no additional packages, API keys, or extra cost. [Get started with AI Gateway](https://vercel.com/ai-gateway).
6
+
5
7
  ## Setup
6
8
 
7
9
  The Google Generative AI provider is available in the `@ai-sdk/google` module. You can install it with
package/dist/index.d.mts CHANGED
@@ -39,6 +39,7 @@ declare const googleLanguageModelOptions: _ai_sdk_provider_utils.LazySchema<{
39
39
  longitude: number;
40
40
  } | undefined;
41
41
  } | undefined;
42
+ streamFunctionCallArguments?: boolean | undefined;
42
43
  serviceTier?: "standard" | "flex" | "priority" | undefined;
43
44
  }>;
44
45
  type GoogleLanguageModelOptions = InferSchema<typeof googleLanguageModelOptions>;
@@ -48,8 +49,17 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
48
49
  content?: Record<string, never> | {
49
50
  parts?: ({
50
51
  functionCall: {
51
- name: string;
52
- args: unknown;
52
+ name?: string | null | undefined;
53
+ args?: unknown;
54
+ partialArgs?: {
55
+ jsonPath: string;
56
+ stringValue?: string | null | undefined;
57
+ numberValue?: number | null | undefined;
58
+ boolValue?: boolean | null | undefined;
59
+ nullValue?: unknown;
60
+ willContinue?: boolean | null | undefined;
61
+ }[] | null | undefined;
62
+ willContinue?: boolean | null | undefined;
53
63
  };
54
64
  thoughtSignature?: string | null | undefined;
55
65
  } | {
package/dist/index.d.ts CHANGED
@@ -39,6 +39,7 @@ declare const googleLanguageModelOptions: _ai_sdk_provider_utils.LazySchema<{
39
39
  longitude: number;
40
40
  } | undefined;
41
41
  } | undefined;
42
+ streamFunctionCallArguments?: boolean | undefined;
42
43
  serviceTier?: "standard" | "flex" | "priority" | undefined;
43
44
  }>;
44
45
  type GoogleLanguageModelOptions = InferSchema<typeof googleLanguageModelOptions>;
@@ -48,8 +49,17 @@ declare const responseSchema: _ai_sdk_provider_utils.LazySchema<{
48
49
  content?: Record<string, never> | {
49
50
  parts?: ({
50
51
  functionCall: {
51
- name: string;
52
- args: unknown;
52
+ name?: string | null | undefined;
53
+ args?: unknown;
54
+ partialArgs?: {
55
+ jsonPath: string;
56
+ stringValue?: string | null | undefined;
57
+ numberValue?: number | null | undefined;
58
+ boolValue?: boolean | null | undefined;
59
+ nullValue?: unknown;
60
+ willContinue?: boolean | null | undefined;
61
+ }[] | null | undefined;
62
+ willContinue?: boolean | null | undefined;
53
63
  };
54
64
  thoughtSignature?: string | null | undefined;
55
65
  } | {
package/dist/index.js CHANGED
@@ -30,7 +30,7 @@ module.exports = __toCommonJS(index_exports);
30
30
  var import_provider_utils16 = require("@ai-sdk/provider-utils");
31
31
 
32
32
  // src/version.ts
33
- var VERSION = true ? "3.0.59" : "0.0.0-test";
33
+ var VERSION = true ? "3.0.61" : "0.0.0-test";
34
34
 
35
35
  // src/google-generative-ai-embedding-model.ts
36
36
  var import_provider = require("@ai-sdk/provider");
@@ -819,6 +819,16 @@ var googleLanguageModelOptions = (0, import_provider_utils5.lazySchema)(
819
819
  longitude: import_v44.z.number()
820
820
  }).optional()
821
821
  }).optional(),
822
+ /**
823
+ * Optional. When set to true, function call arguments will be streamed
824
+ * incrementally via partialArgs in streaming responses. Only supported
825
+ * on the Vertex AI API (not the Gemini API).
826
+ *
827
+ * @default true
828
+ *
829
+ * https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#streaming-fc
830
+ */
831
+ streamFunctionCallArguments: import_v44.z.boolean().optional(),
822
832
  /**
823
833
  * Optional. The service tier to use for the request.
824
834
  */
@@ -1077,6 +1087,229 @@ function prepareTools({
1077
1087
  }
1078
1088
  }
1079
1089
 
1090
+ // src/google-json-accumulator.ts
1091
+ var GoogleJSONAccumulator = class {
1092
+ constructor() {
1093
+ this.accumulatedArgs = {};
1094
+ this.jsonText = "";
1095
+ /**
1096
+ * Stack representing the currently "open" containers in the JSON output.
1097
+ * Entry 0 is always the root `{` object once the first value is written.
1098
+ */
1099
+ this.pathStack = [];
1100
+ /**
1101
+ * Whether a string value is currently "open" (willContinue was true),
1102
+ * meaning the closing quote has not yet been emitted.
1103
+ */
1104
+ this.stringOpen = false;
1105
+ }
1106
+ /**
1107
+ * Input: [{jsonPath:"$.brightness",numberValue:50}]
1108
+ * Output: { currentJSON:{brightness:50}, textDelta:'{"brightness":50' }
1109
+ */
1110
+ processPartialArgs(partialArgs) {
1111
+ let delta = "";
1112
+ for (const arg of partialArgs) {
1113
+ const rawPath = arg.jsonPath.replace(/^\$\./, "");
1114
+ if (!rawPath) continue;
1115
+ const segments = parsePath(rawPath);
1116
+ const existingValue = getNestedValue(this.accumulatedArgs, segments);
1117
+ const isStringContinuation = arg.stringValue != null && existingValue !== void 0;
1118
+ if (isStringContinuation) {
1119
+ const escaped = JSON.stringify(arg.stringValue).slice(1, -1);
1120
+ setNestedValue(
1121
+ this.accumulatedArgs,
1122
+ segments,
1123
+ existingValue + arg.stringValue
1124
+ );
1125
+ delta += escaped;
1126
+ continue;
1127
+ }
1128
+ const resolved = resolvePartialArgValue(arg);
1129
+ if (resolved == null) continue;
1130
+ setNestedValue(this.accumulatedArgs, segments, resolved.value);
1131
+ delta += this.emitNavigationTo(segments, arg, resolved.json);
1132
+ }
1133
+ this.jsonText += delta;
1134
+ return {
1135
+ currentJSON: this.accumulatedArgs,
1136
+ textDelta: delta
1137
+ };
1138
+ }
1139
+ /**
1140
+ * Input: jsonText='{"brightness":50', accumulatedArgs={brightness:50}
1141
+ * Output: { finalJSON:'{"brightness":50}', closingDelta:'}' }
1142
+ */
1143
+ finalize() {
1144
+ const finalArgs = JSON.stringify(this.accumulatedArgs);
1145
+ const closingDelta = finalArgs.slice(this.jsonText.length);
1146
+ return { finalJSON: finalArgs, closingDelta };
1147
+ }
1148
+ /**
1149
+ * Input: pathStack=[] (first call) or pathStack=[root,...] (subsequent calls)
1150
+ * Output: '{' (first call) or '' (subsequent calls)
1151
+ */
1152
+ ensureRoot() {
1153
+ if (this.pathStack.length === 0) {
1154
+ this.pathStack.push({ segment: "", isArray: false, childCount: 0 });
1155
+ return "{";
1156
+ }
1157
+ return "";
1158
+ }
1159
+ /**
1160
+ * Emits the JSON text fragment needed to navigate from the current open
1161
+ * path to the new leaf at `targetSegments`, then writes the value.
1162
+ *
1163
+ * Input: targetSegments=["recipe","name"], arg={jsonPath:"$.recipe.name",stringValue:"Lasagna"}, valueJson='"Lasagna"'
1164
+ * Output: '{"recipe":{"name":"Lasagna"'
1165
+ */
1166
+ emitNavigationTo(targetSegments, arg, valueJson) {
1167
+ let fragment = "";
1168
+ if (this.stringOpen) {
1169
+ fragment += '"';
1170
+ this.stringOpen = false;
1171
+ }
1172
+ fragment += this.ensureRoot();
1173
+ const targetContainerSegments = targetSegments.slice(0, -1);
1174
+ const leafSegment = targetSegments[targetSegments.length - 1];
1175
+ const commonDepth = this.findCommonStackDepth(targetContainerSegments);
1176
+ fragment += this.closeDownTo(commonDepth);
1177
+ fragment += this.openDownTo(targetContainerSegments, leafSegment);
1178
+ fragment += this.emitLeaf(leafSegment, arg, valueJson);
1179
+ return fragment;
1180
+ }
1181
+ /**
1182
+ * Returns the stack depth to preserve when navigating to a new target
1183
+ * container path. Always >= 1 (the root is never popped).
1184
+ *
1185
+ * Input: stack=[root,"recipe","ingredients",0], target=["recipe","ingredients",1]
1186
+ * Output: 3 (keep root+"recipe"+"ingredients")
1187
+ */
1188
+ findCommonStackDepth(targetContainer) {
1189
+ const maxDepth = Math.min(
1190
+ this.pathStack.length - 1,
1191
+ targetContainer.length
1192
+ );
1193
+ let common = 0;
1194
+ for (let i = 0; i < maxDepth; i++) {
1195
+ if (this.pathStack[i + 1].segment === targetContainer[i]) {
1196
+ common++;
1197
+ } else {
1198
+ break;
1199
+ }
1200
+ }
1201
+ return common + 1;
1202
+ }
1203
+ /**
1204
+ * Closes containers from the current stack depth back down to `targetDepth`.
1205
+ *
1206
+ * Input: this.pathStack=[root,"recipe","ingredients",0], targetDepth=3
1207
+ * Output: '}'
1208
+ */
1209
+ closeDownTo(targetDepth) {
1210
+ let fragment = "";
1211
+ while (this.pathStack.length > targetDepth) {
1212
+ const entry = this.pathStack.pop();
1213
+ fragment += entry.isArray ? "]" : "}";
1214
+ }
1215
+ return fragment;
1216
+ }
1217
+ /**
1218
+ * Opens containers from the current stack depth down to the full target
1219
+ * container path, emitting opening `{`, `[`, keys, and commas as needed.
1220
+ * `leafSegment` is used to determine if the innermost container is an array.
1221
+ *
1222
+ * Input: this.pathStack=[root], targetContainer=["recipe","ingredients"], leafSegment=0
1223
+ * Output: '"recipe":{"ingredients":['
1224
+ */
1225
+ openDownTo(targetContainer, leafSegment) {
1226
+ let fragment = "";
1227
+ const startIdx = this.pathStack.length - 1;
1228
+ for (let i = startIdx; i < targetContainer.length; i++) {
1229
+ const seg = targetContainer[i];
1230
+ const parentEntry = this.pathStack[this.pathStack.length - 1];
1231
+ if (parentEntry.childCount > 0) {
1232
+ fragment += ",";
1233
+ }
1234
+ parentEntry.childCount++;
1235
+ if (typeof seg === "string") {
1236
+ fragment += `${JSON.stringify(seg)}:`;
1237
+ }
1238
+ const childSeg = i + 1 < targetContainer.length ? targetContainer[i + 1] : leafSegment;
1239
+ const isArray = typeof childSeg === "number";
1240
+ fragment += isArray ? "[" : "{";
1241
+ this.pathStack.push({ segment: seg, isArray, childCount: 0 });
1242
+ }
1243
+ return fragment;
1244
+ }
1245
+ /**
1246
+ * Emits the comma, key, and value for a leaf entry in the current container.
1247
+ *
1248
+ * Input: leafSegment="name", arg={stringValue:"Lasagna"}, valueJson='"Lasagna"'
1249
+ * Output: '"name":"Lasagna"' (or ',"name":"Lasagna"' if container.childCount > 0)
1250
+ */
1251
+ emitLeaf(leafSegment, arg, valueJson) {
1252
+ let fragment = "";
1253
+ const container = this.pathStack[this.pathStack.length - 1];
1254
+ if (container.childCount > 0) {
1255
+ fragment += ",";
1256
+ }
1257
+ container.childCount++;
1258
+ if (typeof leafSegment === "string") {
1259
+ fragment += `${JSON.stringify(leafSegment)}:`;
1260
+ }
1261
+ if (arg.stringValue != null && arg.willContinue) {
1262
+ fragment += valueJson.slice(0, -1);
1263
+ this.stringOpen = true;
1264
+ } else {
1265
+ fragment += valueJson;
1266
+ }
1267
+ return fragment;
1268
+ }
1269
+ };
1270
+ function parsePath(rawPath) {
1271
+ const segments = [];
1272
+ for (const part of rawPath.split(".")) {
1273
+ const bracketIdx = part.indexOf("[");
1274
+ if (bracketIdx === -1) {
1275
+ segments.push(part);
1276
+ } else {
1277
+ if (bracketIdx > 0) segments.push(part.slice(0, bracketIdx));
1278
+ for (const m of part.matchAll(/\[(\d+)\]/g)) {
1279
+ segments.push(parseInt(m[1], 10));
1280
+ }
1281
+ }
1282
+ }
1283
+ return segments;
1284
+ }
1285
+ function getNestedValue(obj, segments) {
1286
+ let current = obj;
1287
+ for (const seg of segments) {
1288
+ if (current == null || typeof current !== "object") return void 0;
1289
+ current = current[seg];
1290
+ }
1291
+ return current;
1292
+ }
1293
+ function setNestedValue(obj, segments, value) {
1294
+ let current = obj;
1295
+ for (let i = 0; i < segments.length - 1; i++) {
1296
+ const seg = segments[i];
1297
+ const nextSeg = segments[i + 1];
1298
+ if (current[seg] == null) {
1299
+ current[seg] = typeof nextSeg === "number" ? [] : {};
1300
+ }
1301
+ current = current[seg];
1302
+ }
1303
+ current[segments[segments.length - 1]] = value;
1304
+ }
1305
+ function resolvePartialArgValue(arg) {
1306
+ var _a, _b;
1307
+ const value = (_b = (_a = arg.stringValue) != null ? _a : arg.numberValue) != null ? _b : arg.boolValue;
1308
+ if (value != null) return { value, json: JSON.stringify(value) };
1309
+ if ("nullValue" in arg) return { value: null, json: "null" };
1310
+ return void 0;
1311
+ }
1312
+
1080
1313
  // src/map-google-generative-ai-finish-reason.ts
1081
1314
  function mapGoogleGenerativeAIFinishReason({
1082
1315
  finishReason,
@@ -1134,7 +1367,7 @@ var GoogleGenerativeAILanguageModel = class {
1134
1367
  toolChoice,
1135
1368
  providerOptions
1136
1369
  }) {
1137
- var _a;
1370
+ var _a, _b;
1138
1371
  const warnings = [];
1139
1372
  const providerOptionsName = this.config.provider.includes("vertex") ? "vertex" : "google";
1140
1373
  let googleOptions = await (0, import_provider_utils6.parseProviderOptions)({
@@ -1149,14 +1382,21 @@ var GoogleGenerativeAILanguageModel = class {
1149
1382
  schema: googleLanguageModelOptions
1150
1383
  });
1151
1384
  }
1385
+ const isVertexProvider = this.config.provider.startsWith("google.vertex.");
1152
1386
  if ((tools == null ? void 0 : tools.some(
1153
1387
  (tool) => tool.type === "provider" && tool.id === "google.vertex_rag_store"
1154
- )) && !this.config.provider.startsWith("google.vertex.")) {
1388
+ )) && !isVertexProvider) {
1155
1389
  warnings.push({
1156
1390
  type: "other",
1157
1391
  message: `The 'vertex_rag_store' tool is only supported with the Google Vertex provider and might not be supported or could behave unexpectedly with the current Google provider (${this.config.provider}).`
1158
1392
  });
1159
1393
  }
1394
+ if ((googleOptions == null ? void 0 : googleOptions.streamFunctionCallArguments) && !isVertexProvider) {
1395
+ warnings.push({
1396
+ type: "other",
1397
+ message: `'streamFunctionCallArguments' is only supported on the Vertex AI API and will be ignored with the current Google provider (${this.config.provider}). See https://docs.cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling#streaming-fc`
1398
+ });
1399
+ }
1160
1400
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
1161
1401
  const supportsFunctionResponseParts = this.modelId.startsWith("gemini-3");
1162
1402
  const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
@@ -1176,6 +1416,19 @@ var GoogleGenerativeAILanguageModel = class {
1176
1416
  toolChoice,
1177
1417
  modelId: this.modelId
1178
1418
  });
1419
+ const streamFunctionCallArguments = isVertexProvider ? (_a = googleOptions == null ? void 0 : googleOptions.streamFunctionCallArguments) != null ? _a : true : void 0;
1420
+ const toolConfig = googleToolConfig || streamFunctionCallArguments || (googleOptions == null ? void 0 : googleOptions.retrievalConfig) ? {
1421
+ ...googleToolConfig,
1422
+ ...streamFunctionCallArguments && {
1423
+ functionCallingConfig: {
1424
+ ...googleToolConfig == null ? void 0 : googleToolConfig.functionCallingConfig,
1425
+ streamFunctionCallArguments: true
1426
+ }
1427
+ },
1428
+ ...(googleOptions == null ? void 0 : googleOptions.retrievalConfig) && {
1429
+ retrievalConfig: googleOptions.retrievalConfig
1430
+ }
1431
+ } : void 0;
1179
1432
  return {
1180
1433
  args: {
1181
1434
  generationConfig: {
@@ -1193,7 +1446,7 @@ var GoogleGenerativeAILanguageModel = class {
1193
1446
  responseSchema: (responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && // Google GenAI does not support all OpenAPI Schema features,
1194
1447
  // so this is needed as an escape hatch:
1195
1448
  // TODO convert into provider option
1196
- ((_a = googleOptions == null ? void 0 : googleOptions.structuredOutputs) != null ? _a : true) ? convertJSONSchemaToOpenAPISchema(responseFormat.schema) : void 0,
1449
+ ((_b = googleOptions == null ? void 0 : googleOptions.structuredOutputs) != null ? _b : true) ? convertJSONSchemaToOpenAPISchema(responseFormat.schema) : void 0,
1197
1450
  ...(googleOptions == null ? void 0 : googleOptions.audioTimestamp) && {
1198
1451
  audioTimestamp: googleOptions.audioTimestamp
1199
1452
  },
@@ -1211,10 +1464,7 @@ var GoogleGenerativeAILanguageModel = class {
1211
1464
  systemInstruction: isGemmaModel ? void 0 : systemInstruction,
1212
1465
  safetySettings: googleOptions == null ? void 0 : googleOptions.safetySettings,
1213
1466
  tools: googleTools2,
1214
- toolConfig: (googleOptions == null ? void 0 : googleOptions.retrievalConfig) ? {
1215
- ...googleToolConfig,
1216
- retrievalConfig: googleOptions.retrievalConfig
1217
- } : googleToolConfig,
1467
+ toolConfig,
1218
1468
  cachedContent: googleOptions == null ? void 0 : googleOptions.cachedContent,
1219
1469
  labels: googleOptions == null ? void 0 : googleOptions.labels,
1220
1470
  serviceTier: googleOptions == null ? void 0 : googleOptions.serviceTier
@@ -1292,7 +1542,7 @@ var GoogleGenerativeAILanguageModel = class {
1292
1542
  providerMetadata: thoughtSignatureMetadata
1293
1543
  });
1294
1544
  }
1295
- } else if ("functionCall" in part) {
1545
+ } else if ("functionCall" in part && part.functionCall.name != null && part.functionCall.args != null) {
1296
1546
  content.push({
1297
1547
  type: "tool-call",
1298
1548
  toolCallId: this.config.generateId(),
@@ -1438,6 +1688,7 @@ var GoogleGenerativeAILanguageModel = class {
1438
1688
  const emittedSourceUrls = /* @__PURE__ */ new Set();
1439
1689
  let lastCodeExecutionToolCallId;
1440
1690
  let lastServerToolCallId;
1691
+ const activeStreamingToolCalls = [];
1441
1692
  return {
1442
1693
  stream: response.pipeThrough(
1443
1694
  new TransformStream({
@@ -1445,7 +1696,7 @@ var GoogleGenerativeAILanguageModel = class {
1445
1696
  controller.enqueue({ type: "stream-start", warnings });
1446
1697
  },
1447
1698
  transform(chunk, controller) {
1448
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1699
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
1449
1700
  if (options.includeRawChunks) {
1450
1701
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1451
1702
  }
@@ -1638,36 +1889,110 @@ var GoogleGenerativeAILanguageModel = class {
1638
1889
  lastServerToolCallId = void 0;
1639
1890
  }
1640
1891
  }
1641
- const toolCallDeltas = getToolCallsFromParts({
1642
- parts: content.parts,
1643
- generateId: generateId3,
1644
- providerOptionsName
1645
- });
1646
- if (toolCallDeltas != null) {
1647
- for (const toolCall of toolCallDeltas) {
1892
+ for (const part of parts) {
1893
+ if (!("functionCall" in part)) continue;
1894
+ const providerMeta = part.thoughtSignature ? {
1895
+ [providerOptionsName]: {
1896
+ thoughtSignature: part.thoughtSignature
1897
+ }
1898
+ } : void 0;
1899
+ const isStreamingChunk = part.functionCall.partialArgs != null || part.functionCall.name != null && part.functionCall.willContinue === true;
1900
+ const isTerminalChunk = part.functionCall.name == null && part.functionCall.args == null && part.functionCall.partialArgs == null && part.functionCall.willContinue == null;
1901
+ const isCompleteCall = part.functionCall.name != null && part.functionCall.args != null && part.functionCall.partialArgs == null;
1902
+ if (isStreamingChunk) {
1903
+ if (part.functionCall.name != null && part.functionCall.willContinue === true) {
1904
+ const toolCallId = generateId3();
1905
+ const accumulator = new GoogleJSONAccumulator();
1906
+ activeStreamingToolCalls.push({
1907
+ toolCallId,
1908
+ toolName: part.functionCall.name,
1909
+ accumulator,
1910
+ providerMetadata: providerMeta
1911
+ });
1912
+ controller.enqueue({
1913
+ type: "tool-input-start",
1914
+ id: toolCallId,
1915
+ toolName: part.functionCall.name,
1916
+ providerMetadata: providerMeta
1917
+ });
1918
+ if (part.functionCall.partialArgs != null) {
1919
+ const { textDelta } = accumulator.processPartialArgs(
1920
+ part.functionCall.partialArgs
1921
+ );
1922
+ if (textDelta.length > 0) {
1923
+ controller.enqueue({
1924
+ type: "tool-input-delta",
1925
+ id: toolCallId,
1926
+ delta: textDelta,
1927
+ providerMetadata: providerMeta
1928
+ });
1929
+ }
1930
+ }
1931
+ } else if (part.functionCall.partialArgs != null && activeStreamingToolCalls.length > 0) {
1932
+ const active = activeStreamingToolCalls[activeStreamingToolCalls.length - 1];
1933
+ const { textDelta } = active.accumulator.processPartialArgs(
1934
+ part.functionCall.partialArgs
1935
+ );
1936
+ if (textDelta.length > 0) {
1937
+ controller.enqueue({
1938
+ type: "tool-input-delta",
1939
+ id: active.toolCallId,
1940
+ delta: textDelta,
1941
+ providerMetadata: providerMeta
1942
+ });
1943
+ }
1944
+ }
1945
+ } else if (isTerminalChunk && activeStreamingToolCalls.length > 0) {
1946
+ const active = activeStreamingToolCalls.pop();
1947
+ const { finalJSON, closingDelta } = active.accumulator.finalize();
1948
+ if (closingDelta.length > 0) {
1949
+ controller.enqueue({
1950
+ type: "tool-input-delta",
1951
+ id: active.toolCallId,
1952
+ delta: closingDelta,
1953
+ providerMetadata: active.providerMetadata
1954
+ });
1955
+ }
1956
+ controller.enqueue({
1957
+ type: "tool-input-end",
1958
+ id: active.toolCallId,
1959
+ providerMetadata: active.providerMetadata
1960
+ });
1961
+ controller.enqueue({
1962
+ type: "tool-call",
1963
+ toolCallId: active.toolCallId,
1964
+ toolName: active.toolName,
1965
+ input: finalJSON,
1966
+ providerMetadata: active.providerMetadata
1967
+ });
1968
+ hasToolCalls = true;
1969
+ } else if (isCompleteCall) {
1970
+ const toolCallId = generateId3();
1971
+ const toolName = part.functionCall.name;
1972
+ const args2 = typeof part.functionCall.args === "string" ? part.functionCall.args : JSON.stringify((_i = part.functionCall.args) != null ? _i : {});
1648
1973
  controller.enqueue({
1649
1974
  type: "tool-input-start",
1650
- id: toolCall.toolCallId,
1651
- toolName: toolCall.toolName,
1652
- providerMetadata: toolCall.providerMetadata
1975
+ id: toolCallId,
1976
+ toolName,
1977
+ providerMetadata: providerMeta
1653
1978
  });
1654
1979
  controller.enqueue({
1655
1980
  type: "tool-input-delta",
1656
- id: toolCall.toolCallId,
1657
- delta: toolCall.args,
1658
- providerMetadata: toolCall.providerMetadata
1981
+ id: toolCallId,
1982
+ delta: args2,
1983
+ providerMetadata: providerMeta
1659
1984
  });
1660
1985
  controller.enqueue({
1661
1986
  type: "tool-input-end",
1662
- id: toolCall.toolCallId,
1663
- providerMetadata: toolCall.providerMetadata
1987
+ id: toolCallId,
1988
+ providerMetadata: providerMeta
1664
1989
  });
1665
1990
  controller.enqueue({
1666
1991
  type: "tool-call",
1667
- toolCallId: toolCall.toolCallId,
1668
- toolName: toolCall.toolName,
1669
- input: toolCall.args,
1670
- providerMetadata: toolCall.providerMetadata
1992
+ toolCallId,
1993
+ toolName,
1994
+ input: args2,
1995
+ providerMetadata: providerMeta
1671
1996
  });
1672
1997
  hasToolCalls = true;
1673
1998
  }
@@ -1683,12 +2008,12 @@ var GoogleGenerativeAILanguageModel = class {
1683
2008
  };
1684
2009
  providerMetadata = {
1685
2010
  [providerOptionsName]: {
1686
- promptFeedback: (_i = value.promptFeedback) != null ? _i : null,
2011
+ promptFeedback: (_j = value.promptFeedback) != null ? _j : null,
1687
2012
  groundingMetadata: lastGroundingMetadata,
1688
2013
  urlContextMetadata: lastUrlContextMetadata,
1689
- safetyRatings: (_j = candidate.safetyRatings) != null ? _j : null,
2014
+ safetyRatings: (_k = candidate.safetyRatings) != null ? _k : null,
1690
2015
  usageMetadata: usageMetadata != null ? usageMetadata : null,
1691
- finishMessage: (_k = candidate.finishMessage) != null ? _k : null,
2016
+ finishMessage: (_l = candidate.finishMessage) != null ? _l : null,
1692
2017
  serviceTier
1693
2018
  }
1694
2019
  };
@@ -1721,26 +2046,6 @@ var GoogleGenerativeAILanguageModel = class {
1721
2046
  };
1722
2047
  }
1723
2048
  };
1724
- function getToolCallsFromParts({
1725
- parts,
1726
- generateId: generateId3,
1727
- providerOptionsName
1728
- }) {
1729
- const functionCallParts = parts == null ? void 0 : parts.filter(
1730
- (part) => "functionCall" in part
1731
- );
1732
- return functionCallParts == null || functionCallParts.length === 0 ? void 0 : functionCallParts.map((part) => ({
1733
- type: "tool-call",
1734
- toolCallId: generateId3(),
1735
- toolName: part.functionCall.name,
1736
- args: JSON.stringify(part.functionCall.args),
1737
- providerMetadata: part.thoughtSignature ? {
1738
- [providerOptionsName]: {
1739
- thoughtSignature: part.thoughtSignature
1740
- }
1741
- } : void 0
1742
- }));
1743
- }
1744
2049
  function extractSources({
1745
2050
  groundingMetadata,
1746
2051
  generateId: generateId3
@@ -1884,14 +2189,24 @@ var getGroundingMetadataSchema = () => import_v45.z.object({
1884
2189
  import_v45.z.object({})
1885
2190
  ]).nullish()
1886
2191
  });
2192
+ var partialArgSchema = import_v45.z.object({
2193
+ jsonPath: import_v45.z.string(),
2194
+ stringValue: import_v45.z.string().nullish(),
2195
+ numberValue: import_v45.z.number().nullish(),
2196
+ boolValue: import_v45.z.boolean().nullish(),
2197
+ nullValue: import_v45.z.unknown().nullish(),
2198
+ willContinue: import_v45.z.boolean().nullish()
2199
+ });
1887
2200
  var getContentSchema = () => import_v45.z.object({
1888
2201
  parts: import_v45.z.array(
1889
2202
  import_v45.z.union([
1890
2203
  // note: order matters since text can be fully empty
1891
2204
  import_v45.z.object({
1892
2205
  functionCall: import_v45.z.object({
1893
- name: import_v45.z.string(),
1894
- args: import_v45.z.unknown()
2206
+ name: import_v45.z.string().nullish(),
2207
+ args: import_v45.z.unknown().nullish(),
2208
+ partialArgs: import_v45.z.array(partialArgSchema).nullish(),
2209
+ willContinue: import_v45.z.boolean().nullish()
1895
2210
  }),
1896
2211
  thoughtSignature: import_v45.z.string().nullish()
1897
2212
  }),