@google/genai 1.39.0 → 1.41.0

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/dist/genai.d.ts CHANGED
@@ -763,6 +763,7 @@ declare class BaseGeminiNextGenAPIClient {
763
763
  timeout: number;
764
764
  }>;
765
765
  private buildHeaders;
766
+ private _makeAbort;
766
767
  private buildBody;
767
768
  static DEFAULT_TIMEOUT: number;
768
769
  }
@@ -777,7 +778,7 @@ declare class BaseInteractions extends APIResource {
777
778
  * const interaction = await client.interactions.create({
778
779
  * api_version: 'api_version',
779
780
  * input: 'string',
780
- * model: 'gemini-2.5-pro',
781
+ * model: 'gemini-2.5-flash',
781
782
  * });
782
783
  * ```
783
784
  */
@@ -1827,11 +1828,11 @@ declare namespace ContentDelta {
1827
1828
  /**
1828
1829
  * Tool call result delta.
1829
1830
  */
1830
- result?: FunctionResultDelta.Items | string;
1831
+ result?: FunctionResultDelta.Items | unknown | string;
1831
1832
  }
1832
1833
  namespace FunctionResultDelta {
1833
1834
  interface Items {
1834
- items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent | unknown>;
1835
+ items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent>;
1835
1836
  }
1836
1837
  }
1837
1838
  interface CodeExecutionCallDelta {
@@ -1919,12 +1920,12 @@ declare namespace ContentDelta {
1919
1920
  /**
1920
1921
  * Tool call result delta.
1921
1922
  */
1922
- result?: MCPServerToolResultDelta.Items | string;
1923
+ result?: MCPServerToolResultDelta.Items | unknown | string;
1923
1924
  server_name?: string;
1924
1925
  }
1925
1926
  namespace MCPServerToolResultDelta {
1926
1927
  interface Items {
1927
- items?: Array<string | InteractionsAPI.ImageContent | unknown>;
1928
+ items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent>;
1928
1929
  }
1929
1930
  }
1930
1931
  interface FileSearchCallDelta {
@@ -2484,6 +2485,8 @@ export declare interface CreateTuningJobConfig {
2484
2485
  sftLossWeightMultiplier?: number;
2485
2486
  /** The Google Cloud Storage location where the tuning job outputs are written. */
2486
2487
  outputUri?: string;
2488
+ /** The encryption spec of the tuning job. Customer-managed encryption key options for a TuningJob. If this is set, then all resources created by the TuningJob will be encrypted with provided encryption key. */
2489
+ encryptionSpec?: EncryptionSpec;
2487
2490
  }
2488
2491
 
2489
2492
  /** Fine-tuning job creation parameters - optional fields. */
@@ -3962,7 +3965,7 @@ declare interface FunctionResultContent {
3962
3965
 
3963
3966
  declare namespace FunctionResultContent {
3964
3967
  interface Items {
3965
- items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent | unknown>;
3968
+ items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent>;
3966
3969
  }
3967
3970
  }
3968
3971
 
@@ -5429,6 +5432,8 @@ export declare interface HttpOptions {
5429
5432
  - VertexAI backend API docs: https://cloud.google.com/vertex-ai/docs/reference/rest
5430
5433
  - GeminiAPI backend API docs: https://ai.google.dev/api/rest */
5431
5434
  extraBody?: Record<string, unknown>;
5435
+ /** HTTP retry options for the request. */
5436
+ retryOptions?: HttpRetryOptions;
5432
5437
  }
5433
5438
 
5434
5439
  /**
@@ -5492,6 +5497,13 @@ export declare class HttpResponse {
5492
5497
  json(): Promise<unknown>;
5493
5498
  }
5494
5499
 
5500
+ /** HTTP retry options to be used in each of the requests. */
5501
+ export declare interface HttpRetryOptions {
5502
+ /** Maximum number of attempts, including the original request.
5503
+ If 0 or 1, it means no retries. If not specified, default to 5. */
5504
+ attempts?: number;
5505
+ }
5506
+
5495
5507
  /** An image. */
5496
5508
  declare interface Image_2 {
5497
5509
  /** The Cloud Storage URI of the image. ``Image`` can contain a value
@@ -5704,7 +5716,7 @@ declare interface Interaction {
5704
5716
  /**
5705
5717
  * Output only. The status of the interaction.
5706
5718
  */
5707
- status: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
5719
+ status: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled' | 'incomplete';
5708
5720
  /**
5709
5721
  * The name of the `Agent` used for generating the interaction.
5710
5722
  */
@@ -5913,7 +5925,7 @@ declare interface InteractionStatusUpdate {
5913
5925
  event_id?: string;
5914
5926
  event_type?: 'interaction.status_update';
5915
5927
  interaction_id?: string;
5916
- status?: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled';
5928
+ status?: 'in_progress' | 'requires_action' | 'completed' | 'failed' | 'cancelled' | 'incomplete';
5917
5929
  }
5918
5930
 
5919
5931
  /** Parameters for the private _Register method. */
@@ -7133,7 +7145,7 @@ declare interface MCPServerToolResultContent {
7133
7145
 
7134
7146
  declare namespace MCPServerToolResultContent {
7135
7147
  interface Items {
7136
- items?: Array<string | InteractionsAPI.ImageContent | unknown>;
7148
+ items?: Array<InteractionsAPI.TextContent | InteractionsAPI.ImageContent>;
7137
7149
  }
7138
7150
  }
7139
7151
 
@@ -7291,7 +7303,7 @@ export declare interface Model {
7291
7303
  /**
7292
7304
  * The model that will complete your prompt.\n\nSee [models](https://ai.google.dev/gemini-api/docs/models) for additional details.
7293
7305
  */
7294
- declare type Model_2 = 'gemini-2.5-pro' | 'gemini-2.5-flash' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-preview-native-audio-dialog' | 'gemini-2.5-flash-image-preview' | 'gemini-2.5-pro-preview-tts' | 'gemini-3-pro-preview' | 'gemini-3-flash-preview' | (string & {});
7306
+ declare type Model_2 = 'gemini-2.5-flash' | 'gemini-2.5-flash-image' | 'gemini-2.5-flash-lite' | 'gemini-2.5-flash-lite-preview-09-2025' | 'gemini-2.5-flash-native-audio-preview-12-2025' | 'gemini-2.5-flash-preview-09-2025' | 'gemini-2.5-flash-preview-tts' | 'gemini-2.5-pro' | 'gemini-2.5-pro-preview-tts' | 'gemini-3-flash-preview' | 'gemini-3-pro-image-preview' | 'gemini-3-pro-preview' | (string & {});
7295
7307
 
7296
7308
  /** Configuration for Model Armor integrations of prompt and responses. This data type is not supported in Gemini API. */
7297
7309
  export declare interface ModelArmorConfig {
@@ -10047,6 +10059,7 @@ declare namespace types {
10047
10059
  VideoMetadata,
10048
10060
  Part,
10049
10061
  Content,
10062
+ HttpRetryOptions,
10050
10063
  HttpOptions,
10051
10064
  Schema,
10052
10065
  ModelSelectionConfig,
package/dist/index.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var pRetry = require('p-retry');
4
+
3
5
  /**
4
6
  * @license
5
7
  * Copyright 2025 Google LLC
@@ -6931,10 +6933,22 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
6931
6933
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
6932
6934
  const USER_AGENT_HEADER = 'User-Agent';
6933
6935
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
6934
- const SDK_VERSION = '1.39.0'; // x-release-please-version
6936
+ const SDK_VERSION = '1.41.0'; // x-release-please-version
6935
6937
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
6936
6938
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
6937
6939
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
6940
+ // Default retry options.
6941
+ // The config is based on https://cloud.google.com/storage/docs/retry-strategy.
6942
+ const DEFAULT_RETRY_ATTEMPTS = 5; // Including the initial call
6943
+ // LINT.IfChange
6944
+ const DEFAULT_RETRY_HTTP_STATUS_CODES = [
6945
+ 408, // Request timeout
6946
+ 429, // Too many requests
6947
+ 500, // Internal server error
6948
+ 502, // Bad gateway
6949
+ 503, // Service unavailable
6950
+ 504, // Gateway timeout
6951
+ ];
6938
6952
  /**
6939
6953
  * The ApiClient class is used to send requests to the Gemini API or Vertex AI
6940
6954
  * endpoints.
@@ -7319,8 +7333,25 @@ class ApiClient {
7319
7333
  });
7320
7334
  }
7321
7335
  async apiCall(url, requestInit) {
7322
- return fetch(url, requestInit).catch((e) => {
7323
- throw new Error(`exception ${e} sending request`);
7336
+ var _a;
7337
+ if (!this.clientOptions.httpOptions ||
7338
+ !this.clientOptions.httpOptions.retryOptions) {
7339
+ return fetch(url, requestInit);
7340
+ }
7341
+ const retryOptions = this.clientOptions.httpOptions.retryOptions;
7342
+ const runFetch = async () => {
7343
+ const response = await fetch(url, requestInit);
7344
+ if (response.ok) {
7345
+ return response;
7346
+ }
7347
+ if (DEFAULT_RETRY_HTTP_STATUS_CODES.includes(response.status)) {
7348
+ throw new Error(`Retryable HTTP Error: ${response.statusText}`);
7349
+ }
7350
+ throw new pRetry.AbortError(`Non-retryable exception ${response.statusText} sending request`);
7351
+ };
7352
+ return pRetry(runFetch, {
7353
+ // Retry attempts is one less than the number of total attempts.
7354
+ retries: ((_a = retryOptions.attempts) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_ATTEMPTS) - 1,
7324
7355
  });
7325
7356
  }
7326
7357
  getDefaultHeaders() {
@@ -10017,6 +10048,11 @@ async function defaultParseResponse(client, props) {
10017
10048
  const mediaType = (_a = contentType === null || contentType === void 0 ? void 0 : contentType.split(';')[0]) === null || _a === void 0 ? void 0 : _a.trim();
10018
10049
  const isJSON = (mediaType === null || mediaType === void 0 ? void 0 : mediaType.includes('application/json')) || (mediaType === null || mediaType === void 0 ? void 0 : mediaType.endsWith('+json'));
10019
10050
  if (isJSON) {
10051
+ const contentLength = response.headers.get('content-length');
10052
+ if (contentLength === '0') {
10053
+ // if there is no content we can't do anything
10054
+ return undefined;
10055
+ }
10020
10056
  const json = await response.json();
10021
10057
  return json;
10022
10058
  }
@@ -10476,9 +10512,10 @@ class BaseGeminiNextGenAPIClient {
10476
10512
  }
10477
10513
  async fetchWithTimeout(url, init, ms, controller) {
10478
10514
  const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
10515
+ const abort = this._makeAbort(controller);
10479
10516
  if (signal)
10480
- signal.addEventListener('abort', () => controller.abort());
10481
- const timeout = setTimeout(() => controller.abort(), ms);
10517
+ signal.addEventListener('abort', abort, { once: true });
10518
+ const timeout = setTimeout(abort, ms);
10482
10519
  const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
10483
10520
  (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
10484
10521
  const fetchOptions = Object.assign(Object.assign(Object.assign({ signal: controller.signal }, (isReadableBody ? { duplex: 'half' } : {})), { method: 'GET' }), options);
@@ -10591,6 +10628,11 @@ class BaseGeminiNextGenAPIClient {
10591
10628
  this.validateHeaders(headers);
10592
10629
  return headers.values;
10593
10630
  }
10631
+ _makeAbort(controller) {
10632
+ // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
10633
+ // would capture all request options, and cause a memory leak.
10634
+ return () => controller.abort();
10635
+ }
10594
10636
  buildBody({ options: { body, headers: rawHeaders } }) {
10595
10637
  if (!body) {
10596
10638
  return { bodyHeaders: undefined, body: undefined };
@@ -18245,6 +18287,9 @@ function createTuningJobConfigToMldev(fromObject, parentObject, _rootObject) {
18245
18287
  if (getValueByPath(fromObject, ['outputUri']) !== undefined) {
18246
18288
  throw new Error('outputUri parameter is not supported in Gemini API.');
18247
18289
  }
18290
+ if (getValueByPath(fromObject, ['encryptionSpec']) !== undefined) {
18291
+ throw new Error('encryptionSpec parameter is not supported in Gemini API.');
18292
+ }
18248
18293
  return toObject;
18249
18294
  }
18250
18295
  function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
@@ -18480,6 +18525,12 @@ function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
18480
18525
  if (parentObject !== undefined && fromOutputUri != null) {
18481
18526
  setValueByPath(parentObject, ['outputUri'], fromOutputUri);
18482
18527
  }
18528
+ const fromEncryptionSpec = getValueByPath(fromObject, [
18529
+ 'encryptionSpec',
18530
+ ]);
18531
+ if (parentObject !== undefined && fromEncryptionSpec != null) {
18532
+ setValueByPath(parentObject, ['encryptionSpec'], fromEncryptionSpec);
18533
+ }
18483
18534
  return toObject;
18484
18535
  }
18485
18536
  function createTuningJobParametersPrivateToMldev(fromObject, rootObject) {
@@ -19407,6 +19458,7 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
19407
19458
  */
19408
19459
  class GoogleGenAI {
19409
19460
  get interactions() {
19461
+ var _a;
19410
19462
  if (this._interactions !== undefined) {
19411
19463
  return this._interactions;
19412
19464
  }
@@ -19426,6 +19478,7 @@ class GoogleGenAI {
19426
19478
  clientAdapter: this.apiClient,
19427
19479
  defaultHeaders: this.apiClient.getDefaultHeaders(),
19428
19480
  timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19481
+ maxRetries: (_a = httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.retryOptions) === null || _a === void 0 ? void 0 : _a.attempts,
19429
19482
  });
19430
19483
  this._interactions = nextGenClient.interactions;
19431
19484
  return this._interactions;
package/dist/index.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ import pRetry, { AbortError } from 'p-retry';
2
+
1
3
  /**
2
4
  * @license
3
5
  * Copyright 2025 Google LLC
@@ -6929,10 +6931,22 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
6929
6931
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
6930
6932
  const USER_AGENT_HEADER = 'User-Agent';
6931
6933
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
6932
- const SDK_VERSION = '1.39.0'; // x-release-please-version
6934
+ const SDK_VERSION = '1.41.0'; // x-release-please-version
6933
6935
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
6934
6936
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
6935
6937
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
6938
+ // Default retry options.
6939
+ // The config is based on https://cloud.google.com/storage/docs/retry-strategy.
6940
+ const DEFAULT_RETRY_ATTEMPTS = 5; // Including the initial call
6941
+ // LINT.IfChange
6942
+ const DEFAULT_RETRY_HTTP_STATUS_CODES = [
6943
+ 408, // Request timeout
6944
+ 429, // Too many requests
6945
+ 500, // Internal server error
6946
+ 502, // Bad gateway
6947
+ 503, // Service unavailable
6948
+ 504, // Gateway timeout
6949
+ ];
6936
6950
  /**
6937
6951
  * The ApiClient class is used to send requests to the Gemini API or Vertex AI
6938
6952
  * endpoints.
@@ -7317,8 +7331,25 @@ class ApiClient {
7317
7331
  });
7318
7332
  }
7319
7333
  async apiCall(url, requestInit) {
7320
- return fetch(url, requestInit).catch((e) => {
7321
- throw new Error(`exception ${e} sending request`);
7334
+ var _a;
7335
+ if (!this.clientOptions.httpOptions ||
7336
+ !this.clientOptions.httpOptions.retryOptions) {
7337
+ return fetch(url, requestInit);
7338
+ }
7339
+ const retryOptions = this.clientOptions.httpOptions.retryOptions;
7340
+ const runFetch = async () => {
7341
+ const response = await fetch(url, requestInit);
7342
+ if (response.ok) {
7343
+ return response;
7344
+ }
7345
+ if (DEFAULT_RETRY_HTTP_STATUS_CODES.includes(response.status)) {
7346
+ throw new Error(`Retryable HTTP Error: ${response.statusText}`);
7347
+ }
7348
+ throw new AbortError(`Non-retryable exception ${response.statusText} sending request`);
7349
+ };
7350
+ return pRetry(runFetch, {
7351
+ // Retry attempts is one less than the number of total attempts.
7352
+ retries: ((_a = retryOptions.attempts) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_ATTEMPTS) - 1,
7322
7353
  });
7323
7354
  }
7324
7355
  getDefaultHeaders() {
@@ -10015,6 +10046,11 @@ async function defaultParseResponse(client, props) {
10015
10046
  const mediaType = (_a = contentType === null || contentType === void 0 ? void 0 : contentType.split(';')[0]) === null || _a === void 0 ? void 0 : _a.trim();
10016
10047
  const isJSON = (mediaType === null || mediaType === void 0 ? void 0 : mediaType.includes('application/json')) || (mediaType === null || mediaType === void 0 ? void 0 : mediaType.endsWith('+json'));
10017
10048
  if (isJSON) {
10049
+ const contentLength = response.headers.get('content-length');
10050
+ if (contentLength === '0') {
10051
+ // if there is no content we can't do anything
10052
+ return undefined;
10053
+ }
10018
10054
  const json = await response.json();
10019
10055
  return json;
10020
10056
  }
@@ -10474,9 +10510,10 @@ class BaseGeminiNextGenAPIClient {
10474
10510
  }
10475
10511
  async fetchWithTimeout(url, init, ms, controller) {
10476
10512
  const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
10513
+ const abort = this._makeAbort(controller);
10477
10514
  if (signal)
10478
- signal.addEventListener('abort', () => controller.abort());
10479
- const timeout = setTimeout(() => controller.abort(), ms);
10515
+ signal.addEventListener('abort', abort, { once: true });
10516
+ const timeout = setTimeout(abort, ms);
10480
10517
  const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
10481
10518
  (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
10482
10519
  const fetchOptions = Object.assign(Object.assign(Object.assign({ signal: controller.signal }, (isReadableBody ? { duplex: 'half' } : {})), { method: 'GET' }), options);
@@ -10589,6 +10626,11 @@ class BaseGeminiNextGenAPIClient {
10589
10626
  this.validateHeaders(headers);
10590
10627
  return headers.values;
10591
10628
  }
10629
+ _makeAbort(controller) {
10630
+ // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
10631
+ // would capture all request options, and cause a memory leak.
10632
+ return () => controller.abort();
10633
+ }
10592
10634
  buildBody({ options: { body, headers: rawHeaders } }) {
10593
10635
  if (!body) {
10594
10636
  return { bodyHeaders: undefined, body: undefined };
@@ -18243,6 +18285,9 @@ function createTuningJobConfigToMldev(fromObject, parentObject, _rootObject) {
18243
18285
  if (getValueByPath(fromObject, ['outputUri']) !== undefined) {
18244
18286
  throw new Error('outputUri parameter is not supported in Gemini API.');
18245
18287
  }
18288
+ if (getValueByPath(fromObject, ['encryptionSpec']) !== undefined) {
18289
+ throw new Error('encryptionSpec parameter is not supported in Gemini API.');
18290
+ }
18246
18291
  return toObject;
18247
18292
  }
18248
18293
  function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
@@ -18478,6 +18523,12 @@ function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
18478
18523
  if (parentObject !== undefined && fromOutputUri != null) {
18479
18524
  setValueByPath(parentObject, ['outputUri'], fromOutputUri);
18480
18525
  }
18526
+ const fromEncryptionSpec = getValueByPath(fromObject, [
18527
+ 'encryptionSpec',
18528
+ ]);
18529
+ if (parentObject !== undefined && fromEncryptionSpec != null) {
18530
+ setValueByPath(parentObject, ['encryptionSpec'], fromEncryptionSpec);
18531
+ }
18481
18532
  return toObject;
18482
18533
  }
18483
18534
  function createTuningJobParametersPrivateToMldev(fromObject, rootObject) {
@@ -19405,6 +19456,7 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
19405
19456
  */
19406
19457
  class GoogleGenAI {
19407
19458
  get interactions() {
19459
+ var _a;
19408
19460
  if (this._interactions !== undefined) {
19409
19461
  return this._interactions;
19410
19462
  }
@@ -19424,6 +19476,7 @@ class GoogleGenAI {
19424
19476
  clientAdapter: this.apiClient,
19425
19477
  defaultHeaders: this.apiClient.getDefaultHeaders(),
19426
19478
  timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19479
+ maxRetries: (_a = httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.retryOptions) === null || _a === void 0 ? void 0 : _a.attempts,
19427
19480
  });
19428
19481
  this._interactions = nextGenClient.interactions;
19429
19482
  return this._interactions;