@ai-sdk/google 3.0.60 → 3.0.62

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