@ai-sdk/google 4.0.71 → 4.0.73

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,37 @@
1
1
  # @ai-sdk/google
2
2
 
3
+ ## 4.0.73
4
+
5
+ ### Patch Changes
6
+
7
+ - a22b5b2: fix(google): preserve prompt feedback and metadata across streaming chunks
8
+ - 2cd80b3: Keep default Node.js downloads protected by DNS validation and connection pinning when frameworks or instrumentation wrap global fetch before or after the SDK loads.
9
+ - Updated dependencies [91c2128]
10
+ - Updated dependencies [2cd80b3]
11
+ - Updated dependencies [d06bb2a]
12
+ - Updated dependencies [123d71f]
13
+ - Updated dependencies [2fa5e0e]
14
+ - @ai-sdk/provider-utils@5.0.42
15
+ - @ai-sdk/provider@4.0.16
16
+
17
+ ## 4.0.72
18
+
19
+ ### Patch Changes
20
+
21
+ - 4a994ad: feat(google): realtime session options for Gemini 3.8 Live
22
+
23
+ Add `thinkingConfig` (`thinkingLevel`, `thinkingBudget`, `includeThoughts`) and
24
+ `defaultToolBehavior` to `GoogleRealtimeModelOptions`. `thinkingConfig` is merged
25
+ into the Live `setup.generationConfig`. Background-reasoning Live models such as
26
+ `gemini-3.8-live-extended-thinking` require exactly one of `thinkingLevel` or
27
+ `thinkingBudget`, so the provider sends `thinkingLevel: 'low'` on those models
28
+ when neither is set. `defaultToolBehavior` stamps `behavior` on every function
29
+ declaration in the setup.
30
+
31
+ Forward the Live `interactionStatus` and `waitingForInput` server messages as
32
+ custom events so applications can tell when a background-reasoning model is idle,
33
+ since `turnComplete` alone no longer means that.
34
+
3
35
  ## 4.0.71
4
36
 
5
37
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -762,6 +762,41 @@ type GoogleRealtimeModelOptions = {
762
762
  */
763
763
  echoTargetLanguage?: boolean;
764
764
  };
765
+ /**
766
+ * Gemini Live thinking configuration.
767
+ *
768
+ * Supported by Live models with background reasoning (e.g.
769
+ * `gemini-3.8-live-extended-thinking`), which can process multi-step
770
+ * reasoning and function calls while streaming audio responses. Not
771
+ * supported by latency-optimized models (e.g. `gemini-3.8-live`).
772
+ */
773
+ thinkingConfig?: {
774
+ /**
775
+ * Thinking effort level. Background-reasoning Live models require exactly
776
+ * one of `thinkingLevel` or `thinkingBudget`; when neither is set, the
777
+ * provider sends `thinkingLevel: 'low'` on those models.
778
+ */
779
+ thinkingLevel?: 'low' | 'medium' | 'high';
780
+ /**
781
+ * Token budget for background thinking. Mutually exclusive with
782
+ * `thinkingLevel`; setting it suppresses the default level.
783
+ */
784
+ thinkingBudget?: number;
785
+ /**
786
+ * Whether thought summaries should be included in the response.
787
+ */
788
+ includeThoughts?: boolean;
789
+ };
790
+ /**
791
+ * Default `behavior` stamped onto every function declaration in the
792
+ * session setup.
793
+ *
794
+ * Gemini 3.8 Live models default to `NON_BLOCKING` (asynchronous) function
795
+ * calling. Set to `BLOCKING` for synchronous calls on models that support it
796
+ * (e.g. `gemini-3.8-live`); background-reasoning models accept only
797
+ * `NON_BLOCKING`.
798
+ */
799
+ defaultToolBehavior?: 'BLOCKING' | 'NON_BLOCKING';
765
800
  };
766
801
 
767
802
  interface GoogleTranscriptionModelConfig {
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "@ai-sdk/provider-utils";
8
8
 
9
9
  // src/version.ts
10
- var VERSION = true ? "4.0.71" : "0.0.0-test";
10
+ var VERSION = true ? "4.0.73" : "0.0.0-test";
11
11
 
12
12
  // src/google-embedding-model.ts
13
13
  import {
@@ -2122,9 +2122,12 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2122
2122
  raw: void 0
2123
2123
  };
2124
2124
  let usage = void 0;
2125
- let providerMetadata = void 0;
2125
+ let promptFeedback = null;
2126
2126
  let lastGroundingMetadata = null;
2127
2127
  let lastUrlContextMetadata = null;
2128
+ let lastSafetyRatings = null;
2129
+ let lastFinishMessage = null;
2130
+ let confirmedPromptBlockReason;
2128
2131
  const generateId4 = this.config.generateId;
2129
2132
  let hasToolCalls = false;
2130
2133
  let hasEmittedResponseMetadata = false;
@@ -2170,7 +2173,7 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2170
2173
  controller.enqueue({ type: "stream-start", warnings });
2171
2174
  },
