@ai-sdk/google 2.0.90 → 2.0.94

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.
@@ -16,6 +16,10 @@ import { z as z3 } from "zod/v4";
16
16
  import {
17
17
  UnsupportedFunctionalityError
18
18
  } from "@ai-sdk/provider";
19
+ var recursiveReferenceFunctionalityPrefix = "recursive JSON Schema reference:";
20
+ function isRecursiveJSONSchemaReferenceError(error) {
21
+ return UnsupportedFunctionalityError.isInstance(error) && error.functionality.startsWith(recursiveReferenceFunctionalityPrefix);
22
+ }
19
23
  function convertJSONSchemaToOpenAPISchema(jsonSchema, isRoot = true) {
20
24
  const rootSchema = typeof jsonSchema === "object" ? jsonSchema : void 0;
21
25
  return convertJSONSchemaDefinition(jsonSchema, isRoot, {
@@ -66,9 +70,6 @@ function convertJSONSchemaDefinition(jsonSchema, isRoot, referenceContext) {
66
70
  if (description) result.description = description;
67
71
  if (required) result.required = required;
68
72
  if (format) result.format = format;
69
- if (constValue !== void 0) {
70
- result.enum = [constValue];
71
- }
72
73
  if (type) {
73
74
  if (Array.isArray(type)) {
74
75
  const hasNull = type.includes("null");
@@ -85,8 +86,9 @@ function convertJSONSchemaDefinition(jsonSchema, isRoot, referenceContext) {
85
86
  result.type = type;
86
87
  }
87
88
  }
88
- if (enumValues !== void 0) {
89
- result.enum = enumValues;
89
+ const values = enumValues != null ? enumValues : constValue !== void 0 ? [constValue] : void 0;
90
+ if (values !== void 0) {
91
+ addEnumToSchema({ values, type, result });
90
92
  }
91
93
  if (properties != null) {
92
94
  result.properties = Object.entries(properties).reduce(
@@ -146,6 +148,68 @@ function convertJSONSchemaDefinition(jsonSchema, isRoot, referenceContext) {
146
148
  }
147
149
  return result;
148
150
  }
151
+ function addEnumToSchema({
152
+ values,
153
+ type,
154
+ result
155
+ }) {
156
+ const nullable = Array.isArray(type) && type.includes("null") || type === void 0 && values.includes(null);
157
+ const enumValues = nullable ? values.filter((value) => value !== null) : values;
158
+ if (values.length > 0 && values.every((value) => value === null)) {
159
+ const typeAllowsNull = type === void 0 || type === "null" || Array.isArray(type) && type.includes("null");
160
+ if (typeAllowsNull) {
161
+ result.type = "null";
162
+ if (Array.isArray(type)) {
163
+ delete result.anyOf;
164
+ }
165
+ return;
166
+ }
167
+ }
168
+ const enumType = getEnumType({ values: enumValues, type });
169
+ if (enumType === void 0) {
170
+ throw new UnsupportedFunctionalityError({
171
+ functionality: "JSON Schema enum with mixed or unsupported values",
172
+ message: "Google does not support this JSON Schema enum. Enum values must share one supported primitive type and match the schema type."
173
+ });
174
+ }
175
+ result.type = enumType;
176
+ if (Array.isArray(type)) {
177
+ delete result.anyOf;
178
+ }
179
+ if (nullable) {
180
+ result.nullable = true;
181
+ }
182
+ if (enumType === "string") {
183
+ result.enum = enumValues;
184
+ } else {
185
+ result.format = "enum";
186
+ result.enum = enumValues.map(String);
187
+ }
188
+ }
189
+ function getEnumType({
190
+ values,
191
+ type
192
+ }) {
193
+ if (values.length === 0) {
194
+ return void 0;
195
+ }
196
+ const typeAllows = (enumType) => type === void 0 || type === enumType || Array.isArray(type) && type.includes(enumType);
197
+ if (typeAllows("string") && values.every((value) => typeof value === "string")) {
198
+ return "string";
199
+ }
200
+ if ((typeAllows("number") || typeAllows("integer")) && values.every((value) => typeof value === "number" && Number.isFinite(value))) {
201
+ if (typeAllows("number")) {
202
+ return "number";
203
+ }
204
+ if (values.every((value) => Number.isInteger(value))) {
205
+ return "integer";
206
+ }
207
+ }
208
+ if (typeAllows("boolean") && values.every((value) => typeof value === "boolean")) {
209
+ return "boolean";
210
+ }
211
+ return void 0;
212
+ }
149
213
  function convertJSONSchemaReference({
150
214
  jsonSchema,
151
215
  reference,
@@ -158,7 +222,7 @@ function convertJSONSchemaReference({
158
222
  );
159
223
  if (referenceContext.resolvingReferences.has(referenceKey)) {
160
224
  throw new UnsupportedFunctionalityError({
161
- functionality: `recursive JSON Schema reference: ${reference}`,
225
+ functionality: `${recursiveReferenceFunctionalityPrefix} ${reference}`,
162
226
  message: "Google schema conversion does not support recursive JSON Schema references."
163
227
  });
164
228
  }
@@ -675,7 +739,6 @@ function prepareTools({
675
739
  modelId,
676
740
  isVertexProvider = false
677
741
  }) {
678
- var _a, _b;
679
742
  tools = (tools == null ? void 0 : tools.length) ? tools : void 0;
680
743
  const toolWarnings = [];
681
744
  const { supportsGemini2Tools, supportsFileSearch, usesGemini3Features } = getGoogleModelCapabilities(modelId);
@@ -796,11 +859,7 @@ function prepareTools({
796
859
  const functionDeclarations2 = [];
797
860
  for (const tool of tools) {
798
861
  if (tool.type === "function") {
799
- functionDeclarations2.push({
800
- name: tool.name,
801
- description: (_a = tool.description) != null ? _a : "",
802
- parameters: convertJSONSchemaToOpenAPISchema(tool.inputSchema)
803
- });
862
+ functionDeclarations2.push(prepareFunctionDeclaration(tool));
804
863
  }
805
864
  }
806
865
  const combinedToolConfig = {
@@ -844,11 +903,7 @@ function prepareTools({
844
903
  for (const tool of tools) {
845
904
  switch (tool.type) {
846
905
  case "function":
847
- functionDeclarations.push({
848
- name: tool.name,
849
- description: (_b = tool.description) != null ? _b : "",
850
- parameters: convertJSONSchemaToOpenAPISchema(tool.inputSchema)
851
- });
906
+ functionDeclarations.push(prepareFunctionDeclaration(tool));
852
907
  if (tool.strict === true) {
853
908
  hasStrictTools = true;
854
909
  }
@@ -912,6 +967,27 @@ function prepareTools({
912
967
  }
913
968
  }
914
969
  }
970
+ function prepareFunctionDeclaration(tool) {
971
+ var _a;
972
+ const declaration = {
973
+ name: tool.name,
974
+ description: (_a = tool.description) != null ? _a : ""
975
+ };
976
+ try {
977
+ return {
978
+ ...declaration,
979
+ parameters: convertJSONSchemaToOpenAPISchema(tool.inputSchema)
980
+ };
981
+ } catch (error) {
982
+ if (!isRecursiveJSONSchemaReferenceError(error)) {
983
+ throw error;
984
+ }
985
+ return {
986
+ ...declaration,
987
+ parametersJsonSchema: tool.inputSchema
988
+ };
989
+ }
990
+ }
915
991
 
916
992
  // src/map-google-generative-ai-finish-reason.ts
917
993
  function mapGoogleGenerativeAIFinishReason({
@@ -947,6 +1023,7 @@ var configurableSafetySettingCategories = [
947
1023
  "HARM_CATEGORY_HARASSMENT",
948
1024
  "HARM_CATEGORY_SEXUALLY_EXPLICIT"
949
1025
  ];
1026
+ var gemini25ModelPattern2 = /(^|\/)gemini-2\.5(?:[.-]|$)/i;
950
1027
  var GoogleGenerativeAILanguageModel = class {
951
1028
  constructor(modelId, config) {
952
1029
  this.specificationVersion = "v2";
@@ -1024,6 +1101,19 @@ var GoogleGenerativeAILanguageModel = class {
1024
1101
  threshold: safetyThreshold
1025
1102
  })) : void 0;
1026
1103
  const isGemmaModel = this.modelId.toLowerCase().startsWith("gemma-");
1104
+ const isGemini25DeveloperApiModel = !isVertexProvider && gemini25ModelPattern2.test(this.modelId);
1105
+ if (isGemini25DeveloperApiModel && frequencyPenalty != null) {
1106
+ warnings.push({
1107
+ type: "unsupported-setting",
1108
+ setting: "frequencyPenalty"
1109
+ });
1110
+ }
1111
+ if (isGemini25DeveloperApiModel && presencePenalty != null) {
1112
+ warnings.push({
1113
+ type: "unsupported-setting",
1114
+ setting: "presencePenalty"
1115
+ });
1116
+ }
1027
1117
  const { usesGemini3Features } = getGoogleModelCapabilities(this.modelId);
1028
1118
  const { contents, systemInstruction } = convertToGoogleGenerativeAIMessages(
1029
1119
  prompt,
@@ -1051,8 +1141,8 @@ var GoogleGenerativeAILanguageModel = class {
1051
1141
  temperature,
1052
1142
  topK,
1053
1143
  topP,
1054
- frequencyPenalty,
1055
- presencePenalty,
1144
+ frequencyPenalty: isGemini25DeveloperApiModel ? void 0 : frequencyPenalty,
1145
+ presencePenalty: isGemini25DeveloperApiModel ? void 0 : presencePenalty,
1056
1146
  stopSequences,
1057
1147
  seed,
1058
1148
  // response format:
@@ -1088,7 +1178,7 @@ var GoogleGenerativeAILanguageModel = class {
1088
1178
  };
1089
1179
  }
1090
1180
  async doGenerate(options) {
1091
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1181
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
1092
1182
  const { args, warnings } = await this.getArgs(options);
1093
1183
  const body = JSON.stringify(args);
1094
1184
  const mergedHeaders = combineHeaders(
@@ -1110,13 +1200,15 @@ var GoogleGenerativeAILanguageModel = class {
1110
1200
  abortSignal: options.abortSignal,
1111
1201
  fetch: this.config.fetch
1112
1202
  });
1113
- const candidate = response.candidates[0];
1203
+ const candidate = (_a = response.candidates) == null ? void 0 : _a[0];
1204
+ const promptBlockReason = (_b = response.promptFeedback) == null ? void 0 : _b.blockReason;
1205
+ const isPromptBlocked = (candidate == null ? void 0 : candidate.finishReason) == null && promptBlockReason != null;
1114
1206
  const content = [];
1115
- const parts = (_b = (_a = candidate.content) == null ? void 0 : _a.parts) != null ? _b : [];
1207
+ const parts = (_d = (_c = candidate == null ? void 0 : candidate.content) == null ? void 0 : _c.parts) != null ? _d : [];
1116
1208
  const usageMetadata = response.usageMetadata;
1117
1209
  let lastCodeExecutionToolCallId;
1118
1210
  for (const part of parts) {
1119
- if ("executableCode" in part && ((_c = part.executableCode) == null ? void 0 : _c.code)) {
1211
+ if ("executableCode" in part && ((_e = part.executableCode) == null ? void 0 : _e.code)) {
1120
1212
  const toolCallId = this.config.generateId();
1121
1213
  lastCodeExecutionToolCallId = toolCallId;
1122
1214
  content.push({
@@ -1157,7 +1249,7 @@ var GoogleGenerativeAILanguageModel = class {
1157
1249
  } else if ("functionCall" in part) {
1158
1250
  content.push({
1159
1251
  type: "tool-call",
1160
- toolCallId: (_d = part.functionCall.id) != null ? _d : this.config.generateId(),
1252
+ toolCallId: (_f = part.functionCall.id) != null ? _f : this.config.generateId(),
1161
1253
  toolName: part.functionCall.name,
1162
1254
  input: JSON.stringify(part.functionCall.args),
1163
1255
  providerMetadata: part.thoughtSignature ? { google: { thoughtSignature: part.thoughtSignature } } : void 0
@@ -1170,34 +1262,34 @@ var GoogleGenerativeAILanguageModel = class {
1170
1262
  });
1171
1263
  }
1172
1264
  }
1173
- const sources = (_e = extractSources({
1174
- groundingMetadata: candidate.groundingMetadata,
1265
+ const sources = (_g = extractSources({
1266
+ groundingMetadata: candidate == null ? void 0 : candidate.groundingMetadata,
1175
1267
  generateId: this.config.generateId
1176
- })) != null ? _e : [];
1268
+ })) != null ? _g : [];
1177
1269
  for (const source of sources) {
1178
1270
  content.push(source);
1179
1271
  }
1180
1272
  return {
1181
1273
  content,
1182
- finishReason: mapGoogleGenerativeAIFinishReason({
1183
- finishReason: candidate.finishReason,
1274
+ finishReason: isPromptBlocked ? "content-filter" : mapGoogleGenerativeAIFinishReason({
1275
+ finishReason: candidate == null ? void 0 : candidate.finishReason,
1184
1276
  hasToolCalls: content.some((part) => part.type === "tool-call")
1185
1277
  }),
1186
1278
  usage: {
1187
- inputTokens: (_f = usageMetadata == null ? void 0 : usageMetadata.promptTokenCount) != null ? _f : void 0,
1188
- outputTokens: (_g = usageMetadata == null ? void 0 : usageMetadata.candidatesTokenCount) != null ? _g : void 0,
1189
- totalTokens: (_h = usageMetadata == null ? void 0 : usageMetadata.totalTokenCount) != null ? _h : void 0,
1190
- reasoningTokens: (_i = usageMetadata == null ? void 0 : usageMetadata.thoughtsTokenCount) != null ? _i : void 0,
1191
- cachedInputTokens: (_j = usageMetadata == null ? void 0 : usageMetadata.cachedContentTokenCount) != null ? _j : void 0
1279
+ inputTokens: (_h = usageMetadata == null ? void 0 : usageMetadata.promptTokenCount) != null ? _h : void 0,
1280
+ outputTokens: (_i = usageMetadata == null ? void 0 : usageMetadata.candidatesTokenCount) != null ? _i : void 0,
1281
+ totalTokens: (_j = usageMetadata == null ? void 0 : usageMetadata.totalTokenCount) != null ? _j : void 0,
1282
+ reasoningTokens: (_k = usageMetadata == null ? void 0 : usageMetadata.thoughtsTokenCount) != null ? _k : void 0,
1283
+ cachedInputTokens: (_l = usageMetadata == null ? void 0 : usageMetadata.cachedContentTokenCount) != null ? _l : void 0
1192
1284
  },
1193
1285
  warnings,
1194
1286
  providerMetadata: {
1195
1287
  google: {
1196
- promptFeedback: (_k = response.promptFeedback) != null ? _k : null,
1197
- groundingMetadata: (_l = candidate.groundingMetadata) != null ? _l : null,
1198
- urlContextMetadata: (_m = candidate.urlContextMetadata) != null ? _m : null,
1199
- safetyRatings: (_n = candidate.safetyRatings) != null ? _n : null,
1200
- serviceTier: (_o = response.serviceTier) != null ? _o : null,
1288
+ promptFeedback: (_m = response.promptFeedback) != null ? _m : null,
1289
+ groundingMetadata: (_n = candidate == null ? void 0 : candidate.groundingMetadata) != null ? _n : null,
1290
+ urlContextMetadata: (_o = candidate == null ? void 0 : candidate.urlContextMetadata) != null ? _o : null,
1291
+ safetyRatings: (_p = candidate == null ? void 0 : candidate.safetyRatings) != null ? _p : null,
1292
+ serviceTier: (_q = response.serviceTier) != null ? _q : null,
1201
1293
  usageMetadata: usageMetadata != null ? usageMetadata : null
1202
1294
  }
1203
1295
  },
@@ -1251,7 +1343,7 @@ var GoogleGenerativeAILanguageModel = class {
1251
1343
  controller.enqueue({ type: "stream-start", warnings });
1252
1344
  },
1253
1345
  transform(chunk, controller) {
1254
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1346
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
1255
1347
  if (options.includeRawChunks) {
1256
1348
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
1257
1349
  }
@@ -1273,6 +1365,22 @@ var GoogleGenerativeAILanguageModel = class {
1273
1365
  }
1274
1366
  const candidate = (_f = value.candidates) == null ? void 0 : _f[0];
1275
1367
  if (candidate == null) {
1368
+ const promptBlockReason2 = (_g = value.promptFeedback) == null ? void 0 : _g.blockReason;
1369
+ if (promptBlockReason2 != null) {
1370
+ finishReason = "content-filter";
1371
+ providerMetadata = {
1372
+ google: {
1373
+ promptFeedback: (_h = value.promptFeedback) != null ? _h : null,
1374
+ groundingMetadata: lastGroundingMetadata,
1375
+ urlContextMetadata: lastUrlContextMetadata,
1376
+ safetyRatings: null,
1377
+ serviceTier
1378
+ }
1379
+ };
1380
+ if (usageMetadata != null) {
1381
+ providerMetadata.google.usageMetadata = usageMetadata;
1382
+ }
1383
+ }
1276
1384
  return;
1277
1385
  }
1278
1386
  const content = candidate.content;
@@ -1295,9 +1403,9 @@ var GoogleGenerativeAILanguageModel = class {
1295
1403
  }
1296
1404
  }
1297
1405
  if (content != null) {
1298
- const parts = (_g = content.parts) != null ? _g : [];
1406
+ const parts = (_i = content.parts) != null ? _i : [];
1299
1407
  for (const part of parts) {
1300
- if ("executableCode" in part && ((_h = part.executableCode) == null ? void 0 : _h.code)) {
1408
+ if ("executableCode" in part && ((_j = part.executableCode) == null ? void 0 : _j.code)) {
1301
1409
  const toolCallId = generateId2();
1302
1410
  lastCodeExecutionToolCallId = toolCallId;
1303
1411
  controller.enqueue({
@@ -1424,17 +1532,20 @@ var GoogleGenerativeAILanguageModel = class {
1424
1532
  }
1425
1533
  }
1426
1534
  }
1427
- if (candidate.finishReason != null) {
1428
- finishReason = mapGoogleGenerativeAIFinishReason({
1429
- finishReason: candidate.finishReason,
1535
+ const promptBlockReason = (_k = value.promptFeedback) == null ? void 0 : _k.blockReason;
1536
+ const isPromptBlocked = candidate.finishReason == null && promptBlockReason != null;
1537
+ const rawFinishReason = (_m = (_l = candidate.finishReason) != null ? _l : promptBlockReason) != null ? _m : void 0;
1538
+ if (rawFinishReason != null) {
1539
+ finishReason = isPromptBlocked ? "content-filter" : mapGoogleGenerativeAIFinishReason({
1540
+ finishReason: rawFinishReason,
1430
1541
  hasToolCalls
1431
1542
  });
1432
1543
  providerMetadata = {
1433
1544
  google: {
1434
- promptFeedback: (_i = value.promptFeedback) != null ? _i : null,
1545
+ promptFeedback: (_n = value.promptFeedback) != null ? _n : null,
1435
1546
  groundingMetadata: lastGroundingMetadata,
1436
1547
  urlContextMetadata: lastUrlContextMetadata,
1437
- safetyRatings: (_j = candidate.safetyRatings) != null ? _j : null,
1548
+ safetyRatings: (_o = candidate.safetyRatings) != null ? _o : null,
1438
1549
  serviceTier
1439
1550
  }
1440
1551
  };
@@ -1710,7 +1821,7 @@ var responseSchema = lazySchema3(
1710
1821
  groundingMetadata: getGroundingMetadataSchema().nullish(),
1711
1822
  urlContextMetadata: getUrlContextMetadataSchema().nullish()
1712
1823
  })
1713
- ),
1824
+ ).nullish(),
1714
1825
  usageMetadata: usageSchema.nullish(),
1715
1826
  promptFeedback: z3.object({
1716
1827
  blockReason: z3.string().nullish(),