@google/genai 1.40.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.
@@ -1,3 +1,5 @@
1
+ import pRetry, { AbortError } from 'p-retry';
2
+
1
3
  /**
2
4
  * @license
3
5
  * Copyright 2025 Google LLC
@@ -11608,10 +11610,22 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
11608
11610
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
11609
11611
  const USER_AGENT_HEADER = 'User-Agent';
11610
11612
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
11611
- const SDK_VERSION = '1.40.0'; // x-release-please-version
11613
+ const SDK_VERSION = '1.41.0'; // x-release-please-version
11612
11614
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
11613
11615
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
11614
11616
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
11617
+ // Default retry options.
11618
+ // The config is based on https://cloud.google.com/storage/docs/retry-strategy.
11619
+ const DEFAULT_RETRY_ATTEMPTS = 5; // Including the initial call
11620
+ // LINT.IfChange
11621
+ const DEFAULT_RETRY_HTTP_STATUS_CODES = [
11622
+ 408, // Request timeout
11623
+ 429, // Too many requests
11624
+ 500, // Internal server error
11625
+ 502, // Bad gateway
11626
+ 503, // Service unavailable
11627
+ 504, // Gateway timeout
11628
+ ];
11615
11629
  /**
11616
11630
  * The ApiClient class is used to send requests to the Gemini API or Vertex AI
11617
11631
  * endpoints.
@@ -11996,8 +12010,25 @@ class ApiClient {
11996
12010
  });
11997
12011
  }
11998
12012
  async apiCall(url, requestInit) {
11999
- return fetch(url, requestInit).catch((e) => {
12000
- throw new Error(`exception ${e} sending request`);
12013
+ var _a;
12014
+ if (!this.clientOptions.httpOptions ||
12015
+ !this.clientOptions.httpOptions.retryOptions) {
12016
+ return fetch(url, requestInit);
12017
+ }
12018
+ const retryOptions = this.clientOptions.httpOptions.retryOptions;
12019
+ const runFetch = async () => {
12020
+ const response = await fetch(url, requestInit);
12021
+ if (response.ok) {
12022
+ return response;
12023
+ }
12024
+ if (DEFAULT_RETRY_HTTP_STATUS_CODES.includes(response.status)) {
12025
+ throw new Error(`Retryable HTTP Error: ${response.statusText}`);
12026
+ }
12027
+ throw new AbortError(`Non-retryable exception ${response.statusText} sending request`);
12028
+ };
12029
+ return pRetry(runFetch, {
12030
+ // Retry attempts is one less than the number of total attempts.
12031
+ retries: ((_a = retryOptions.attempts) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_ATTEMPTS) - 1,
12001
12032
  });
12002
12033
  }
12003
12034
  getDefaultHeaders() {
@@ -17845,7 +17876,7 @@ class BaseGeminiNextGenAPIClient {
17845
17876
  }
17846
17877
  async fetchWithTimeout(url, init, ms, controller) {
17847
17878
  const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
17848
- const abort = controller.abort.bind(controller);
17879
+ const abort = this._makeAbort(controller);
17849
17880
  if (signal)
17850
17881
  signal.addEventListener('abort', abort, { once: true });
17851
17882
  const timeout = setTimeout(abort, ms);
@@ -17961,6 +17992,11 @@ class BaseGeminiNextGenAPIClient {
17961
17992
  this.validateHeaders(headers);
17962
17993
  return headers.values;
17963
17994
  }
17995
+ _makeAbort(controller) {
17996
+ // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
17997
+ // would capture all request options, and cause a memory leak.
17998
+ return () => controller.abort();
17999
+ }
17964
18000
  buildBody({ options: { body, headers: rawHeaders } }) {
17965
18001
  if (!body) {
17966
18002
  return { bodyHeaders: undefined, body: undefined };
@@ -18131,6 +18167,9 @@ function createTuningJobConfigToMldev(fromObject, parentObject, _rootObject) {
18131
18167
  if (getValueByPath(fromObject, ['outputUri']) !== undefined) {
18132
18168
  throw new Error('outputUri parameter is not supported in Gemini API.');
18133
18169
  }
18170
+ if (getValueByPath(fromObject, ['encryptionSpec']) !== undefined) {
18171
+ throw new Error('encryptionSpec parameter is not supported in Gemini API.');
18172
+ }
18134
18173
  return toObject;
18135
18174
  }
18136
18175
  function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
@@ -18366,6 +18405,12 @@ function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
18366
18405
  if (parentObject !== undefined && fromOutputUri != null) {
18367
18406
  setValueByPath(parentObject, ['outputUri'], fromOutputUri);
18368
18407
  }
18408
+ const fromEncryptionSpec = getValueByPath(fromObject, [
18409
+ 'encryptionSpec',
18410
+ ]);
18411
+ if (parentObject !== undefined && fromEncryptionSpec != null) {
18412
+ setValueByPath(parentObject, ['encryptionSpec'], fromEncryptionSpec);
18413
+ }
18369
18414
  return toObject;
18370
18415
  }
18371
18416
  function createTuningJobParametersPrivateToMldev(fromObject, rootObject) {
@@ -19454,6 +19499,7 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
19454
19499
  */
19455
19500
  class GoogleGenAI {
19456
19501
  get interactions() {
19502
+ var _a;
19457
19503
  if (this._interactions !== undefined) {
19458
19504
  return this._interactions;
19459
19505
  }
@@ -19470,6 +19516,7 @@ class GoogleGenAI {
19470
19516
  clientAdapter: this.apiClient,
19471
19517
  defaultHeaders: this.apiClient.getDefaultHeaders(),
19472
19518
  timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19519
+ maxRetries: (_a = httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.retryOptions) === null || _a === void 0 ? void 0 : _a.attempts,
19473
19520
  });
19474
19521
  this._interactions = nextGenClient.interactions;
19475
19522
  return this._interactions;