2172
2175
  transform(chunk, controller) {
2173
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q;
2176
+ var _a, _b, _c, _d, _e, _f, _g;
2174
2177
  if (options.includeRawChunks) {
2175
2178
  controller.enqueue({ type: "raw", rawValue: chunk.rawValue });
2176
2179
  }
@@ -2190,33 +2193,35 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2190
2193
  if (usageMetadata != null) {
2191
2194
  usage = usageMetadata;
2192
2195
  }
2193
- const candidate = (_a = value.candidates) == null ? void 0 : _a[0];
2194
- if (candidate == null) {
2195
- const promptBlockReason2 = (_b = value.promptFeedback) == null ? void 0 : _b.blockReason;
2196
- if (promptBlockReason2 != null) {
2196
+ if (value.promptFeedback != null && confirmedPromptBlockReason == null) {
2197
+ promptFeedback = value.promptFeedback;
2198
+ if (isConfirmedPromptBlockReason(value.promptFeedback.blockReason)) {
2199
+ confirmedPromptBlockReason = value.promptFeedback.blockReason;
2197
2200
  finishReason = {
2198
2201
  unified: "content-filter",
2199
- raw: promptBlockReason2
2202
+ raw: confirmedPromptBlockReason
2200
2203
  };
2201
- providerMetadata = wrapProviderMetadata({
2202
- promptFeedback: (_c = value.promptFeedback) != null ? _c : null,
2203
- groundingMetadata: lastGroundingMetadata,
2204
- urlContextMetadata: lastUrlContextMetadata,
2205
- safetyRatings: null,
2206
- usageMetadata: usageMetadata != null ? usageMetadata : null,
2207
- finishMessage: null,
2208
- serviceTier: (_d = usage == null ? void 0 : usage.serviceTier) != null ? _d : null
2209
- });
2210
2204
  }
2211
- return;
2212
2205
  }
2213
- const content = candidate.content;
2214
- if (candidate.groundingMetadata != null) {
2215
- lastGroundingMetadata = candidate.groundingMetadata;
2206
+ const candidate = (_a = value.candidates) == null ? void 0 : _a[0];
2207
+ if (candidate != null) {
2208
+ if (candidate.groundingMetadata != null) {
2209
+ lastGroundingMetadata = candidate.groundingMetadata;
2210
+ }
2211
+ if (candidate.urlContextMetadata != null) {
2212
+ lastUrlContextMetadata = candidate.urlContextMetadata;
2213
+ }
2214
+ if (candidate.safetyRatings != null) {
2215
+ lastSafetyRatings = candidate.safetyRatings;
2216
+ }
2217
+ if (candidate.finishMessage != null) {
2218
+ lastFinishMessage = candidate.finishMessage;
2219
+ }
2216
2220
  }
2217
- if (candidate.urlContextMetadata != null) {
2218
- lastUrlContextMetadata = candidate.urlContextMetadata;
2221
+ if (confirmedPromptBlockReason != null || candidate == null) {
2222
+ return;
2219
2223
  }
2224
+ const content = candidate.content;
2220
2225
  const sources = extractSources({
2221
2226
  groundingMetadata: candidate.groundingMetadata,
2222
2227
  generateId: generateId4
@@ -2230,9 +2235,9 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2230
2235
  }
2231
2236
  }
2232
2237
  if (content != null) {
2233
- const parts = (_e = content.parts) != null ? _e : [];
2238
+ const parts = (_b = content.parts) != null ? _b : [];
2234
2239
  for (const part of parts) {
2235
- if ("executableCode" in part && ((_f = part.executableCode) == null ? void 0 : _f.code)) {
2240
+ if ("executableCode" in part && ((_c = part.executableCode) == null ? void 0 : _c.code)) {
2236
2241
  const toolCallId = generateId4();
2237
2242
  lastCodeExecutionToolCallId = toolCallId;
2238
2243
  controller.enqueue({
@@ -2251,7 +2256,7 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2251
2256
  toolName: toolNameMapping.toCustomToolName("code_execution"),
2252
2257
  result: {
2253
2258
  outcome: part.codeExecutionResult.outcome,
2254
- output: (_g = part.codeExecutionResult.output) != null ? _g : ""
2259
+ output: (_d = part.codeExecutionResult.output) != null ? _d : ""
2255
2260
  }
2256
2261
  });
2257
2262
  }
@@ -2351,7 +2356,7 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2351
2356
  type: "tool-call",
2352
2357
  toolCallId,
2353
2358
  toolName: `server:${part.toolCall.toolType}`,
2354
- input: JSON.stringify((_h = part.toolCall.args) != null ? _h : {}),
2359
+ input: JSON.stringify((_e = part.toolCall.args) != null ? _e : {}),
2355
2360
  providerExecuted: true,
2356
2361
  dynamic: true,
2357
2362
  providerMetadata: serverMeta
@@ -2367,7 +2372,7 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2367
2372
  type: "tool-result",
2368
2373
  toolCallId: responseToolCallId,
2369
2374
  toolName: `server:${part.toolResponse.toolType}`,
2370
- result: (_i = part.toolResponse.response) != null ? _i : {},
2375
+ result: (_f = part.toolResponse.response) != null ? _f : {},
2371
2376
  providerMetadata: serverMeta
2372
2377
  });
2373
2378
  lastServerToolCallId = void 0;
@@ -2434,7 +2439,7 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2434
2439
  } else if (isCompleteCall) {
2435
2440
  const toolCallId = part.functionCall.id || generateId4();
2436
2441
  const toolName = part.functionCall.name;
2437
- const args2 = typeof part.functionCall.args === "string" ? part.functionCall.args : JSON.stringify((_j = part.functionCall.args) != null ? _j : {});
2442
+ const args2 = typeof part.functionCall.args === "string" ? part.functionCall.args : JSON.stringify((_g = part.functionCall.args) != null ? _g : {});
2438
2443
  controller.enqueue({
2439
2444
  type: "tool-input-start",
2440
2445
  id: toolCallId,
@@ -2485,29 +2490,18 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2485
2490
  }
2486
2491
  }
2487
2492
  }
2488
- const promptBlockReason = (_k = value.promptFeedback) == null ? void 0 : _k.blockReason;
2489
- const isPromptBlocked = candidate.finishReason == null && promptBlockReason != null;
2490
- const rawFinishReason = (_m = (_l = candidate.finishReason) != null ? _l : promptBlockReason) != null ? _m : void 0;
2491
- if (rawFinishReason != null) {
2493
+ if (candidate.finishReason != null) {
2492
2494
  finishReason = {
2493
- unified: isPromptBlocked ? "content-filter" : mapGoogleFinishReason({
2494
- finishReason: rawFinishReason,
2495
+ unified: mapGoogleFinishReason({
2496
+ finishReason: candidate.finishReason,
2495
2497
  hasToolCalls
2496
2498
  }),
2497
- raw: rawFinishReason
2499
+ raw: candidate.finishReason
2498
2500
  };
2499
- providerMetadata = wrapProviderMetadata({
2500
- promptFeedback: (_n = value.promptFeedback) != null ? _n : null,
2501
- groundingMetadata: lastGroundingMetadata,
2502
- urlContextMetadata: lastUrlContextMetadata,
2503
- safetyRatings: (_o = candidate.safetyRatings) != null ? _o : null,
2504
- usageMetadata: usageMetadata != null ? usageMetadata : null,
2505
- finishMessage: (_p = candidate.finishMessage) != null ? _p : null,
2506
- serviceTier: (_q = usage == null ? void 0 : usage.serviceTier) != null ? _q : null
2507
- });
2508
2501
  }
2509
2502
  },
2510
2503
  flush(controller) {
2504
+ var _a;
2511
2505
  if (currentTextBlockId !== null) {
2512
2506
  controller.enqueue({
2513
2507
  type: "text-end",
@@ -2524,7 +2518,15 @@ var GoogleLanguageModel = class _GoogleLanguageModel {
2524
2518
  type: "finish",
2525
2519
  finishReason,
2526
2520
  usage: convertGoogleUsage(usage),
2527
- providerMetadata
2521
+ providerMetadata: wrapProviderMetadata({
2522
+ promptFeedback,
2523
+ groundingMetadata: lastGroundingMetadata,
2524
+ urlContextMetadata: lastUrlContextMetadata,
2525
+ safetyRatings: lastSafetyRatings,
2526
+ usageMetadata: usage != null ? usage : null,
2527
+ finishMessage: lastFinishMessage,
2528
+ serviceTier: (_a = usage == null ? void 0 : usage.serviceTier) != null ? _a : null
2529
+ })
2528
2530
  });
2529
2531
  }
2530
2532
  })
@@ -2905,6 +2907,9 @@ var chunkSchema = lazySchema5(
2905
2907
  })
2906
2908
  )
2907
2909
  );
2910
+ function isConfirmedPromptBlockReason(blockReason) {
2911
+ return blockReason != null && blockReason !== "" && blockReason !== "BLOCK_REASON_UNSPECIFIED" && blockReason !== "BLOCKED_REASON_UNSPECIFIED";
2912
+ }
2908
2913
 
2909
2914
  // src/google-image-model-options.ts
2910
2915
  import { lazySchema as lazySchema7, zodSchema as zodSchema7 } from "@ai-sdk/provider-utils";
@@ -8057,6 +8062,20 @@ var GoogleRealtimeEventMapper = class {
8057
8062
  raw
8058
8063
  });
8059
8064
  }
8065
+ if (serverContent.interactionStatus != null) {
8066
+ events.push({
8067
+ type: "custom",
8068
+ rawType: "interactionStatus",
8069
+ raw
8070
+ });
8071
+ }
8072
+ if (serverContent.waitingForInput) {
8073
+ events.push({
8074
+ type: "custom",
8075
+ rawType: "waitingForInput",
8076
+ raw
8077
+ });
8078
+ }
8060
8079
  if (serverContent.turnComplete) {
8061
8080
  if (this.hasAudio) {
8062
8081
  events.push({
@@ -8167,10 +8186,18 @@ async function serializeFunctionCallOutput(item) {
8167
8186
  }
8168
8187
  };
8169
8188
  }
8189
+ function isThinkingLiveModel(modelId) {
8190
+ var _a, _b;
8191
+ const modelName = (_b = (_a = modelId.split("/").at(-1)) == null ? void 0 : _a.toLowerCase()) != null ? _b : "";
8192
+ return /^gemini-\d+\.\d+-live\b.*thinking/.test(modelName);
8193
+ }
8170
8194
  function buildGoogleSessionConfig(config, modelId) {
8195
+ var _a, _b;
8171
8196
  const setup = {
8172
8197
  model: getModelPath(modelId)
8173
8198
  };
8199
+ const { google: google2, ...restProviderOptions } = (_a = config == null ? void 0 : config.providerOptions) != null ? _a : {};
8200
+ const googleOptions = isRecord(google2) ? google2 : void 0;
8174
8201
  const generationConfig = {};
8175
8202
  if ((config == null ? void 0 : config.outputModalities) != null) {
8176
8203
  generationConfig.responseModalities = config.outputModalities.map(
@@ -8200,7 +8227,8 @@ function buildGoogleSessionConfig(config, modelId) {
8200
8227
  functionDeclarations: config.tools.map((tool) => ({
8201
8228
  name: tool.name,
8202
8229
  description: tool.description,
8203
- parametersJsonSchema: tool.parameters
8230
+ parametersJsonSchema: tool.parameters,
8231
+ ...(googleOptions == null ? void 0 : googleOptions.defaultToolBehavior) != null ? { behavior: googleOptions.defaultToolBehavior } : {}
8204
8232
  }))
8205
8233
  }
8206
8234
  ];
@@ -8211,12 +8239,17 @@ function buildGoogleSessionConfig(config, modelId) {
8211
8239
  if ((config == null ? void 0 : config.outputAudioTranscription) != null) {
8212
8240
  setup.outputAudioTranscription = {};
8213
8241
  }
8242
+ const thinkingConfig = (_b = googleOptions == null ? void 0 : googleOptions.thinkingConfig) != null ? _b : isThinkingLiveModel(modelId) ? { thinkingLevel: "low" } : void 0;
8243
+ const applyThinkingConfig = () => {
8244
+ if (thinkingConfig == null) return;
8245
+ const target = isRecord(setup.generationConfig) ? setup.generationConfig : generationConfig;
8246
+ setup.generationConfig = { ...target, thinkingConfig };
8247
+ };
8214
8248
  if ((config == null ? void 0 : config.providerOptions) == null) {
8249
+ applyThinkingConfig();
8215
8250
  return setup;
8216
8251
  }
8217
- const { google: google2, ...providerOptions } = config.providerOptions;
8218
- Object.assign(setup, providerOptions);
8219
- const googleOptions = isRecord(google2) ? google2 : void 0;
8252
+ Object.assign(setup, restProviderOptions);
8220
8253
  if ((googleOptions == null ? void 0 : googleOptions.translationConfig) != null) {
8221
8254
  const target = isRecord(setup.generationConfig) ? setup.generationConfig : generationConfig;
8222
8255
  setup.generationConfig = {
@@ -8224,6 +8257,7 @@ function buildGoogleSessionConfig(config, modelId) {
8224
8257
  translationConfig: googleOptions.translationConfig
8225
8258
  };
8226
8259
  }
8260
+ applyThinkingConfig();
8227
8261
  return setup;
8228
8262
  }
8229
8263