@google/genai 1.32.0 → 1.34.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.
@@ -5,7 +5,7 @@ import { writeFile } from 'fs/promises';
5
5
  import { Readable } from 'node:stream';
6
6
  import { finished } from 'node:stream/promises';
7
7
  import * as NodeWs from 'ws';
8
- import * as path from 'path';
8
+ import * as path$1 from 'path';
9
9
 
10
10
  /**
11
11
  * @license
@@ -795,21 +795,29 @@ var PhishBlockThreshold;
795
795
  */
796
796
  PhishBlockThreshold["BLOCK_ONLY_EXTREMELY_HIGH"] = "BLOCK_ONLY_EXTREMELY_HIGH";
797
797
  })(PhishBlockThreshold || (PhishBlockThreshold = {}));
798
- /** The level of thoughts tokens that the model should generate. */
798
+ /** The number of thoughts tokens that the model should generate. */
799
799
  var ThinkingLevel;
800
800
  (function (ThinkingLevel) {
801
801
  /**
802
- * Default value.
802
+ * Unspecified thinking level.
803
803
  */
804
804
  ThinkingLevel["THINKING_LEVEL_UNSPECIFIED"] = "THINKING_LEVEL_UNSPECIFIED";
805
805
  /**
806
806
  * Low thinking level.
807
807
  */
808
808
  ThinkingLevel["LOW"] = "LOW";
809
+ /**
810
+ * Medium thinking level.
811
+ */
812
+ ThinkingLevel["MEDIUM"] = "MEDIUM";
809
813
  /**
810
814
  * High thinking level.
811
815
  */
812
816
  ThinkingLevel["HIGH"] = "HIGH";
817
+ /**
818
+ * MINIMAL thinking level.
819
+ */
820
+ ThinkingLevel["MINIMAL"] = "MINIMAL";
813
821
  })(ThinkingLevel || (ThinkingLevel = {}));
814
822
  /** Harm category. */
815
823
  var HarmCategory;
@@ -968,6 +976,14 @@ var FinishReason;
968
976
  * The model was expected to generate an image, but none was generated.
969
977
  */
970
978
  FinishReason["NO_IMAGE"] = "NO_IMAGE";
979
+ /**
980
+ * Image generation stopped because the generated image may be a recitation from a source.
981
+ */
982
+ FinishReason["IMAGE_RECITATION"] = "IMAGE_RECITATION";
983
+ /**
984
+ * Image generation stopped for a reason not otherwise specified.
985
+ */
986
+ FinishReason["IMAGE_OTHER"] = "IMAGE_OTHER";
971
987
  })(FinishReason || (FinishReason = {}));
972
988
  /** Output only. Harm probability levels in the content. */
973
989
  var HarmProbability;
@@ -1272,6 +1288,10 @@ var PartMediaResolutionLevel;
1272
1288
  * Media resolution set to high.
1273
1289
  */
1274
1290
  PartMediaResolutionLevel["MEDIA_RESOLUTION_HIGH"] = "MEDIA_RESOLUTION_HIGH";
1291
+ /**
1292
+ * Media resolution set to ultra high.
1293
+ */
1294
+ PartMediaResolutionLevel["MEDIA_RESOLUTION_ULTRA_HIGH"] = "MEDIA_RESOLUTION_ULTRA_HIGH";
1275
1295
  })(PartMediaResolutionLevel || (PartMediaResolutionLevel = {}));
1276
1296
  /** Options for feature selection preference. */
1277
1297
  var FeatureSelectionPreference;
@@ -1590,6 +1610,22 @@ var MediaModality;
1590
1610
  */
1591
1611
  MediaModality["DOCUMENT"] = "DOCUMENT";
1592
1612
  })(MediaModality || (MediaModality = {}));
1613
+ /** The type of the VAD signal. */
1614
+ var VadSignalType;
1615
+ (function (VadSignalType) {
1616
+ /**
1617
+ * The default is VAD_SIGNAL_TYPE_UNSPECIFIED.
1618
+ */
1619
+ VadSignalType["VAD_SIGNAL_TYPE_UNSPECIFIED"] = "VAD_SIGNAL_TYPE_UNSPECIFIED";
1620
+ /**
1621
+ * Start of sentence signal.
1622
+ */
1623
+ VadSignalType["VAD_SIGNAL_TYPE_SOS"] = "VAD_SIGNAL_TYPE_SOS";
1624
+ /**
1625
+ * End of sentence signal.
1626
+ */
1627
+ VadSignalType["VAD_SIGNAL_TYPE_EOS"] = "VAD_SIGNAL_TYPE_EOS";
1628
+ })(VadSignalType || (VadSignalType = {}));
1593
1629
  /** Start of speech sensitivity. */
1594
1630
  var StartSensitivity;
1595
1631
  (function (StartSensitivity) {
@@ -6260,6 +6296,18 @@ PERFORMANCE OF THIS SOFTWARE.
6260
6296
  /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
6261
6297
 
6262
6298
 
6299
+ function __rest(s, e) {
6300
+ var t = {};
6301
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6302
+ t[p] = s[p];
6303
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6304
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
6305
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
6306
+ t[p[i]] = s[p[i]];
6307
+ }
6308
+ return t;
6309
+ }
6310
+
6263
6311
  function __values(o) {
6264
6312
  var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
6265
6313
  if (m) return m.call(o);
@@ -7219,7 +7267,7 @@ function generationConfigToVertex$1(fromObject) {
7219
7267
  }
7220
7268
  const fromSpeechConfig = getValueByPath(fromObject, ['speechConfig']);
7221
7269
  if (fromSpeechConfig != null) {
7222
- setValueByPath(toObject, ['speechConfig'], speechConfigToVertex$1(fromSpeechConfig));
7270
+ setValueByPath(toObject, ['speechConfig'], fromSpeechConfig);
7223
7271
  }
7224
7272
  const fromStopSequences = getValueByPath(fromObject, [
7225
7273
  'stopSequences',
@@ -7386,6 +7434,9 @@ function liveConnectConfigToMldev$1(fromObject, parentObject) {
7386
7434
  if (parentObject !== undefined && fromProactivity != null) {
7387
7435
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
7388
7436
  }
7437
+ if (getValueByPath(fromObject, ['explicitVadSignal']) !== undefined) {
7438
+ throw new Error('explicitVadSignal parameter is not supported in Gemini API.');
7439
+ }
7389
7440
  return toObject;
7390
7441
  }
7391
7442
  function liveConnectConfigToVertex(fromObject, parentObject) {
@@ -7432,7 +7483,7 @@ function liveConnectConfigToVertex(fromObject, parentObject) {
7432
7483
  }
7433
7484
  const fromSpeechConfig = getValueByPath(fromObject, ['speechConfig']);
7434
7485
  if (parentObject !== undefined && fromSpeechConfig != null) {
7435
- setValueByPath(parentObject, ['setup', 'generationConfig', 'speechConfig'], speechConfigToVertex$1(tLiveSpeechConfig(fromSpeechConfig)));
7486
+ setValueByPath(parentObject, ['setup', 'generationConfig', 'speechConfig'], tLiveSpeechConfig(fromSpeechConfig));
7436
7487
  }
7437
7488
  const fromThinkingConfig = getValueByPath(fromObject, [
7438
7489
  'thinkingConfig',
@@ -7496,6 +7547,12 @@ function liveConnectConfigToVertex(fromObject, parentObject) {
7496
7547
  if (parentObject !== undefined && fromProactivity != null) {
7497
7548
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
7498
7549
  }
7550
+ const fromExplicitVadSignal = getValueByPath(fromObject, [
7551
+ 'explicitVadSignal',
7552
+ ]);
7553
+ if (parentObject !== undefined && fromExplicitVadSignal != null) {
7554
+ setValueByPath(parentObject, ['setup', 'explicitVadSignal'], fromExplicitVadSignal);
7555
+ }
7499
7556
  return toObject;
7500
7557
  }
7501
7558
  function liveConnectParametersToMldev(apiClient, fromObject) {
@@ -7672,6 +7729,12 @@ function liveServerMessageFromVertex(fromObject) {
7672
7729
  if (fromSessionResumptionUpdate != null) {
7673
7730
  setValueByPath(toObject, ['sessionResumptionUpdate'], fromSessionResumptionUpdate);
7674
7731
  }
7732
+ const fromVoiceActivityDetectionSignal = getValueByPath(fromObject, [
7733
+ 'voiceActivityDetectionSignal',
7734
+ ]);
7735
+ if (fromVoiceActivityDetectionSignal != null) {
7736
+ setValueByPath(toObject, ['voiceActivityDetectionSignal'], fromVoiceActivityDetectionSignal);
7737
+ }
7675
7738
  return toObject;
7676
7739
  }
7677
7740
  function partToMldev$2(fromObject) {
@@ -7745,21 +7808,6 @@ function sessionResumptionConfigToMldev$1(fromObject) {
7745
7808
  }
7746
7809
  return toObject;
7747
7810
  }
7748
- function speechConfigToVertex$1(fromObject) {
7749
- const toObject = {};
7750
- const fromVoiceConfig = getValueByPath(fromObject, ['voiceConfig']);
7751
- if (fromVoiceConfig != null) {
7752
- setValueByPath(toObject, ['voiceConfig'], fromVoiceConfig);
7753
- }
7754
- const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
7755
- if (fromLanguageCode != null) {
7756
- setValueByPath(toObject, ['languageCode'], fromLanguageCode);
7757
- }
7758
- if (getValueByPath(fromObject, ['multiSpeakerVoiceConfig']) !== undefined) {
7759
- throw new Error('multiSpeakerVoiceConfig parameter is not supported in Vertex AI.');
7760
- }
7761
- return toObject;
7762
- }
7763
7811
  function toolToMldev$2(fromObject) {
7764
7812
  const toObject = {};
7765
7813
  const fromFunctionDeclarations = getValueByPath(fromObject, [
@@ -9002,7 +9050,7 @@ function generateContentConfigToVertex(apiClient, fromObject, parentObject) {
9002
9050
  }
9003
9051
  const fromSpeechConfig = getValueByPath(fromObject, ['speechConfig']);
9004
9052
  if (fromSpeechConfig != null) {
9005
- setValueByPath(toObject, ['speechConfig'], speechConfigToVertex(tSpeechConfig(fromSpeechConfig)));
9053
+ setValueByPath(toObject, ['speechConfig'], tSpeechConfig(fromSpeechConfig));
9006
9054
  }
9007
9055
  const fromAudioTimestamp = getValueByPath(fromObject, [
9008
9056
  'audioTimestamp',
@@ -9948,7 +9996,7 @@ function generationConfigToVertex(fromObject) {
9948
9996
  }
9949
9997
  const fromSpeechConfig = getValueByPath(fromObject, ['speechConfig']);
9950
9998
  if (fromSpeechConfig != null) {
9951
- setValueByPath(toObject, ['speechConfig'], speechConfigToVertex(fromSpeechConfig));
9999
+ setValueByPath(toObject, ['speechConfig'], fromSpeechConfig);
9952
10000
  }
9953
10001
  const fromStopSequences = getValueByPath(fromObject, [
9954
10002
  'stopSequences',
@@ -10750,21 +10798,6 @@ function segmentImageSourceToVertex(fromObject, parentObject) {
10750
10798
  }
10751
10799
  return toObject;
10752
10800
  }
10753
- function speechConfigToVertex(fromObject) {
10754
- const toObject = {};
10755
- const fromVoiceConfig = getValueByPath(fromObject, ['voiceConfig']);
10756
- if (fromVoiceConfig != null) {
10757
- setValueByPath(toObject, ['voiceConfig'], fromVoiceConfig);
10758
- }
10759
- const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
10760
- if (fromLanguageCode != null) {
10761
- setValueByPath(toObject, ['languageCode'], fromLanguageCode);
10762
- }
10763
- if (getValueByPath(fromObject, ['multiSpeakerVoiceConfig']) !== undefined) {
10764
- throw new Error('multiSpeakerVoiceConfig parameter is not supported in Vertex AI.');
10765
- }
10766
- return toObject;
10767
- }
10768
10801
  function toolConfigToMldev(fromObject) {
10769
10802
  const toObject = {};
10770
10803
  const fromFunctionCallingConfig = getValueByPath(fromObject, [
@@ -11446,7 +11479,7 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
11446
11479
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
11447
11480
  const USER_AGENT_HEADER = 'User-Agent';
11448
11481
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
11449
- const SDK_VERSION = '1.32.0'; // x-release-please-version
11482
+ const SDK_VERSION = '1.34.0'; // x-release-please-version
11450
11483
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
11451
11484
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
11452
11485
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
@@ -11520,6 +11553,11 @@ class ApiClient {
11520
11553
  getLocation() {
11521
11554
  return this.clientOptions.location;
11522
11555
  }
11556
+ async getAuthHeaders() {
11557
+ const headers = new Headers();
11558
+ await this.clientOptions.auth.addAuthHeaders(headers);
11559
+ return headers;
11560
+ }
11523
11561
  getApiVersion() {
11524
11562
  if (this.clientOptions.httpOptions &&
11525
11563
  this.clientOptions.httpOptions.apiVersion !== undefined) {
@@ -14918,6 +14956,9 @@ function liveConnectConfigToMldev(fromObject, parentObject) {
14918
14956
  if (parentObject !== undefined && fromProactivity != null) {
14919
14957
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
14920
14958
  }
14959
+ if (getValueByPath(fromObject, ['explicitVadSignal']) !== undefined) {
14960
+ throw new Error('explicitVadSignal parameter is not supported in Gemini API.');
14961
+ }
14921
14962
  return toObject;
14922
14963
  }
14923
14964
  function liveConnectConstraintsToMldev(apiClient, fromObject) {
@@ -15830,201 +15871,2193 @@ class FileSearchStores extends BaseModule {
15830
15871
  * Copyright 2025 Google LLC
15831
15872
  * SPDX-License-Identifier: Apache-2.0
15832
15873
  */
15833
- const GOOGLE_API_KEY_HEADER = 'x-goog-api-key';
15834
- const REQUIRED_VERTEX_AI_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
15835
- class NodeAuth {
15836
- constructor(opts) {
15837
- if (opts.apiKey !== undefined) {
15838
- this.apiKey = opts.apiKey;
15839
- return;
15840
- }
15841
- const vertexAuthOptions = buildGoogleAuthOptions(opts.googleAuthOptions);
15842
- this.googleAuth = new GoogleAuth(vertexAuthOptions);
15843
- }
15844
- async addAuthHeaders(headers, url) {
15845
- if (this.apiKey !== undefined) {
15846
- if (this.apiKey.startsWith('auth_tokens/')) {
15847
- throw new Error('Ephemeral tokens are only supported by the live API.');
15848
- }
15849
- this.addKeyHeader(headers);
15850
- return;
15851
- }
15852
- return this.addGoogleAuthHeaders(headers, url);
15853
- }
15854
- addKeyHeader(headers) {
15855
- if (headers.get(GOOGLE_API_KEY_HEADER) !== null) {
15856
- return;
15857
- }
15858
- if (this.apiKey === undefined) {
15859
- // This should never happen, this method is only called
15860
- // when apiKey is set.
15861
- throw new Error('Trying to set API key header but apiKey is not set');
15862
- }
15863
- headers.append(GOOGLE_API_KEY_HEADER, this.apiKey);
15864
- }
15865
- async addGoogleAuthHeaders(headers, url) {
15866
- if (this.googleAuth === undefined) {
15867
- // This should never happen, addGoogleAuthHeaders should only be
15868
- // called when there is no apiKey set and in these cases googleAuth
15869
- // is set.
15870
- throw new Error('Trying to set google-auth headers but googleAuth is unset');
15871
- }
15872
- const authHeaders = await this.googleAuth.getRequestHeaders(url);
15873
- for (const [key, value] of authHeaders) {
15874
- if (headers.get(key) !== null) {
15875
- continue;
15874
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15875
+ /**
15876
+ * https://stackoverflow.com/a/2117523
15877
+ */
15878
+ let uuid4Internal = function () {
15879
+ const { crypto } = globalThis;
15880
+ if (crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) {
15881
+ uuid4Internal = crypto.randomUUID.bind(crypto);
15882
+ return crypto.randomUUID();
15883
+ }
15884
+ const u8 = new Uint8Array(1);
15885
+ const randomByte = crypto ? () => crypto.getRandomValues(u8)[0] : () => (Math.random() * 0xff) & 0xff;
15886
+ return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16));
15887
+ };
15888
+ const uuid4 = () => uuid4Internal();
15889
+
15890
+ /**
15891
+ * @license
15892
+ * Copyright 2025 Google LLC
15893
+ * SPDX-License-Identifier: Apache-2.0
15894
+ */
15895
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15896
+ function isAbortError(err) {
15897
+ return (typeof err === 'object' &&
15898
+ err !== null &&
15899
+ // Spec-compliant fetch implementations
15900
+ (('name' in err && err.name === 'AbortError') ||
15901
+ // Expo fetch
15902
+ ('message' in err && String(err.message).includes('FetchRequestCanceledException'))));
15903
+ }
15904
+ const castToError = (err) => {
15905
+ if (err instanceof Error)
15906
+ return err;
15907
+ if (typeof err === 'object' && err !== null) {
15908
+ try {
15909
+ if (Object.prototype.toString.call(err) === '[object Error]') {
15910
+ // @ts-ignore - not all envs have native support for cause yet
15911
+ const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
15912
+ if (err.stack)
15913
+ error.stack = err.stack;
15914
+ // @ts-ignore - not all envs have native support for cause yet
15915
+ if (err.cause && !error.cause)
15916
+ error.cause = err.cause;
15917
+ if (err.name)
15918
+ error.name = err.name;
15919
+ return error;
15876
15920
  }
15877
- headers.append(key, value);
15878
15921
  }
15879
- }
15880
- }
15881
- function buildGoogleAuthOptions(googleAuthOptions) {
15882
- let authOptions;
15883
- if (!googleAuthOptions) {
15884
- authOptions = {
15885
- scopes: [REQUIRED_VERTEX_AI_SCOPE],
15886
- };
15887
- return authOptions;
15888
- }
15889
- else {
15890
- authOptions = googleAuthOptions;
15891
- if (!authOptions.scopes) {
15892
- authOptions.scopes = [REQUIRED_VERTEX_AI_SCOPE];
15893
- return authOptions;
15894
- }
15895
- else if ((typeof authOptions.scopes === 'string' &&
15896
- authOptions.scopes !== REQUIRED_VERTEX_AI_SCOPE) ||
15897
- (Array.isArray(authOptions.scopes) &&
15898
- authOptions.scopes.indexOf(REQUIRED_VERTEX_AI_SCOPE) < 0)) {
15899
- throw new Error(`Invalid auth scopes. Scopes must include: ${REQUIRED_VERTEX_AI_SCOPE}`);
15922
+ catch (_a) { }
15923
+ try {
15924
+ return new Error(JSON.stringify(err));
15900
15925
  }
15901
- return authOptions;
15926
+ catch (_b) { }
15902
15927
  }
15903
- }
15928
+ return new Error(err);
15929
+ };
15904
15930
 
15905
15931
  /**
15906
15932
  * @license
15907
15933
  * Copyright 2025 Google LLC
15908
15934
  * SPDX-License-Identifier: Apache-2.0
15909
15935
  */
15910
- class NodeDownloader {
15911
- async download(params, apiClient) {
15912
- if (params.downloadPath) {
15913
- const response = await downloadFile(params, apiClient);
15914
- if (response instanceof HttpResponse) {
15915
- const writer = createWriteStream(params.downloadPath);
15916
- const body = Readable.fromWeb(response.responseInternal.body);
15917
- body.pipe(writer);
15918
- await finished(writer);
15919
- }
15920
- else {
15921
- try {
15922
- await writeFile(params.downloadPath, response, {
15923
- encoding: 'base64',
15924
- });
15925
- }
15926
- catch (error) {
15927
- throw new Error(`Failed to write file to ${params.downloadPath}: ${error}`);
15928
- }
15929
- }
15930
- }
15931
- }
15936
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15937
+ class GeminiNextGenAPIClientError extends Error {
15932
15938
  }
15933
- async function downloadFile(params, apiClient) {
15934
- var _a, _b, _c;
15935
- const name = tFileName(params.file);
15936
- if (name !== undefined) {
15937
- return await apiClient.request({
15938
- path: `files/${name}:download`,
15939
- httpMethod: 'GET',
15940
- queryParams: {
15941
- 'alt': 'media',
15942
- },
15943
- httpOptions: (_a = params.config) === null || _a === void 0 ? void 0 : _a.httpOptions,
15944
- abortSignal: (_b = params.config) === null || _b === void 0 ? void 0 : _b.abortSignal,
15945
- });
15939
+ class APIError extends GeminiNextGenAPIClientError {
15940
+ constructor(status, error, message, headers) {
15941
+ super(`${APIError.makeMessage(status, error, message)}`);
15942
+ this.status = status;
15943
+ this.headers = headers;
15944
+ this.error = error;
15946
15945
  }
15947
- else if (isGeneratedVideo(params.file)) {
15948
- const videoBytes = (_c = params.file.video) === null || _c === void 0 ? void 0 : _c.videoBytes;
15949
- if (typeof videoBytes === 'string') {
15950
- return videoBytes;
15946
+ static makeMessage(status, error, message) {
15947
+ const msg = (error === null || error === void 0 ? void 0 : error.message) ?
15948
+ typeof error.message === 'string' ?
15949
+ error.message
15950
+ : JSON.stringify(error.message)
15951
+ : error ? JSON.stringify(error)
15952
+ : message;
15953
+ if (status && msg) {
15954
+ return `${status} ${msg}`;
15951
15955
  }
15952
- else {
15953
- throw new Error('Failed to download generated video, Uri or videoBytes not found.');
15956
+ if (status) {
15957
+ return `${status} status code (no body)`;
15958
+ }
15959
+ if (msg) {
15960
+ return msg;
15954
15961
  }
15962
+ return '(no status code or body)';
15955
15963
  }
15956
- else if (isVideo(params.file)) {
15957
- const videoBytes = params.file.videoBytes;
15958
- if (typeof videoBytes === 'string') {
15959
- return videoBytes;
15964
+ static generate(status, errorResponse, message, headers) {
15965
+ if (!status || !headers) {
15966
+ return new APIConnectionError({ message, cause: castToError(errorResponse) });
15960
15967
  }
15961
- else {
15962
- throw new Error('Failed to download video, Uri or videoBytes not found.');
15968
+ const error = errorResponse;
15969
+ if (status === 400) {
15970
+ return new BadRequestError(status, error, message, headers);
15971
+ }
15972
+ if (status === 401) {
15973
+ return new AuthenticationError(status, error, message, headers);
15974
+ }
15975
+ if (status === 403) {
15976
+ return new PermissionDeniedError(status, error, message, headers);
15977
+ }
15978
+ if (status === 404) {
15979
+ return new NotFoundError(status, error, message, headers);
15980
+ }
15981
+ if (status === 409) {
15982
+ return new ConflictError(status, error, message, headers);
15983
+ }
15984
+ if (status === 422) {
15985
+ return new UnprocessableEntityError(status, error, message, headers);
15986
+ }
15987
+ if (status === 429) {
15988
+ return new RateLimitError(status, error, message, headers);
15963
15989
  }
15990
+ if (status >= 500) {
15991
+ return new InternalServerError(status, error, message, headers);
15992
+ }
15993
+ return new APIError(status, error, message, headers);
15964
15994
  }
15965
- else {
15966
- throw new Error('Unsupported file type');
15995
+ }
15996
+ class APIUserAbortError extends APIError {
15997
+ constructor({ message } = {}) {
15998
+ super(undefined, undefined, message || 'Request was aborted.', undefined);
15999
+ }
16000
+ }
16001
+ class APIConnectionError extends APIError {
16002
+ constructor({ message, cause }) {
16003
+ super(undefined, undefined, message || 'Connection error.', undefined);
16004
+ // in some environments the 'cause' property is already declared
16005
+ // @ts-ignore
16006
+ if (cause)
16007
+ this.cause = cause;
16008
+ }
16009
+ }
16010
+ class APIConnectionTimeoutError extends APIConnectionError {
16011
+ constructor({ message } = {}) {
16012
+ super({ message: message !== null && message !== void 0 ? message : 'Request timed out.' });
15967
16013
  }
15968
16014
  }
16015
+ class BadRequestError extends APIError {
16016
+ }
16017
+ class AuthenticationError extends APIError {
16018
+ }
16019
+ class PermissionDeniedError extends APIError {
16020
+ }
16021
+ class NotFoundError extends APIError {
16022
+ }
16023
+ class ConflictError extends APIError {
16024
+ }
16025
+ class UnprocessableEntityError extends APIError {
16026
+ }
16027
+ class RateLimitError extends APIError {
16028
+ }
16029
+ class InternalServerError extends APIError {
16030
+ }
15969
16031
 
15970
16032
  /**
15971
16033
  * @license
15972
16034
  * Copyright 2025 Google LLC
15973
16035
  * SPDX-License-Identifier: Apache-2.0
15974
16036
  */
15975
- class NodeWebSocketFactory {
15976
- create(url, headers, callbacks) {
15977
- return new NodeWebSocket(url, headers, callbacks);
15978
- }
16037
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16038
+ // https://url.spec.whatwg.org/#url-scheme-string
16039
+ const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
16040
+ const isAbsoluteURL = (url) => {
16041
+ return startsWithSchemeRegexp.test(url);
16042
+ };
16043
+ let isArrayInternal = (val) => ((isArrayInternal = Array.isArray), isArrayInternal(val));
16044
+ const isArray = isArrayInternal;
16045
+ let isReadonlyArrayInternal = isArray;
16046
+ const isReadonlyArray = isReadonlyArrayInternal;
16047
+ // https://stackoverflow.com/a/34491287
16048
+ function isEmptyObj(obj) {
16049
+ if (!obj)
16050
+ return true;
16051
+ for (const _k in obj)
16052
+ return false;
16053
+ return true;
15979
16054
  }
15980
- class NodeWebSocket {
15981
- constructor(url, headers, callbacks) {
15982
- this.url = url;
15983
- this.headers = headers;
15984
- this.callbacks = callbacks;
16055
+ // https://eslint.org/docs/latest/rules/no-prototype-builtins
16056
+ function hasOwn(obj, key) {
16057
+ return Object.prototype.hasOwnProperty.call(obj, key);
16058
+ }
16059
+ const validatePositiveInteger = (name, n) => {
16060
+ if (typeof n !== 'number' || !Number.isInteger(n)) {
16061
+ throw new GeminiNextGenAPIClientError(`${name} must be an integer`);
15985
16062
  }
15986
- connect() {
15987
- this.ws = new NodeWs.WebSocket(this.url, { headers: this.headers });
15988
- this.ws.onopen = this.callbacks.onopen;
15989
- this.ws.onerror = this.callbacks.onerror;
15990
- this.ws.onclose = this.callbacks.onclose;
15991
- this.ws.onmessage = this.callbacks.onmessage;
16063
+ if (n < 0) {
16064
+ throw new GeminiNextGenAPIClientError(`${name} must be a positive integer`);
15992
16065
  }
15993
- send(message) {
15994
- if (this.ws === undefined) {
15995
- throw new Error('WebSocket is not connected');
15996
- }
15997
- this.ws.send(message);
16066
+ return n;
16067
+ };
16068
+ const safeJSON = (text) => {
16069
+ try {
16070
+ return JSON.parse(text);
15998
16071
  }
15999
- close() {
16000
- if (this.ws === undefined) {
16001
- throw new Error('WebSocket is not connected');
16002
- }
16003
- this.ws.close();
16072
+ catch (err) {
16073
+ return undefined;
16004
16074
  }
16005
- }
16075
+ };
16006
16076
 
16007
16077
  /**
16008
16078
  * @license
16009
16079
  * Copyright 2025 Google LLC
16010
16080
  * SPDX-License-Identifier: Apache-2.0
16011
16081
  */
16012
- // Code generated by the Google Gen AI SDK generator DO NOT EDIT.
16013
- function cancelTuningJobParametersToMldev(fromObject, _rootObject) {
16014
- const toObject = {};
16015
- const fromName = getValueByPath(fromObject, ['name']);
16016
- if (fromName != null) {
16017
- setValueByPath(toObject, ['_url', 'name'], fromName);
16082
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16083
+ const sleep$1 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
16084
+
16085
+ /**
16086
+ * @license
16087
+ * Copyright 2025 Google LLC
16088
+ * SPDX-License-Identifier: Apache-2.0
16089
+ */
16090
+ const VERSION = '0.0.1';
16091
+
16092
+ /**
16093
+ * @license
16094
+ * Copyright 2025 Google LLC
16095
+ * SPDX-License-Identifier: Apache-2.0
16096
+ */
16097
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16098
+ /**
16099
+ * Note this does not detect 'browser'; for that, use getBrowserInfo().
16100
+ */
16101
+ function getDetectedPlatform() {
16102
+ if (typeof Deno !== 'undefined' && Deno.build != null) {
16103
+ return 'deno';
16018
16104
  }
16019
- return toObject;
16020
- }
16021
- function cancelTuningJobParametersToVertex(fromObject, _rootObject) {
16022
- const toObject = {};
16023
- const fromName = getValueByPath(fromObject, ['name']);
16024
- if (fromName != null) {
16025
- setValueByPath(toObject, ['_url', 'name'], fromName);
16105
+ if (typeof EdgeRuntime !== 'undefined') {
16106
+ return 'edge';
16026
16107
  }
16027
- return toObject;
16108
+ if (Object.prototype.toString.call(typeof globalThis.process !== 'undefined' ? globalThis.process : 0) === '[object process]') {
16109
+ return 'node';
16110
+ }
16111
+ return 'unknown';
16112
+ }
16113
+ const getPlatformProperties = () => {
16114
+ var _a, _b, _c, _d, _e;
16115
+ const detectedPlatform = getDetectedPlatform();
16116
+ if (detectedPlatform === 'deno') {
16117
+ return {
16118
+ 'X-Stainless-Lang': 'js',
16119
+ 'X-Stainless-Package-Version': VERSION,
16120
+ 'X-Stainless-OS': normalizePlatform(Deno.build.os),
16121
+ 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
16122
+ 'X-Stainless-Runtime': 'deno',
16123
+ 'X-Stainless-Runtime-Version': typeof Deno.version === 'string' ? Deno.version : (_b = (_a = Deno.version) === null || _a === void 0 ? void 0 : _a.deno) !== null && _b !== void 0 ? _b : 'unknown',
16124
+ };
16125
+ }
16126
+ if (typeof EdgeRuntime !== 'undefined') {
16127
+ return {
16128
+ 'X-Stainless-Lang': 'js',
16129
+ 'X-Stainless-Package-Version': VERSION,
16130
+ 'X-Stainless-OS': 'Unknown',
16131
+ 'X-Stainless-Arch': `other:${EdgeRuntime}`,
16132
+ 'X-Stainless-Runtime': 'edge',
16133
+ 'X-Stainless-Runtime-Version': globalThis.process.version,
16134
+ };
16135
+ }
16136
+ // Check if Node.js
16137
+ if (detectedPlatform === 'node') {
16138
+ return {
16139
+ 'X-Stainless-Lang': 'js',
16140
+ 'X-Stainless-Package-Version': VERSION,
16141
+ 'X-Stainless-OS': normalizePlatform((_c = globalThis.process.platform) !== null && _c !== void 0 ? _c : 'unknown'),
16142
+ 'X-Stainless-Arch': normalizeArch((_d = globalThis.process.arch) !== null && _d !== void 0 ? _d : 'unknown'),
16143
+ 'X-Stainless-Runtime': 'node',
16144
+ 'X-Stainless-Runtime-Version': (_e = globalThis.process.version) !== null && _e !== void 0 ? _e : 'unknown',
16145
+ };
16146
+ }
16147
+ const browserInfo = getBrowserInfo();
16148
+ if (browserInfo) {
16149
+ return {
16150
+ 'X-Stainless-Lang': 'js',
16151
+ 'X-Stainless-Package-Version': VERSION,
16152
+ 'X-Stainless-OS': 'Unknown',
16153
+ 'X-Stainless-Arch': 'unknown',
16154
+ 'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
16155
+ 'X-Stainless-Runtime-Version': browserInfo.version,
16156
+ };
16157
+ }
16158
+ // TODO add support for Cloudflare workers, etc.
16159
+ return {
16160
+ 'X-Stainless-Lang': 'js',
16161
+ 'X-Stainless-Package-Version': VERSION,
16162
+ 'X-Stainless-OS': 'Unknown',
16163
+ 'X-Stainless-Arch': 'unknown',
16164
+ 'X-Stainless-Runtime': 'unknown',
16165
+ 'X-Stainless-Runtime-Version': 'unknown',
16166
+ };
16167
+ };
16168
+ // Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
16169
+ function getBrowserInfo() {
16170
+ if (typeof navigator === 'undefined' || !navigator) {
16171
+ return null;
16172
+ }
16173
+ // NOTE: The order matters here!
16174
+ const browserPatterns = [
16175
+ { key: 'edge', pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16176
+ { key: 'ie', pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16177
+ { key: 'ie', pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16178
+ { key: 'chrome', pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16179
+ { key: 'firefox', pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16180
+ { key: 'safari', pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
16181
+ ];
16182
+ // Find the FIRST matching browser
16183
+ for (const { key, pattern } of browserPatterns) {
16184
+ const match = pattern.exec(navigator.userAgent);
16185
+ if (match) {
16186
+ const major = match[1] || 0;
16187
+ const minor = match[2] || 0;
16188
+ const patch = match[3] || 0;
16189
+ return { browser: key, version: `${major}.${minor}.${patch}` };
16190
+ }
16191
+ }
16192
+ return null;
16193
+ }
16194
+ const normalizeArch = (arch) => {
16195
+ // Node docs:
16196
+ // - https://nodejs.org/api/process.html#processarch
16197
+ // Deno docs:
16198
+ // - https://doc.deno.land/deno/stable/~/Deno.build
16199
+ if (arch === 'x32')
16200
+ return 'x32';
16201
+ if (arch === 'x86_64' || arch === 'x64')
16202
+ return 'x64';
16203
+ if (arch === 'arm')
16204
+ return 'arm';
16205
+ if (arch === 'aarch64' || arch === 'arm64')
16206
+ return 'arm64';
16207
+ if (arch)
16208
+ return `other:${arch}`;
16209
+ return 'unknown';
16210
+ };
16211
+ const normalizePlatform = (platform) => {
16212
+ // Node platforms:
16213
+ // - https://nodejs.org/api/process.html#processplatform
16214
+ // Deno platforms:
16215
+ // - https://doc.deno.land/deno/stable/~/Deno.build
16216
+ // - https://github.com/denoland/deno/issues/14799
16217
+ platform = platform.toLowerCase();
16218
+ // NOTE: this iOS check is untested and may not work
16219
+ // Node does not work natively on IOS, there is a fork at
16220
+ // https://github.com/nodejs-mobile/nodejs-mobile
16221
+ // however it is unknown at the time of writing how to detect if it is running
16222
+ if (platform.includes('ios'))
16223
+ return 'iOS';
16224
+ if (platform === 'android')
16225
+ return 'Android';
16226
+ if (platform === 'darwin')
16227
+ return 'MacOS';
16228
+ if (platform === 'win32')
16229
+ return 'Windows';
16230
+ if (platform === 'freebsd')
16231
+ return 'FreeBSD';
16232
+ if (platform === 'openbsd')
16233
+ return 'OpenBSD';
16234
+ if (platform === 'linux')
16235
+ return 'Linux';
16236
+ if (platform)
16237
+ return `Other:${platform}`;
16238
+ return 'Unknown';
16239
+ };
16240
+ let _platformHeaders;
16241
+ const getPlatformHeaders = () => {
16242
+ return (_platformHeaders !== null && _platformHeaders !== void 0 ? _platformHeaders : (_platformHeaders = getPlatformProperties()));
16243
+ };
16244
+
16245
+ /**
16246
+ * @license
16247
+ * Copyright 2025 Google LLC
16248
+ * SPDX-License-Identifier: Apache-2.0
16249
+ */
16250
+ function getDefaultFetch() {
16251
+ if (typeof fetch !== 'undefined') {
16252
+ return fetch;
16253
+ }
16254
+ throw new Error('`fetch` is not defined as a global; Either pass `fetch` to the client, `new GeminiNextGenAPIClient({ fetch })` or polyfill the global, `globalThis.fetch = fetch`');
16255
+ }
16256
+ function makeReadableStream(...args) {
16257
+ const ReadableStream = globalThis.ReadableStream;
16258
+ if (typeof ReadableStream === 'undefined') {
16259
+ // Note: All of the platforms / runtimes we officially support already define
16260
+ // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes.
16261
+ throw new Error('`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`');
16262
+ }
16263
+ return new ReadableStream(...args);
16264
+ }
16265
+ function ReadableStreamFrom(iterable) {
16266
+ let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
16267
+ return makeReadableStream({
16268
+ start() { },
16269
+ async pull(controller) {
16270
+ const { done, value } = await iter.next();
16271
+ if (done) {
16272
+ controller.close();
16273
+ }
16274
+ else {
16275
+ controller.enqueue(value);
16276
+ }
16277
+ },
16278
+ async cancel() {
16279
+ var _a;
16280
+ await ((_a = iter.return) === null || _a === void 0 ? void 0 : _a.call(iter));
16281
+ },
16282
+ });
16283
+ }
16284
+ /**
16285
+ * Most browsers don't yet have async iterable support for ReadableStream,
16286
+ * and Node has a very different way of reading bytes from its "ReadableStream".
16287
+ *
16288
+ * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
16289
+ */
16290
+ function ReadableStreamToAsyncIterable(stream) {
16291
+ if (stream[Symbol.asyncIterator])
16292
+ return stream;
16293
+ const reader = stream.getReader();
16294
+ return {
16295
+ async next() {
16296
+ try {
16297
+ const result = await reader.read();
16298
+ if (result === null || result === void 0 ? void 0 : result.done)
16299
+ reader.releaseLock(); // release lock when stream becomes closed
16300
+ return result;
16301
+ }
16302
+ catch (e) {
16303
+ reader.releaseLock(); // release lock when stream becomes errored
16304
+ throw e;
16305
+ }
16306
+ },
16307
+ async return() {
16308
+ const cancelPromise = reader.cancel();
16309
+ reader.releaseLock();
16310
+ await cancelPromise;
16311
+ return { done: true, value: undefined };
16312
+ },
16313
+ [Symbol.asyncIterator]() {
16314
+ return this;
16315
+ },
16316
+ };
16317
+ }
16318
+ /**
16319
+ * Cancels a ReadableStream we don't need to consume.
16320
+ * See https://undici.nodejs.org/#/?id=garbage-collection
16321
+ */
16322
+ async function CancelReadableStream(stream) {
16323
+ var _a, _b;
16324
+ if (stream === null || typeof stream !== 'object')
16325
+ return;
16326
+ if (stream[Symbol.asyncIterator]) {
16327
+ await ((_b = (_a = stream[Symbol.asyncIterator]()).return) === null || _b === void 0 ? void 0 : _b.call(_a));
16328
+ return;
16329
+ }
16330
+ const reader = stream.getReader();
16331
+ const cancelPromise = reader.cancel();
16332
+ reader.releaseLock();
16333
+ await cancelPromise;
16334
+ }
16335
+
16336
+ /**
16337
+ * @license
16338
+ * Copyright 2025 Google LLC
16339
+ * SPDX-License-Identifier: Apache-2.0
16340
+ */
16341
+ const FallbackEncoder = ({ headers, body }) => {
16342
+ return {
16343
+ bodyHeaders: {
16344
+ 'content-type': 'application/json',
16345
+ },
16346
+ body: JSON.stringify(body),
16347
+ };
16348
+ };
16349
+
16350
+ /**
16351
+ * @license
16352
+ * Copyright 2025 Google LLC
16353
+ * SPDX-License-Identifier: Apache-2.0
16354
+ */
16355
+ const checkFileSupport = () => {
16356
+ var _a;
16357
+ if (typeof File === 'undefined') {
16358
+ const { process } = globalThis;
16359
+ const isOldNode = typeof ((_a = process === null || process === void 0 ? void 0 : process.versions) === null || _a === void 0 ? void 0 : _a.node) === 'string' && parseInt(process.versions.node.split('.')) < 20;
16360
+ throw new Error('`File` is not defined as a global, which is required for file uploads.' +
16361
+ (isOldNode ?
16362
+ " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`."
16363
+ : ''));
16364
+ }
16365
+ };
16366
+ /**
16367
+ * Construct a `File` instance. This is used to ensure a helpful error is thrown
16368
+ * for environments that don't define a global `File` yet.
16369
+ */
16370
+ function makeFile(fileBits, fileName, options) {
16371
+ checkFileSupport();
16372
+ return new File(fileBits, fileName !== null && fileName !== void 0 ? fileName : 'unknown_file', options);
16373
+ }
16374
+ function getName(value) {
16375
+ return (((typeof value === 'object' &&
16376
+ value !== null &&
16377
+ (('name' in value && value.name && String(value.name)) ||
16378
+ ('url' in value && value.url && String(value.url)) ||
16379
+ ('filename' in value && value.filename && String(value.filename)) ||
16380
+ ('path' in value && value.path && String(value.path)))) ||
16381
+ '')
16382
+ .split(/[\\/]/)
16383
+ .pop() || undefined);
16384
+ }
16385
+ const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
16386
+
16387
+ /**
16388
+ * @license
16389
+ * Copyright 2025 Google LLC
16390
+ * SPDX-License-Identifier: Apache-2.0
16391
+ */
16392
+ /**
16393
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
16394
+ */
16395
+ const isBlobLike = (value) => value != null &&
16396
+ typeof value === 'object' &&
16397
+ typeof value.size === 'number' &&
16398
+ typeof value.type === 'string' &&
16399
+ typeof value.text === 'function' &&
16400
+ typeof value.slice === 'function' &&
16401
+ typeof value.arrayBuffer === 'function';
16402
+ /**
16403
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
16404
+ */
16405
+ const isFileLike = (value) => value != null &&
16406
+ typeof value === 'object' &&
16407
+ typeof value.name === 'string' &&
16408
+ typeof value.lastModified === 'number' &&
16409
+ isBlobLike(value);
16410
+ const isResponseLike = (value) => value != null &&
16411
+ typeof value === 'object' &&
16412
+ typeof value.url === 'string' &&
16413
+ typeof value.blob === 'function';
16414
+ /**
16415
+ * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
16416
+ * @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts
16417
+ * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
16418
+ * @param {Object=} options additional properties
16419
+ * @param {string=} options.type the MIME type of the content
16420
+ * @param {number=} options.lastModified the last modified timestamp
16421
+ * @returns a {@link File} with the given properties
16422
+ */
16423
+ async function toFile(value, name, options) {
16424
+ checkFileSupport();
16425
+ // If it's a promise, resolve it.
16426
+ value = await value;
16427
+ // If we've been given a `File` we don't need to do anything
16428
+ if (isFileLike(value)) {
16429
+ if (value instanceof File) {
16430
+ return value;
16431
+ }
16432
+ return makeFile([await value.arrayBuffer()], value.name);
16433
+ }
16434
+ if (isResponseLike(value)) {
16435
+ const blob = await value.blob();
16436
+ name || (name = new URL(value.url).pathname.split(/[\\/]/).pop());
16437
+ return makeFile(await getBytes(blob), name, options);
16438
+ }
16439
+ const parts = await getBytes(value);
16440
+ name || (name = getName(value));
16441
+ if (!(options === null || options === void 0 ? void 0 : options.type)) {
16442
+ const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type);
16443
+ if (typeof type === 'string') {
16444
+ options = Object.assign(Object.assign({}, options), { type });
16445
+ }
16446
+ }
16447
+ return makeFile(parts, name, options);
16448
+ }
16449
+ async function getBytes(value) {
16450
+ var _a, e_1, _b, _c;
16451
+ var _d;
16452
+ let parts = [];
16453
+ if (typeof value === 'string' ||
16454
+ ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
16455
+ value instanceof ArrayBuffer) {
16456
+ parts.push(value);
16457
+ }
16458
+ else if (isBlobLike(value)) {
16459
+ parts.push(value instanceof Blob ? value : await value.arrayBuffer());
16460
+ }
16461
+ else if (isAsyncIterable(value) // includes Readable, ReadableStream, etc.
16462
+ ) {
16463
+ try {
16464
+ for (var _e = true, value_1 = __asyncValues(value), value_1_1; value_1_1 = await value_1.next(), _a = value_1_1.done, !_a; _e = true) {
16465
+ _c = value_1_1.value;
16466
+ _e = false;
16467
+ const chunk = _c;
16468
+ parts.push(...(await getBytes(chunk))); // TODO, consider validating?
16469
+ }
16470
+ }
16471
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
16472
+ finally {
16473
+ try {
16474
+ if (!_e && !_a && (_b = value_1.return)) await _b.call(value_1);
16475
+ }
16476
+ finally { if (e_1) throw e_1.error; }
16477
+ }
16478
+ }
16479
+ else {
16480
+ const constructor = (_d = value === null || value === void 0 ? void 0 : value.constructor) === null || _d === void 0 ? void 0 : _d.name;
16481
+ throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ''}${propsForError(value)}`);
16482
+ }
16483
+ return parts;
16484
+ }
16485
+ function propsForError(value) {
16486
+ if (typeof value !== 'object' || value === null)
16487
+ return '';
16488
+ const props = Object.getOwnPropertyNames(value);
16489
+ return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`;
16490
+ }
16491
+
16492
+ /**
16493
+ * @license
16494
+ * Copyright 2025 Google LLC
16495
+ * SPDX-License-Identifier: Apache-2.0
16496
+ */
16497
+ class APIResource {
16498
+ constructor(client) {
16499
+ this._client = client;
16500
+ }
16501
+ }
16502
+ /**
16503
+ * The key path from the client. For example, a resource accessible as `client.resource.subresource` would
16504
+ * have a property `static override readonly _key = Object.freeze(['resource', 'subresource'] as const);`.
16505
+ */
16506
+ APIResource._key = [];
16507
+
16508
+ /**
16509
+ * @license
16510
+ * Copyright 2025 Google LLC
16511
+ * SPDX-License-Identifier: Apache-2.0
16512
+ */
16513
+ /**
16514
+ * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
16515
+ *
16516
+ * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3:
16517
+ * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
16518
+ * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
16519
+ * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
16520
+ */
16521
+ function encodeURIPath(str) {
16522
+ return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
16523
+ }
16524
+ const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
16525
+ const createPathTagFunction = (pathEncoder = encodeURIPath) => (function path(statics, ...params) {
16526
+ // If there are no params, no processing is needed.
16527
+ if (statics.length === 1)
16528
+ return statics[0];
16529
+ let postPath = false;
16530
+ const invalidSegments = [];
16531
+ const path = statics.reduce((previousValue, currentValue, index) => {
16532
+ var _a, _b, _c;
16533
+ if (/[?#]/.test(currentValue)) {
16534
+ postPath = true;
16535
+ }
16536
+ const value = params[index];
16537
+ let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
16538
+ if (index !== params.length &&
16539
+ (value == null ||
16540
+ (typeof value === 'object' &&
16541
+ // handle values from other realms
16542
+ value.toString ===
16543
+ ((_c = Object.getPrototypeOf((_b = Object.getPrototypeOf((_a = value.hasOwnProperty) !== null && _a !== void 0 ? _a : EMPTY)) !== null && _b !== void 0 ? _b : EMPTY)) === null || _c === void 0 ? void 0 : _c.toString)))) {
16544
+ encoded = value + '';
16545
+ invalidSegments.push({
16546
+ start: previousValue.length + currentValue.length,
16547
+ length: encoded.length,
16548
+ error: `Value of type ${Object.prototype.toString
16549
+ .call(value)
16550
+ .slice(8, -1)} is not a valid path parameter`,
16551
+ });
16552
+ }
16553
+ return previousValue + currentValue + (index === params.length ? '' : encoded);
16554
+ }, '');
16555
+ const pathOnly = path.split(/[?#]/, 1)[0];
16556
+ const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
16557
+ let match;
16558
+ // Find all invalid segments
16559
+ while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
16560
+ invalidSegments.push({
16561
+ start: match.index,
16562
+ length: match[0].length,
16563
+ error: `Value "${match[0]}" can\'t be safely passed as a path parameter`,
16564
+ });
16565
+ }
16566
+ invalidSegments.sort((a, b) => a.start - b.start);
16567
+ if (invalidSegments.length > 0) {
16568
+ let lastEnd = 0;
16569
+ const underline = invalidSegments.reduce((acc, segment) => {
16570
+ const spaces = ' '.repeat(segment.start - lastEnd);
16571
+ const arrows = '^'.repeat(segment.length);
16572
+ lastEnd = segment.start + segment.length;
16573
+ return acc + spaces + arrows;
16574
+ }, '');
16575
+ throw new GeminiNextGenAPIClientError(`Path parameters result in path with invalid segments:\n${invalidSegments
16576
+ .map((e) => e.error)
16577
+ .join('\n')}\n${path}\n${underline}`);
16578
+ }
16579
+ return path;
16580
+ });
16581
+ /**
16582
+ * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
16583
+ */
16584
+ const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
16585
+
16586
+ /**
16587
+ * @license
16588
+ * Copyright 2025 Google LLC
16589
+ * SPDX-License-Identifier: Apache-2.0
16590
+ */
16591
+ class BaseInteractions extends APIResource {
16592
+ create(params, options) {
16593
+ var _a;
16594
+ const { api_version = this._client.apiVersion } = params, body = __rest(params, ["api_version"]);
16595
+ if ('model' in body && 'agent_config' in body) {
16596
+ throw new GeminiNextGenAPIClientError(`Invalid request: specified \`model\` and \`agent_config\`. If specifying \`model\`, use \`generation_config\`.`);
16597
+ }
16598
+ if ('agent' in body && 'generation_config' in body) {
16599
+ throw new GeminiNextGenAPIClientError(`Invalid request: specified \`agent\` and \`generation_config\`. If specifying \`agent\`, use \`agent_config\`.`);
16600
+ }
16601
+ return this._client.post(path `/${api_version}/interactions`, Object.assign(Object.assign({ body }, options), { stream: (_a = params.stream) !== null && _a !== void 0 ? _a : false }));
16602
+ }
16603
+ /**
16604
+ * Deletes the interaction by id.
16605
+ *
16606
+ * @example
16607
+ * ```ts
16608
+ * const interaction = await client.interactions.delete('id');
16609
+ * ```
16610
+ */
16611
+ delete(id, params = {}, options) {
16612
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
16613
+ return this._client.delete(path `/${api_version}/interactions/${id}`, options);
16614
+ }
16615
+ /**
16616
+ * Cancels an interaction by id. This only applies to background interactions that are still running.
16617
+ *
16618
+ * @example
16619
+ * ```ts
16620
+ * const interaction = await client.interactions.cancel('id');
16621
+ * ```
16622
+ */
16623
+ cancel(id, params = {}, options) {
16624
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
16625
+ return this._client.post(path `/${api_version}/interactions/${id}/cancel`, options);
16626
+ }
16627
+ get(id, params = {}, options) {
16628
+ var _a;
16629
+ const _b = params !== null && params !== void 0 ? params : {}, { api_version = this._client.apiVersion } = _b, query = __rest(_b, ["api_version"]);
16630
+ return this._client.get(path `/${api_version}/interactions/${id}`, Object.assign(Object.assign({ query }, options), { stream: (_a = params === null || params === void 0 ? void 0 : params.stream) !== null && _a !== void 0 ? _a : false }));
16631
+ }
16632
+ }
16633
+ BaseInteractions._key = Object.freeze(['interactions']);
16634
+ class Interactions extends BaseInteractions {
16635
+ }
16636
+
16637
+ /**
16638
+ * @license
16639
+ * Copyright 2025 Google LLC
16640
+ * SPDX-License-Identifier: Apache-2.0
16641
+ */
16642
+ function concatBytes(buffers) {
16643
+ let length = 0;
16644
+ for (const buffer of buffers) {
16645
+ length += buffer.length;
16646
+ }
16647
+ const output = new Uint8Array(length);
16648
+ let index = 0;
16649
+ for (const buffer of buffers) {
16650
+ output.set(buffer, index);
16651
+ index += buffer.length;
16652
+ }
16653
+ return output;
16654
+ }
16655
+ let encodeUTF8_;
16656
+ function encodeUTF8(str) {
16657
+ let encoder;
16658
+ return (encodeUTF8_ !== null && encodeUTF8_ !== void 0 ? encodeUTF8_ : ((encoder = new globalThis.TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))))(str);
16659
+ }
16660
+ let decodeUTF8_;
16661
+ function decodeUTF8(bytes) {
16662
+ let decoder;
16663
+ return (decodeUTF8_ !== null && decodeUTF8_ !== void 0 ? decodeUTF8_ : ((decoder = new globalThis.TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))))(bytes);
16664
+ }
16665
+
16666
+ /**
16667
+ * @license
16668
+ * Copyright 2025 Google LLC
16669
+ * SPDX-License-Identifier: Apache-2.0
16670
+ */
16671
+ /**
16672
+ * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
16673
+ * reading lines from text.
16674
+ *
16675
+ * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
16676
+ */
16677
+ class LineDecoder {
16678
+ constructor() {
16679
+ this.buffer = new Uint8Array();
16680
+ this.carriageReturnIndex = null;
16681
+ }
16682
+ decode(chunk) {
16683
+ if (chunk == null) {
16684
+ return [];
16685
+ }
16686
+ const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
16687
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
16688
+ : chunk;
16689
+ this.buffer = concatBytes([this.buffer, binaryChunk]);
16690
+ const lines = [];
16691
+ let patternIndex;
16692
+ while ((patternIndex = findNewlineIndex(this.buffer, this.carriageReturnIndex)) != null) {
16693
+ if (patternIndex.carriage && this.carriageReturnIndex == null) {
16694
+ // skip until we either get a corresponding `\n`, a new `\r` or nothing
16695
+ this.carriageReturnIndex = patternIndex.index;
16696
+ continue;
16697
+ }
16698
+ // we got double \r or \rtext\n
16699
+ if (this.carriageReturnIndex != null &&
16700
+ (patternIndex.index !== this.carriageReturnIndex + 1 || patternIndex.carriage)) {
16701
+ lines.push(decodeUTF8(this.buffer.subarray(0, this.carriageReturnIndex - 1)));
16702
+ this.buffer = this.buffer.subarray(this.carriageReturnIndex);
16703
+ this.carriageReturnIndex = null;
16704
+ continue;
16705
+ }
16706
+ const endIndex = this.carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
16707
+ const line = decodeUTF8(this.buffer.subarray(0, endIndex));
16708
+ lines.push(line);
16709
+ this.buffer = this.buffer.subarray(patternIndex.index);
16710
+ this.carriageReturnIndex = null;
16711
+ }
16712
+ return lines;
16713
+ }
16714
+ flush() {
16715
+ if (!this.buffer.length) {
16716
+ return [];
16717
+ }
16718
+ return this.decode('\n');
16719
+ }
16720
+ }
16721
+ // prettier-ignore
16722
+ LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']);
16723
+ LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
16724
+ /**
16725
+ * This function searches the buffer for the end patterns, (\r or \n)
16726
+ * and returns an object with the index preceding the matched newline and the
16727
+ * index after the newline char. `null` is returned if no new line is found.
16728
+ *
16729
+ * ```ts
16730
+ * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 }
16731
+ * ```
16732
+ */
16733
+ function findNewlineIndex(buffer, startIndex) {
16734
+ const newline = 0x0a; // \n
16735
+ const carriage = 0x0d; // \r
16736
+ for (let i = startIndex !== null && startIndex !== void 0 ? startIndex : 0; i < buffer.length; i++) {
16737
+ if (buffer[i] === newline) {
16738
+ return { preceding: i, index: i + 1, carriage: false };
16739
+ }
16740
+ if (buffer[i] === carriage) {
16741
+ return { preceding: i, index: i + 1, carriage: true };
16742
+ }
16743
+ }
16744
+ return null;
16745
+ }
16746
+ function findDoubleNewlineIndex(buffer) {
16747
+ // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n)
16748
+ // and returns the index right after the first occurrence of any pattern,
16749
+ // or -1 if none of the patterns are found.
16750
+ const newline = 0x0a; // \n
16751
+ const carriage = 0x0d; // \r
16752
+ for (let i = 0; i < buffer.length - 1; i++) {
16753
+ if (buffer[i] === newline && buffer[i + 1] === newline) {
16754
+ // \n\n
16755
+ return i + 2;
16756
+ }
16757
+ if (buffer[i] === carriage && buffer[i + 1] === carriage) {
16758
+ // \r\r
16759
+ return i + 2;
16760
+ }
16761
+ if (buffer[i] === carriage &&
16762
+ buffer[i + 1] === newline &&
16763
+ i + 3 < buffer.length &&
16764
+ buffer[i + 2] === carriage &&
16765
+ buffer[i + 3] === newline) {
16766
+ // \r\n\r\n
16767
+ return i + 4;
16768
+ }
16769
+ }
16770
+ return -1;
16771
+ }
16772
+
16773
+ /**
16774
+ * @license
16775
+ * Copyright 2025 Google LLC
16776
+ * SPDX-License-Identifier: Apache-2.0
16777
+ */
16778
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16779
+ const levelNumbers = {
16780
+ off: 0,
16781
+ error: 200,
16782
+ warn: 300,
16783
+ info: 400,
16784
+ debug: 500,
16785
+ };
16786
+ const parseLogLevel = (maybeLevel, sourceName, client) => {
16787
+ if (!maybeLevel) {
16788
+ return undefined;
16789
+ }
16790
+ if (hasOwn(levelNumbers, maybeLevel)) {
16791
+ return maybeLevel;
16792
+ }
16793
+ loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`);
16794
+ return undefined;
16795
+ };
16796
+ function noop() { }
16797
+ function makeLogFn(fnLevel, logger, logLevel) {
16798
+ if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
16799
+ return noop;
16800
+ }
16801
+ else {
16802
+ // Don't wrap logger functions, we want the stacktrace intact!
16803
+ return logger[fnLevel].bind(logger);
16804
+ }
16805
+ }
16806
+ const noopLogger = {
16807
+ error: noop,
16808
+ warn: noop,
16809
+ info: noop,
16810
+ debug: noop,
16811
+ };
16812
+ let cachedLoggers = /* @__PURE__ */ new WeakMap();
16813
+ function loggerFor(client) {
16814
+ var _a;
16815
+ const logger = client.logger;
16816
+ const logLevel = (_a = client.logLevel) !== null && _a !== void 0 ? _a : 'off';
16817
+ if (!logger) {
16818
+ return noopLogger;
16819
+ }
16820
+ const cachedLogger = cachedLoggers.get(logger);
16821
+ if (cachedLogger && cachedLogger[0] === logLevel) {
16822
+ return cachedLogger[1];
16823
+ }
16824
+ const levelLogger = {
16825
+ error: makeLogFn('error', logger, logLevel),
16826
+ warn: makeLogFn('warn', logger, logLevel),
16827
+ info: makeLogFn('info', logger, logLevel),
16828
+ debug: makeLogFn('debug', logger, logLevel),
16829
+ };
16830
+ cachedLoggers.set(logger, [logLevel, levelLogger]);
16831
+ return levelLogger;
16832
+ }
16833
+ const formatRequestDetails = (details) => {
16834
+ if (details.options) {
16835
+ details.options = Object.assign({}, details.options);
16836
+ delete details.options['headers']; // redundant + leaks internals
16837
+ }
16838
+ if (details.headers) {
16839
+ details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [
16840
+ name,
16841
+ (name.toLowerCase() === 'x-goog-api-key' ||
16842
+ name.toLowerCase() === 'authorization' ||
16843
+ name.toLowerCase() === 'cookie' ||
16844
+ name.toLowerCase() === 'set-cookie') ?
16845
+ '***'
16846
+ : value,
16847
+ ]));
16848
+ }
16849
+ if ('retryOfRequestLogID' in details) {
16850
+ if (details.retryOfRequestLogID) {
16851
+ details.retryOf = details.retryOfRequestLogID;
16852
+ }
16853
+ delete details.retryOfRequestLogID;
16854
+ }
16855
+ return details;
16856
+ };
16857
+
16858
+ /**
16859
+ * @license
16860
+ * Copyright 2025 Google LLC
16861
+ * SPDX-License-Identifier: Apache-2.0
16862
+ */
16863
+ class Stream {
16864
+ constructor(iterator, controller, client) {
16865
+ this.iterator = iterator;
16866
+ this.controller = controller;
16867
+ this.client = client;
16868
+ }
16869
+ static fromSSEResponse(response, controller, client) {
16870
+ let consumed = false;
16871
+ const logger = client ? loggerFor(client) : console;
16872
+ function iterator() {
16873
+ return __asyncGenerator(this, arguments, function* iterator_1() {
16874
+ var _a, e_1, _b, _c;
16875
+ if (consumed) {
16876
+ throw new GeminiNextGenAPIClientError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
16877
+ }
16878
+ consumed = true;
16879
+ let done = false;
16880
+ try {
16881
+ try {
16882
+ for (var _d = true, _e = __asyncValues(_iterSSEMessages(response, controller)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
16883
+ _c = _f.value;
16884
+ _d = false;
16885
+ const sse = _c;
16886
+ if (done)
16887
+ continue;
16888
+ if (sse.data.startsWith('[DONE]')) {
16889
+ done = true;
16890
+ continue;
16891
+ }
16892
+ else {
16893
+ try {
16894
+ // @ts-ignore
16895
+ yield yield __await(JSON.parse(sse.data));
16896
+ }
16897
+ catch (e) {
16898
+ logger.error(`Could not parse message into JSON:`, sse.data);
16899
+ logger.error(`From chunk:`, sse.raw);
16900
+ throw e;
16901
+ }
16902
+ }
16903
+ }
16904
+ }
16905
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
16906
+ finally {
16907
+ try {
16908
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
16909
+ }
16910
+ finally { if (e_1) throw e_1.error; }
16911
+ }
16912
+ done = true;
16913
+ }
16914
+ catch (e) {
16915
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
16916
+ if (isAbortError(e))
16917
+ return yield __await(void 0);
16918
+ throw e;
16919
+ }
16920
+ finally {
16921
+ // If the user `break`s, abort the ongoing request.
16922
+ if (!done)
16923
+ controller.abort();
16924
+ }
16925
+ });
16926
+ }
16927
+ return new Stream(iterator, controller, client);
16928
+ }
16929
+ /**
16930
+ * Generates a Stream from a newline-separated ReadableStream
16931
+ * where each item is a JSON value.
16932
+ */
16933
+ static fromReadableStream(readableStream, controller, client) {
16934
+ let consumed = false;
16935
+ function iterLines() {
16936
+ return __asyncGenerator(this, arguments, function* iterLines_1() {
16937
+ var _a, e_2, _b, _c;
16938
+ const lineDecoder = new LineDecoder();
16939
+ const iter = ReadableStreamToAsyncIterable(readableStream);
16940
+ try {
16941
+ for (var _d = true, iter_1 = __asyncValues(iter), iter_1_1; iter_1_1 = yield __await(iter_1.next()), _a = iter_1_1.done, !_a; _d = true) {
16942
+ _c = iter_1_1.value;
16943
+ _d = false;
16944
+ const chunk = _c;
16945
+ for (const line of lineDecoder.decode(chunk)) {
16946
+ yield yield __await(line);
16947
+ }
16948
+ }
16949
+ }
16950
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
16951
+ finally {
16952
+ try {
16953
+ if (!_d && !_a && (_b = iter_1.return)) yield __await(_b.call(iter_1));
16954
+ }
16955
+ finally { if (e_2) throw e_2.error; }
16956
+ }
16957
+ for (const line of lineDecoder.flush()) {
16958
+ yield yield __await(line);
16959
+ }
16960
+ });
16961
+ }
16962
+ function iterator() {
16963
+ return __asyncGenerator(this, arguments, function* iterator_2() {
16964
+ var _a, e_3, _b, _c;
16965
+ if (consumed) {
16966
+ throw new GeminiNextGenAPIClientError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
16967
+ }
16968
+ consumed = true;
16969
+ let done = false;
16970
+ try {
16971
+ try {
16972
+ for (var _d = true, _e = __asyncValues(iterLines()), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
16973
+ _c = _f.value;
16974
+ _d = false;
16975
+ const line = _c;
16976
+ if (done)
16977
+ continue;
16978
+ // @ts-ignore
16979
+ if (line)
16980
+ yield yield __await(JSON.parse(line));
16981
+ }
16982
+ }
16983
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
16984
+ finally {
16985
+ try {
16986
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
16987
+ }
16988
+ finally { if (e_3) throw e_3.error; }
16989
+ }
16990
+ done = true;
16991
+ }
16992
+ catch (e) {
16993
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
16994
+ if (isAbortError(e))
16995
+ return yield __await(void 0);
16996
+ throw e;
16997
+ }
16998
+ finally {
16999
+ // If the user `break`s, abort the ongoing request.
17000
+ if (!done)
17001
+ controller.abort();
17002
+ }
17003
+ });
17004
+ }
17005
+ return new Stream(iterator, controller, client);
17006
+ }
17007
+ [Symbol.asyncIterator]() {
17008
+ return this.iterator();
17009
+ }
17010
+ /**
17011
+ * Splits the stream into two streams which can be
17012
+ * independently read from at different speeds.
17013
+ */
17014
+ tee() {
17015
+ const left = [];
17016
+ const right = [];
17017
+ const iterator = this.iterator();
17018
+ const teeIterator = (queue) => {
17019
+ return {
17020
+ next: () => {
17021
+ if (queue.length === 0) {
17022
+ const result = iterator.next();
17023
+ left.push(result);
17024
+ right.push(result);
17025
+ }
17026
+ return queue.shift();
17027
+ },
17028
+ };
17029
+ };
17030
+ return [
17031
+ new Stream(() => teeIterator(left), this.controller, this.client),
17032
+ new Stream(() => teeIterator(right), this.controller, this.client),
17033
+ ];
17034
+ }
17035
+ /**
17036
+ * Converts this stream to a newline-separated ReadableStream of
17037
+ * JSON stringified values in the stream
17038
+ * which can be turned back into a Stream with `Stream.fromReadableStream()`.
17039
+ */
17040
+ toReadableStream() {
17041
+ const self = this;
17042
+ let iter;
17043
+ return makeReadableStream({
17044
+ async start() {
17045
+ iter = self[Symbol.asyncIterator]();
17046
+ },
17047
+ async pull(ctrl) {
17048
+ try {
17049
+ const { value, done } = await iter.next();
17050
+ if (done)
17051
+ return ctrl.close();
17052
+ const bytes = encodeUTF8(JSON.stringify(value) + '\n');
17053
+ ctrl.enqueue(bytes);
17054
+ }
17055
+ catch (err) {
17056
+ ctrl.error(err);
17057
+ }
17058
+ },
17059
+ async cancel() {
17060
+ var _a;
17061
+ await ((_a = iter.return) === null || _a === void 0 ? void 0 : _a.call(iter));
17062
+ },
17063
+ });
17064
+ }
17065
+ }
17066
+ function _iterSSEMessages(response, controller) {
17067
+ return __asyncGenerator(this, arguments, function* _iterSSEMessages_1() {
17068
+ var _a, e_4, _b, _c;
17069
+ if (!response.body) {
17070
+ controller.abort();
17071
+ if (typeof globalThis.navigator !== 'undefined' &&
17072
+ globalThis.navigator.product === 'ReactNative') {
17073
+ throw new GeminiNextGenAPIClientError(`The default react-native fetch implementation does not support streaming. Please use expo/fetch: https://docs.expo.dev/versions/latest/sdk/expo/#expofetch-api`);
17074
+ }
17075
+ throw new GeminiNextGenAPIClientError(`Attempted to iterate over a response with no body`);
17076
+ }
17077
+ const sseDecoder = new SSEDecoder();
17078
+ const lineDecoder = new LineDecoder();
17079
+ const iter = ReadableStreamToAsyncIterable(response.body);
17080
+ try {
17081
+ for (var _d = true, _e = __asyncValues(iterSSEChunks(iter)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
17082
+ _c = _f.value;
17083
+ _d = false;
17084
+ const sseChunk = _c;
17085
+ for (const line of lineDecoder.decode(sseChunk)) {
17086
+ const sse = sseDecoder.decode(line);
17087
+ if (sse)
17088
+ yield yield __await(sse);
17089
+ }
17090
+ }
17091
+ }
17092
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
17093
+ finally {
17094
+ try {
17095
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
17096
+ }
17097
+ finally { if (e_4) throw e_4.error; }
17098
+ }
17099
+ for (const line of lineDecoder.flush()) {
17100
+ const sse = sseDecoder.decode(line);
17101
+ if (sse)
17102
+ yield yield __await(sse);
17103
+ }
17104
+ });
17105
+ }
17106
+ /**
17107
+ * Given an async iterable iterator, iterates over it and yields full
17108
+ * SSE chunks, i.e. yields when a double new-line is encountered.
17109
+ */
17110
+ function iterSSEChunks(iterator) {
17111
+ return __asyncGenerator(this, arguments, function* iterSSEChunks_1() {
17112
+ var _a, e_5, _b, _c;
17113
+ let data = new Uint8Array();
17114
+ try {
17115
+ for (var _d = true, iterator_3 = __asyncValues(iterator), iterator_3_1; iterator_3_1 = yield __await(iterator_3.next()), _a = iterator_3_1.done, !_a; _d = true) {
17116
+ _c = iterator_3_1.value;
17117
+ _d = false;
17118
+ const chunk = _c;
17119
+ if (chunk == null) {
17120
+ continue;
17121
+ }
17122
+ const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
17123
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
17124
+ : chunk;
17125
+ let newData = new Uint8Array(data.length + binaryChunk.length);
17126
+ newData.set(data);
17127
+ newData.set(binaryChunk, data.length);
17128
+ data = newData;
17129
+ let patternIndex;
17130
+ while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
17131
+ yield yield __await(data.slice(0, patternIndex));
17132
+ data = data.slice(patternIndex);
17133
+ }
17134
+ }
17135
+ }
17136
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
17137
+ finally {
17138
+ try {
17139
+ if (!_d && !_a && (_b = iterator_3.return)) yield __await(_b.call(iterator_3));
17140
+ }
17141
+ finally { if (e_5) throw e_5.error; }
17142
+ }
17143
+ if (data.length > 0) {
17144
+ yield yield __await(data);
17145
+ }
17146
+ });
17147
+ }
17148
+ class SSEDecoder {
17149
+ constructor() {
17150
+ this.event = null;
17151
+ this.data = [];
17152
+ this.chunks = [];
17153
+ }
17154
+ decode(line) {
17155
+ if (line.endsWith('\r')) {
17156
+ line = line.substring(0, line.length - 1);
17157
+ }
17158
+ if (!line) {
17159
+ // empty line and we didn't previously encounter any messages
17160
+ if (!this.event && !this.data.length)
17161
+ return null;
17162
+ const sse = {
17163
+ event: this.event,
17164
+ data: this.data.join('\n'),
17165
+ raw: this.chunks,
17166
+ };
17167
+ this.event = null;
17168
+ this.data = [];
17169
+ this.chunks = [];
17170
+ return sse;
17171
+ }
17172
+ this.chunks.push(line);
17173
+ if (line.startsWith(':')) {
17174
+ return null;
17175
+ }
17176
+ let [fieldname, _, value] = partition(line, ':');
17177
+ if (value.startsWith(' ')) {
17178
+ value = value.substring(1);
17179
+ }
17180
+ if (fieldname === 'event') {
17181
+ this.event = value;
17182
+ }
17183
+ else if (fieldname === 'data') {
17184
+ this.data.push(value);
17185
+ }
17186
+ return null;
17187
+ }
17188
+ }
17189
+ function partition(str, delimiter) {
17190
+ const index = str.indexOf(delimiter);
17191
+ if (index !== -1) {
17192
+ return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
17193
+ }
17194
+ return [str, '', ''];
17195
+ }
17196
+
17197
+ /**
17198
+ * @license
17199
+ * Copyright 2025 Google LLC
17200
+ * SPDX-License-Identifier: Apache-2.0
17201
+ */
17202
+ async function defaultParseResponse(client, props) {
17203
+ const { response, requestLogID, retryOfRequestLogID, startTime } = props;
17204
+ const body = await (async () => {
17205
+ var _a;
17206
+ if (props.options.stream) {
17207
+ loggerFor(client).debug('response', response.status, response.url, response.headers, response.body);
17208
+ // Note: there is an invariant here that isn't represented in the type system
17209
+ // that if you set `stream: true` the response type must also be `Stream<T>`
17210
+ if (props.options.__streamClass) {
17211
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
17212
+ }
17213
+ return Stream.fromSSEResponse(response, props.controller, client);
17214
+ }
17215
+ // fetch refuses to read the body when the status code is 204.
17216
+ if (response.status === 204) {
17217
+ return null;
17218
+ }
17219
+ if (props.options.__binaryResponse) {
17220
+ return response;
17221
+ }
17222
+ const contentType = response.headers.get('content-type');
17223
+ const mediaType = (_a = contentType === null || contentType === void 0 ? void 0 : contentType.split(';')[0]) === null || _a === void 0 ? void 0 : _a.trim();
17224
+ const isJSON = (mediaType === null || mediaType === void 0 ? void 0 : mediaType.includes('application/json')) || (mediaType === null || mediaType === void 0 ? void 0 : mediaType.endsWith('+json'));
17225
+ if (isJSON) {
17226
+ const json = await response.json();
17227
+ return json;
17228
+ }
17229
+ const text = await response.text();
17230
+ return text;
17231
+ })();
17232
+ loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
17233
+ retryOfRequestLogID,
17234
+ url: response.url,
17235
+ status: response.status,
17236
+ body,
17237
+ durationMs: Date.now() - startTime,
17238
+ }));
17239
+ return body;
17240
+ }
17241
+
17242
+ /**
17243
+ * @license
17244
+ * Copyright 2025 Google LLC
17245
+ * SPDX-License-Identifier: Apache-2.0
17246
+ */
17247
+ /**
17248
+ * A subclass of `Promise` providing additional helper methods
17249
+ * for interacting with the SDK.
17250
+ */
17251
+ class APIPromise extends Promise {
17252
+ constructor(client, responsePromise, parseResponse = defaultParseResponse) {
17253
+ super((resolve) => {
17254
+ // this is maybe a bit weird but this has to be a no-op to not implicitly
17255
+ // parse the response body; instead .then, .catch, .finally are overridden
17256
+ // to parse the response
17257
+ resolve(null);
17258
+ });
17259
+ this.responsePromise = responsePromise;
17260
+ this.parseResponse = parseResponse;
17261
+ this.client = client;
17262
+ }
17263
+ _thenUnwrap(transform) {
17264
+ return new APIPromise(this.client, this.responsePromise, async (client, props) => transform(await this.parseResponse(client, props), props));
17265
+ }
17266
+ /**
17267
+ * Gets the raw `Response` instance instead of parsing the response
17268
+ * data.
17269
+ *
17270
+ * If you want to parse the response body but still get the `Response`
17271
+ * instance, you can use {@link withResponse()}.
17272
+ *
17273
+ * 👋 Getting the wrong TypeScript type for `Response`?
17274
+ * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
17275
+ * to your `tsconfig.json`.
17276
+ */
17277
+ asResponse() {
17278
+ return this.responsePromise.then((p) => p.response);
17279
+ }
17280
+ /**
17281
+ * Gets the parsed response data and the raw `Response` instance.
17282
+ *
17283
+ * If you just want to get the raw `Response` instance without parsing it,
17284
+ * you can use {@link asResponse()}.
17285
+ *
17286
+ * 👋 Getting the wrong TypeScript type for `Response`?
17287
+ * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
17288
+ * to your `tsconfig.json`.
17289
+ */
17290
+ async withResponse() {
17291
+ const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
17292
+ return { data, response };
17293
+ }
17294
+ parse() {
17295
+ if (!this.parsedPromise) {
17296
+ this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.client, data));
17297
+ }
17298
+ return this.parsedPromise;
17299
+ }
17300
+ then(onfulfilled, onrejected) {
17301
+ return this.parse().then(onfulfilled, onrejected);
17302
+ }
17303
+ catch(onrejected) {
17304
+ return this.parse().catch(onrejected);
17305
+ }
17306
+ finally(onfinally) {
17307
+ return this.parse().finally(onfinally);
17308
+ }
17309
+ }
17310
+
17311
+ /**
17312
+ * @license
17313
+ * Copyright 2025 Google LLC
17314
+ * SPDX-License-Identifier: Apache-2.0
17315
+ */
17316
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17317
+ const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
17318
+ function* iterateHeaders(headers) {
17319
+ if (!headers)
17320
+ return;
17321
+ if (brand_privateNullableHeaders in headers) {
17322
+ const { values, nulls } = headers;
17323
+ yield* values.entries();
17324
+ for (const name of nulls) {
17325
+ yield [name, null];
17326
+ }
17327
+ return;
17328
+ }
17329
+ let shouldClear = false;
17330
+ let iter;
17331
+ if (headers instanceof Headers) {
17332
+ iter = headers.entries();
17333
+ }
17334
+ else if (isReadonlyArray(headers)) {
17335
+ iter = headers;
17336
+ }
17337
+ else {
17338
+ shouldClear = true;
17339
+ iter = Object.entries(headers !== null && headers !== void 0 ? headers : {});
17340
+ }
17341
+ for (let row of iter) {
17342
+ const name = row[0];
17343
+ if (typeof name !== 'string')
17344
+ throw new TypeError('expected header name to be a string');
17345
+ const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
17346
+ let didClear = false;
17347
+ for (const value of values) {
17348
+ if (value === undefined)
17349
+ continue;
17350
+ // Objects keys always overwrite older headers, they never append.
17351
+ // Yield a null to clear the header before adding the new values.
17352
+ if (shouldClear && !didClear) {
17353
+ didClear = true;
17354
+ yield [name, null];
17355
+ }
17356
+ yield [name, value];
17357
+ }
17358
+ }
17359
+ }
17360
+ const buildHeaders = (newHeaders) => {
17361
+ const targetHeaders = new Headers();
17362
+ const nullHeaders = new Set();
17363
+ for (const headers of newHeaders) {
17364
+ const seenHeaders = new Set();
17365
+ for (const [name, value] of iterateHeaders(headers)) {
17366
+ const lowerName = name.toLowerCase();
17367
+ if (!seenHeaders.has(lowerName)) {
17368
+ targetHeaders.delete(name);
17369
+ seenHeaders.add(lowerName);
17370
+ }
17371
+ if (value === null) {
17372
+ targetHeaders.delete(name);
17373
+ nullHeaders.add(lowerName);
17374
+ }
17375
+ else {
17376
+ targetHeaders.append(name, value);
17377
+ nullHeaders.delete(lowerName);
17378
+ }
17379
+ }
17380
+ }
17381
+ return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
17382
+ };
17383
+
17384
+ /**
17385
+ * @license
17386
+ * Copyright 2025 Google LLC
17387
+ * SPDX-License-Identifier: Apache-2.0
17388
+ */
17389
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17390
+ /**
17391
+ * Read an environment variable.
17392
+ *
17393
+ * Trims beginning and trailing whitespace.
17394
+ *
17395
+ * Will return undefined if the environment variable doesn't exist or cannot be accessed.
17396
+ */
17397
+ const readEnv = (env) => {
17398
+ var _a, _b, _c, _d, _e, _f;
17399
+ if (typeof globalThis.process !== 'undefined') {
17400
+ return (_c = (_b = (_a = globalThis.process.env) === null || _a === void 0 ? void 0 : _a[env]) === null || _b === void 0 ? void 0 : _b.trim()) !== null && _c !== void 0 ? _c : undefined;
17401
+ }
17402
+ if (typeof globalThis.Deno !== 'undefined') {
17403
+ return (_f = (_e = (_d = globalThis.Deno.env) === null || _d === void 0 ? void 0 : _d.get) === null || _e === void 0 ? void 0 : _e.call(_d, env)) === null || _f === void 0 ? void 0 : _f.trim();
17404
+ }
17405
+ return undefined;
17406
+ };
17407
+
17408
+ /**
17409
+ * @license
17410
+ * Copyright 2025 Google LLC
17411
+ * SPDX-License-Identifier: Apache-2.0
17412
+ */
17413
+ var _a;
17414
+ /**
17415
+ * Base class for Gemini Next Gen API API clients.
17416
+ */
17417
+ class BaseGeminiNextGenAPIClient {
17418
+ /**
17419
+ * API Client for interfacing with the Gemini Next Gen API API.
17420
+ *
17421
+ * @param {string | null | undefined} [opts.apiKey=process.env['GEMINI_API_KEY'] ?? null]
17422
+ * @param {string | undefined} [opts.apiVersion=v1beta]
17423
+ * @param {string} [opts.baseURL=process.env['GEMINI_NEXT_GEN_API_BASE_URL'] ?? https://generativelanguage.googleapis.com] - Override the default base URL for the API.
17424
+ * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
17425
+ * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
17426
+ * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
17427
+ * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
17428
+ * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
17429
+ * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
17430
+ */
17431
+ constructor(_b) {
17432
+ var _c, _d, _e, _f, _g, _h, _j;
17433
+ var { baseURL = readEnv('GEMINI_NEXT_GEN_API_BASE_URL'), apiKey = (_c = readEnv('GEMINI_API_KEY')) !== null && _c !== void 0 ? _c : null, apiVersion = 'v1beta' } = _b, opts = __rest(_b, ["baseURL", "apiKey", "apiVersion"]);
17434
+ const options = Object.assign(Object.assign({ apiKey,
17435
+ apiVersion }, opts), { baseURL: baseURL || `https://generativelanguage.googleapis.com` });
17436
+ this.baseURL = options.baseURL;
17437
+ this.timeout = (_d = options.timeout) !== null && _d !== void 0 ? _d : BaseGeminiNextGenAPIClient.DEFAULT_TIMEOUT /* 1 minute */;
17438
+ this.logger = (_e = options.logger) !== null && _e !== void 0 ? _e : console;
17439
+ const defaultLogLevel = 'warn';
17440
+ // Set default logLevel early so that we can log a warning in parseLogLevel.
17441
+ this.logLevel = defaultLogLevel;
17442
+ this.logLevel =
17443
+ (_g = (_f = parseLogLevel(options.logLevel, 'ClientOptions.logLevel', this)) !== null && _f !== void 0 ? _f : parseLogLevel(readEnv('GEMINI_NEXT_GEN_API_LOG'), "process.env['GEMINI_NEXT_GEN_API_LOG']", this)) !== null && _g !== void 0 ? _g : defaultLogLevel;
17444
+ this.fetchOptions = options.fetchOptions;
17445
+ this.maxRetries = (_h = options.maxRetries) !== null && _h !== void 0 ? _h : 2;
17446
+ this.fetch = (_j = options.fetch) !== null && _j !== void 0 ? _j : getDefaultFetch();
17447
+ this.encoder = FallbackEncoder;
17448
+ this._options = options;
17449
+ this.apiKey = apiKey;
17450
+ this.apiVersion = apiVersion;
17451
+ this.clientAdapter = options.clientAdapter;
17452
+ }
17453
+ /**
17454
+ * Create a new client instance re-using the same options given to the current client with optional overriding.
17455
+ */
17456
+ withOptions(options) {
17457
+ const client = new this.constructor(Object.assign(Object.assign(Object.assign({}, this._options), { baseURL: this.baseURL, maxRetries: this.maxRetries, timeout: this.timeout, logger: this.logger, logLevel: this.logLevel, fetch: this.fetch, fetchOptions: this.fetchOptions, apiKey: this.apiKey, apiVersion: this.apiVersion }), options));
17458
+ return client;
17459
+ }
17460
+ /**
17461
+ * Check whether the base URL is set to its default.
17462
+ */
17463
+ baseURLOverridden() {
17464
+ return this.baseURL !== 'https://generativelanguage.googleapis.com';
17465
+ }
17466
+ defaultQuery() {
17467
+ return this._options.defaultQuery;
17468
+ }
17469
+ validateHeaders({ values, nulls }) {
17470
+ // The headers object handles case insensitivity.
17471
+ if (values.has('authorization') || values.has('x-goog-api-key')) {
17472
+ return;
17473
+ }
17474
+ if (this.apiKey && values.get('x-goog-api-key')) {
17475
+ return;
17476
+ }
17477
+ if (nulls.has('x-goog-api-key')) {
17478
+ return;
17479
+ }
17480
+ throw new Error('Could not resolve authentication method. Expected the apiKey to be set. Or for the "x-goog-api-key" headers to be explicitly omitted');
17481
+ }
17482
+ async authHeaders(opts) {
17483
+ const existingHeaders = buildHeaders([opts.headers]);
17484
+ if (existingHeaders.values.has('authorization') || existingHeaders.values.has('x-goog-api-key')) {
17485
+ return undefined;
17486
+ }
17487
+ if (this.apiKey) {
17488
+ return buildHeaders([{ 'x-goog-api-key': this.apiKey }]);
17489
+ }
17490
+ if (this.clientAdapter.isVertexAI()) {
17491
+ return buildHeaders([await this.clientAdapter.getAuthHeaders()]);
17492
+ }
17493
+ return undefined;
17494
+ }
17495
+ /**
17496
+ * Basic re-implementation of `qs.stringify` for primitive types.
17497
+ */
17498
+ stringifyQuery(query) {
17499
+ return Object.entries(query)
17500
+ .filter(([_, value]) => typeof value !== 'undefined')
17501
+ .map(([key, value]) => {
17502
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
17503
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
17504
+ }
17505
+ if (value === null) {
17506
+ return `${encodeURIComponent(key)}=`;
17507
+ }
17508
+ throw new GeminiNextGenAPIClientError(`Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`);
17509
+ })
17510
+ .join('&');
17511
+ }
17512
+ getUserAgent() {
17513
+ return `${this.constructor.name}/JS ${VERSION}`;
17514
+ }
17515
+ defaultIdempotencyKey() {
17516
+ return `stainless-node-retry-${uuid4()}`;
17517
+ }
17518
+ makeStatusError(status, error, message, headers) {
17519
+ return APIError.generate(status, error, message, headers);
17520
+ }
17521
+ buildURL(path, query, defaultBaseURL) {
17522
+ const baseURL = (!this.baseURLOverridden() && defaultBaseURL) || this.baseURL;
17523
+ const url = isAbsoluteURL(path) ?
17524
+ new URL(path)
17525
+ : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
17526
+ const defaultQuery = this.defaultQuery();
17527
+ if (!isEmptyObj(defaultQuery)) {
17528
+ query = Object.assign(Object.assign({}, defaultQuery), query);
17529
+ }
17530
+ if (typeof query === 'object' && query && !Array.isArray(query)) {
17531
+ url.search = this.stringifyQuery(query);
17532
+ }
17533
+ return url.toString();
17534
+ }
17535
+ /**
17536
+ * Used as a callback for mutating the given `FinalRequestOptions` object.
17537
+
17538
+ */
17539
+ async prepareOptions(options) {
17540
+ if (this.clientAdapter &&
17541
+ this.clientAdapter.isVertexAI() &&
17542
+ !options.path.startsWith(`/${this.apiVersion}/projects/`)) {
17543
+ const oldPath = options.path.slice(this.apiVersion.length + 1);
17544
+ options.path = `/${this.apiVersion}/projects/${this.clientAdapter.getProject()}/locations/${this.clientAdapter.getLocation()}${oldPath}`;
17545
+ }
17546
+ }
17547
+ /**
17548
+ * Used as a callback for mutating the given `RequestInit` object.
17549
+ *
17550
+ * This is useful for cases where you want to add certain headers based off of
17551
+ * the request properties, e.g. `method` or `url`.
17552
+ */
17553
+ async prepareRequest(request, { url, options }) { }
17554
+ get(path, opts) {
17555
+ return this.methodRequest('get', path, opts);
17556
+ }
17557
+ post(path, opts) {
17558
+ return this.methodRequest('post', path, opts);
17559
+ }
17560
+ patch(path, opts) {
17561
+ return this.methodRequest('patch', path, opts);
17562
+ }
17563
+ put(path, opts) {
17564
+ return this.methodRequest('put', path, opts);
17565
+ }
17566
+ delete(path, opts) {
17567
+ return this.methodRequest('delete', path, opts);
17568
+ }
17569
+ methodRequest(method, path, opts) {
17570
+ return this.request(Promise.resolve(opts).then((opts) => {
17571
+ return Object.assign({ method, path }, opts);
17572
+ }));
17573
+ }
17574
+ request(options, remainingRetries = null) {
17575
+ return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
17576
+ }
17577
+ async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
17578
+ var _b, _c, _d;
17579
+ const options = await optionsInput;
17580
+ const maxRetries = (_b = options.maxRetries) !== null && _b !== void 0 ? _b : this.maxRetries;
17581
+ if (retriesRemaining == null) {
17582
+ retriesRemaining = maxRetries;
17583
+ }
17584
+ await this.prepareOptions(options);
17585
+ const { req, url, timeout } = await this.buildRequest(options, {
17586
+ retryCount: maxRetries - retriesRemaining,
17587
+ });
17588
+ await this.prepareRequest(req, { url, options });
17589
+ /** Not an API request ID, just for correlating local log entries. */
17590
+ const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
17591
+ const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
17592
+ const startTime = Date.now();
17593
+ loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
17594
+ retryOfRequestLogID,
17595
+ method: options.method,
17596
+ url,
17597
+ options,
17598
+ headers: req.headers,
17599
+ }));
17600
+ if ((_c = options.signal) === null || _c === void 0 ? void 0 : _c.aborted) {
17601
+ throw new APIUserAbortError();
17602
+ }
17603
+ const controller = new AbortController();
17604
+ const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
17605
+ const headersTime = Date.now();
17606
+ if (response instanceof globalThis.Error) {
17607
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
17608
+ if ((_d = options.signal) === null || _d === void 0 ? void 0 : _d.aborted) {
17609
+ throw new APIUserAbortError();
17610
+ }
17611
+ // detect native connection timeout errors
17612
+ // deno throws "TypeError: error sending request for url (https://example/): client error (Connect): tcp connect error: Operation timed out (os error 60): Operation timed out (os error 60)"
17613
+ // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
17614
+ // others do not provide enough information to distinguish timeouts from other connection errors
17615
+ const isTimeout = isAbortError(response) ||
17616
+ /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
17617
+ if (retriesRemaining) {
17618
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
17619
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
17620
+ retryOfRequestLogID,
17621
+ url,
17622
+ durationMs: headersTime - startTime,
17623
+ message: response.message,
17624
+ }));
17625
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID !== null && retryOfRequestLogID !== void 0 ? retryOfRequestLogID : requestLogID);
17626
+ }
17627
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
17628
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
17629
+ retryOfRequestLogID,
17630
+ url,
17631
+ durationMs: headersTime - startTime,
17632
+ message: response.message,
17633
+ }));
17634
+ if (isTimeout) {
17635
+ throw new APIConnectionTimeoutError();
17636
+ }
17637
+ throw new APIConnectionError({ cause: response });
17638
+ }
17639
+ const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
17640
+ if (!response.ok) {
17641
+ const shouldRetry = await this.shouldRetry(response);
17642
+ if (retriesRemaining && shouldRetry) {
17643
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
17644
+ // We don't need the body of this response.
17645
+ await CancelReadableStream(response.body);
17646
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
17647
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
17648
+ retryOfRequestLogID,
17649
+ url: response.url,
17650
+ status: response.status,
17651
+ headers: response.headers,
17652
+ durationMs: headersTime - startTime,
17653
+ }));
17654
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID !== null && retryOfRequestLogID !== void 0 ? retryOfRequestLogID : requestLogID, response.headers);
17655
+ }
17656
+ const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
17657
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
17658
+ const errText = await response.text().catch((err) => castToError(err).message);
17659
+ const errJSON = safeJSON(errText);
17660
+ const errMessage = errJSON ? undefined : errText;
17661
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
17662
+ retryOfRequestLogID,
17663
+ url: response.url,
17664
+ status: response.status,
17665
+ headers: response.headers,
17666
+ message: errMessage,
17667
+ durationMs: Date.now() - startTime,
17668
+ }));
17669
+ // @ts-ignore
17670
+ const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
17671
+ throw err;
17672
+ }
17673
+ loggerFor(this).info(responseInfo);
17674
+ loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
17675
+ retryOfRequestLogID,
17676
+ url: response.url,
17677
+ status: response.status,
17678
+ headers: response.headers,
17679
+ durationMs: headersTime - startTime,
17680
+ }));
17681
+ return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
17682
+ }
17683
+ async fetchWithTimeout(url, init, ms, controller) {
17684
+ const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
17685
+ if (signal)
17686
+ signal.addEventListener('abort', () => controller.abort());
17687
+ const timeout = setTimeout(() => controller.abort(), ms);
17688
+ const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
17689
+ (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
17690
+ const fetchOptions = Object.assign(Object.assign(Object.assign({ signal: controller.signal }, (isReadableBody ? { duplex: 'half' } : {})), { method: 'GET' }), options);
17691
+ if (method) {
17692
+ // Custom methods like 'patch' need to be uppercased
17693
+ // See https://github.com/nodejs/undici/issues/2294
17694
+ fetchOptions.method = method.toUpperCase();
17695
+ }
17696
+ try {
17697
+ // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
17698
+ return await this.fetch.call(undefined, url, fetchOptions);
17699
+ }
17700
+ finally {
17701
+ clearTimeout(timeout);
17702
+ }
17703
+ }
17704
+ async shouldRetry(response) {
17705
+ // Note this is not a standard header.
17706
+ const shouldRetryHeader = response.headers.get('x-should-retry');
17707
+ // If the server explicitly says whether or not to retry, obey.
17708
+ if (shouldRetryHeader === 'true')
17709
+ return true;
17710
+ if (shouldRetryHeader === 'false')
17711
+ return false;
17712
+ // Retry on request timeouts.
17713
+ if (response.status === 408)
17714
+ return true;
17715
+ // Retry on lock timeouts.
17716
+ if (response.status === 409)
17717
+ return true;
17718
+ // Retry on rate limits.
17719
+ if (response.status === 429)
17720
+ return true;
17721
+ // Retry internal errors.
17722
+ if (response.status >= 500)
17723
+ return true;
17724
+ return false;
17725
+ }
17726
+ async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
17727
+ var _b;
17728
+ let timeoutMillis;
17729
+ // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
17730
+ const retryAfterMillisHeader = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders.get('retry-after-ms');
17731
+ if (retryAfterMillisHeader) {
17732
+ const timeoutMs = parseFloat(retryAfterMillisHeader);
17733
+ if (!Number.isNaN(timeoutMs)) {
17734
+ timeoutMillis = timeoutMs;
17735
+ }
17736
+ }
17737
+ // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
17738
+ const retryAfterHeader = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders.get('retry-after');
17739
+ if (retryAfterHeader && !timeoutMillis) {
17740
+ const timeoutSeconds = parseFloat(retryAfterHeader);
17741
+ if (!Number.isNaN(timeoutSeconds)) {
17742
+ timeoutMillis = timeoutSeconds * 1000;
17743
+ }
17744
+ else {
17745
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
17746
+ }
17747
+ }
17748
+ // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
17749
+ // just do what it says, but otherwise calculate a default
17750
+ if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
17751
+ const maxRetries = (_b = options.maxRetries) !== null && _b !== void 0 ? _b : this.maxRetries;
17752
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
17753
+ }
17754
+ await sleep$1(timeoutMillis);
17755
+ return this.makeRequest(options, retriesRemaining - 1, requestLogID);
17756
+ }
17757
+ calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
17758
+ const initialRetryDelay = 0.5;
17759
+ const maxRetryDelay = 8.0;
17760
+ const numRetries = maxRetries - retriesRemaining;
17761
+ // Apply exponential backoff, but not more than the max.
17762
+ const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
17763
+ // Apply some jitter, take up to at most 25 percent of the retry time.
17764
+ const jitter = 1 - Math.random() * 0.25;
17765
+ return sleepSeconds * jitter * 1000;
17766
+ }
17767
+ async buildRequest(inputOptions, { retryCount = 0 } = {}) {
17768
+ var _b, _c, _d;
17769
+ const options = Object.assign({}, inputOptions);
17770
+ const { method, path, query, defaultBaseURL } = options;
17771
+ const url = this.buildURL(path, query, defaultBaseURL);
17772
+ if ('timeout' in options)
17773
+ validatePositiveInteger('timeout', options.timeout);
17774
+ options.timeout = (_b = options.timeout) !== null && _b !== void 0 ? _b : this.timeout;
17775
+ const { bodyHeaders, body } = this.buildBody({ options });
17776
+ const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
17777
+ const req = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ method, headers: reqHeaders }, (options.signal && { signal: options.signal })), (globalThis.ReadableStream &&
17778
+ body instanceof globalThis.ReadableStream && { duplex: 'half' })), (body && { body })), ((_c = this.fetchOptions) !== null && _c !== void 0 ? _c : {})), ((_d = options.fetchOptions) !== null && _d !== void 0 ? _d : {}));
17779
+ return { req, url, timeout: options.timeout };
17780
+ }
17781
+ async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
17782
+ let idempotencyHeaders = {};
17783
+ if (this.idempotencyHeader && method !== 'get') {
17784
+ if (!options.idempotencyKey)
17785
+ options.idempotencyKey = this.defaultIdempotencyKey();
17786
+ idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
17787
+ }
17788
+ const authHeaders = await this.authHeaders(options);
17789
+ let headers = buildHeaders([
17790
+ idempotencyHeaders,
17791
+ Object.assign(Object.assign({ Accept: 'application/json', 'User-Agent': this.getUserAgent(), 'X-Stainless-Retry-Count': String(retryCount) }, (options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {})), getPlatformHeaders()),
17792
+ this._options.defaultHeaders,
17793
+ bodyHeaders,
17794
+ options.headers,
17795
+ authHeaders,
17796
+ ]);
17797
+ this.validateHeaders(headers);
17798
+ return headers.values;
17799
+ }
17800
+ buildBody({ options: { body, headers: rawHeaders } }) {
17801
+ if (!body) {
17802
+ return { bodyHeaders: undefined, body: undefined };
17803
+ }
17804
+ const headers = buildHeaders([rawHeaders]);
17805
+ if (
17806
+ // Pass raw type verbatim
17807
+ ArrayBuffer.isView(body) ||
17808
+ body instanceof ArrayBuffer ||
17809
+ body instanceof DataView ||
17810
+ (typeof body === 'string' &&
17811
+ // Preserve legacy string encoding behavior for now
17812
+ headers.values.has('content-type')) ||
17813
+ // `Blob` is superset of `File`
17814
+ (globalThis.Blob && body instanceof globalThis.Blob) ||
17815
+ // `FormData` -> `multipart/form-data`
17816
+ body instanceof FormData ||
17817
+ // `URLSearchParams` -> `application/x-www-form-urlencoded`
17818
+ body instanceof URLSearchParams ||
17819
+ // Send chunked stream (each chunk has own `length`)
17820
+ (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
17821
+ return { bodyHeaders: undefined, body: body };
17822
+ }
17823
+ else if (typeof body === 'object' &&
17824
+ (Symbol.asyncIterator in body ||
17825
+ (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
17826
+ return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
17827
+ }
17828
+ else {
17829
+ return this.encoder({ body, headers });
17830
+ }
17831
+ }
17832
+ }
17833
+ BaseGeminiNextGenAPIClient.DEFAULT_TIMEOUT = 60000; // 1 minute
17834
+ /**
17835
+ * API Client for interfacing with the Gemini Next Gen API API.
17836
+ */
17837
+ class GeminiNextGenAPIClient extends BaseGeminiNextGenAPIClient {
17838
+ constructor() {
17839
+ super(...arguments);
17840
+ this.interactions = new Interactions(this);
17841
+ }
17842
+ }
17843
+ _a = GeminiNextGenAPIClient;
17844
+ GeminiNextGenAPIClient.GeminiNextGenAPIClient = _a;
17845
+ GeminiNextGenAPIClient.GeminiNextGenAPIClientError = GeminiNextGenAPIClientError;
17846
+ GeminiNextGenAPIClient.APIError = APIError;
17847
+ GeminiNextGenAPIClient.APIConnectionError = APIConnectionError;
17848
+ GeminiNextGenAPIClient.APIConnectionTimeoutError = APIConnectionTimeoutError;
17849
+ GeminiNextGenAPIClient.APIUserAbortError = APIUserAbortError;
17850
+ GeminiNextGenAPIClient.NotFoundError = NotFoundError;
17851
+ GeminiNextGenAPIClient.ConflictError = ConflictError;
17852
+ GeminiNextGenAPIClient.RateLimitError = RateLimitError;
17853
+ GeminiNextGenAPIClient.BadRequestError = BadRequestError;
17854
+ GeminiNextGenAPIClient.AuthenticationError = AuthenticationError;
17855
+ GeminiNextGenAPIClient.InternalServerError = InternalServerError;
17856
+ GeminiNextGenAPIClient.PermissionDeniedError = PermissionDeniedError;
17857
+ GeminiNextGenAPIClient.UnprocessableEntityError = UnprocessableEntityError;
17858
+ GeminiNextGenAPIClient.toFile = toFile;
17859
+ GeminiNextGenAPIClient.Interactions = Interactions;
17860
+
17861
+ /**
17862
+ * @license
17863
+ * Copyright 2025 Google LLC
17864
+ * SPDX-License-Identifier: Apache-2.0
17865
+ */
17866
+ const GOOGLE_API_KEY_HEADER = 'x-goog-api-key';
17867
+ const REQUIRED_VERTEX_AI_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
17868
+ class NodeAuth {
17869
+ constructor(opts) {
17870
+ if (opts.apiKey !== undefined) {
17871
+ this.apiKey = opts.apiKey;
17872
+ return;
17873
+ }
17874
+ const vertexAuthOptions = buildGoogleAuthOptions(opts.googleAuthOptions);
17875
+ this.googleAuth = new GoogleAuth(vertexAuthOptions);
17876
+ }
17877
+ async addAuthHeaders(headers, url) {
17878
+ if (this.apiKey !== undefined) {
17879
+ if (this.apiKey.startsWith('auth_tokens/')) {
17880
+ throw new Error('Ephemeral tokens are only supported by the live API.');
17881
+ }
17882
+ this.addKeyHeader(headers);
17883
+ return;
17884
+ }
17885
+ return this.addGoogleAuthHeaders(headers, url);
17886
+ }
17887
+ addKeyHeader(headers) {
17888
+ if (headers.get(GOOGLE_API_KEY_HEADER) !== null) {
17889
+ return;
17890
+ }
17891
+ if (this.apiKey === undefined) {
17892
+ // This should never happen, this method is only called
17893
+ // when apiKey is set.
17894
+ throw new Error('Trying to set API key header but apiKey is not set');
17895
+ }
17896
+ headers.append(GOOGLE_API_KEY_HEADER, this.apiKey);
17897
+ }
17898
+ async addGoogleAuthHeaders(headers, url) {
17899
+ if (this.googleAuth === undefined) {
17900
+ // This should never happen, addGoogleAuthHeaders should only be
17901
+ // called when there is no apiKey set and in these cases googleAuth
17902
+ // is set.
17903
+ throw new Error('Trying to set google-auth headers but googleAuth is unset');
17904
+ }
17905
+ const authHeaders = await this.googleAuth.getRequestHeaders(url);
17906
+ for (const [key, value] of authHeaders) {
17907
+ if (headers.get(key) !== null) {
17908
+ continue;
17909
+ }
17910
+ headers.append(key, value);
17911
+ }
17912
+ }
17913
+ }
17914
+ function buildGoogleAuthOptions(googleAuthOptions) {
17915
+ let authOptions;
17916
+ if (!googleAuthOptions) {
17917
+ authOptions = {
17918
+ scopes: [REQUIRED_VERTEX_AI_SCOPE],
17919
+ };
17920
+ return authOptions;
17921
+ }
17922
+ else {
17923
+ authOptions = googleAuthOptions;
17924
+ if (!authOptions.scopes) {
17925
+ authOptions.scopes = [REQUIRED_VERTEX_AI_SCOPE];
17926
+ return authOptions;
17927
+ }
17928
+ else if ((typeof authOptions.scopes === 'string' &&
17929
+ authOptions.scopes !== REQUIRED_VERTEX_AI_SCOPE) ||
17930
+ (Array.isArray(authOptions.scopes) &&
17931
+ authOptions.scopes.indexOf(REQUIRED_VERTEX_AI_SCOPE) < 0)) {
17932
+ throw new Error(`Invalid auth scopes. Scopes must include: ${REQUIRED_VERTEX_AI_SCOPE}`);
17933
+ }
17934
+ return authOptions;
17935
+ }
17936
+ }
17937
+
17938
+ /**
17939
+ * @license
17940
+ * Copyright 2025 Google LLC
17941
+ * SPDX-License-Identifier: Apache-2.0
17942
+ */
17943
+ class NodeDownloader {
17944
+ async download(params, apiClient) {
17945
+ if (params.downloadPath) {
17946
+ const response = await downloadFile(params, apiClient);
17947
+ if (response instanceof HttpResponse) {
17948
+ const writer = createWriteStream(params.downloadPath);
17949
+ const body = Readable.fromWeb(response.responseInternal.body);
17950
+ body.pipe(writer);
17951
+ await finished(writer);
17952
+ }
17953
+ else {
17954
+ try {
17955
+ await writeFile(params.downloadPath, response, {
17956
+ encoding: 'base64',
17957
+ });
17958
+ }
17959
+ catch (error) {
17960
+ throw new Error(`Failed to write file to ${params.downloadPath}: ${error}`);
17961
+ }
17962
+ }
17963
+ }
17964
+ }
17965
+ }
17966
+ async function downloadFile(params, apiClient) {
17967
+ var _a, _b, _c;
17968
+ const name = tFileName(params.file);
17969
+ if (name !== undefined) {
17970
+ return await apiClient.request({
17971
+ path: `files/${name}:download`,
17972
+ httpMethod: 'GET',
17973
+ queryParams: {
17974
+ 'alt': 'media',
17975
+ },
17976
+ httpOptions: (_a = params.config) === null || _a === void 0 ? void 0 : _a.httpOptions,
17977
+ abortSignal: (_b = params.config) === null || _b === void 0 ? void 0 : _b.abortSignal,
17978
+ });
17979
+ }
17980
+ else if (isGeneratedVideo(params.file)) {
17981
+ const videoBytes = (_c = params.file.video) === null || _c === void 0 ? void 0 : _c.videoBytes;
17982
+ if (typeof videoBytes === 'string') {
17983
+ return videoBytes;
17984
+ }
17985
+ else {
17986
+ throw new Error('Failed to download generated video, Uri or videoBytes not found.');
17987
+ }
17988
+ }
17989
+ else if (isVideo(params.file)) {
17990
+ const videoBytes = params.file.videoBytes;
17991
+ if (typeof videoBytes === 'string') {
17992
+ return videoBytes;
17993
+ }
17994
+ else {
17995
+ throw new Error('Failed to download video, Uri or videoBytes not found.');
17996
+ }
17997
+ }
17998
+ else {
17999
+ throw new Error('Unsupported file type');
18000
+ }
18001
+ }
18002
+
18003
+ /**
18004
+ * @license
18005
+ * Copyright 2025 Google LLC
18006
+ * SPDX-License-Identifier: Apache-2.0
18007
+ */
18008
+ class NodeWebSocketFactory {
18009
+ create(url, headers, callbacks) {
18010
+ return new NodeWebSocket(url, headers, callbacks);
18011
+ }
18012
+ }
18013
+ class NodeWebSocket {
18014
+ constructor(url, headers, callbacks) {
18015
+ this.url = url;
18016
+ this.headers = headers;
18017
+ this.callbacks = callbacks;
18018
+ }
18019
+ connect() {
18020
+ this.ws = new NodeWs.WebSocket(this.url, { headers: this.headers });
18021
+ this.ws.onopen = this.callbacks.onopen;
18022
+ this.ws.onerror = this.callbacks.onerror;
18023
+ this.ws.onclose = this.callbacks.onclose;
18024
+ this.ws.onmessage = this.callbacks.onmessage;
18025
+ }
18026
+ send(message) {
18027
+ if (this.ws === undefined) {
18028
+ throw new Error('WebSocket is not connected');
18029
+ }
18030
+ this.ws.send(message);
18031
+ }
18032
+ close() {
18033
+ if (this.ws === undefined) {
18034
+ throw new Error('WebSocket is not connected');
18035
+ }
18036
+ this.ws.close();
18037
+ }
18038
+ }
18039
+
18040
+ /**
18041
+ * @license
18042
+ * Copyright 2025 Google LLC
18043
+ * SPDX-License-Identifier: Apache-2.0
18044
+ */
18045
+ // Code generated by the Google Gen AI SDK generator DO NOT EDIT.
18046
+ function cancelTuningJobParametersToMldev(fromObject, _rootObject) {
18047
+ const toObject = {};
18048
+ const fromName = getValueByPath(fromObject, ['name']);
18049
+ if (fromName != null) {
18050
+ setValueByPath(toObject, ['_url', 'name'], fromName);
18051
+ }
18052
+ return toObject;
18053
+ }
18054
+ function cancelTuningJobParametersToVertex(fromObject, _rootObject) {
18055
+ const toObject = {};
18056
+ const fromName = getValueByPath(fromObject, ['name']);
18057
+ if (fromName != null) {
18058
+ setValueByPath(toObject, ['_url', 'name'], fromName);
18059
+ }
18060
+ return toObject;
16028
18061
  }
16029
18062
  function cancelTuningJobResponseFromMldev(fromObject, _rootObject) {
16030
18063
  const toObject = {};
@@ -17309,7 +19342,7 @@ class NodeUploader {
17309
19342
  let response = new HttpResponse(new Response());
17310
19343
  let uploadCommand = 'upload';
17311
19344
  let fileHandle;
17312
- const fileName = path.basename(file);
19345
+ const fileName = path$1.basename(file);
17313
19346
  try {
17314
19347
  fileHandle = await fs.open(file, 'r');
17315
19348
  if (!fileHandle) {
@@ -17420,6 +19453,27 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
17420
19453
  *
17421
19454
  */
17422
19455
  class GoogleGenAI {
19456
+ get interactions() {
19457
+ if (this._interactions !== undefined) {
19458
+ return this._interactions;
19459
+ }
19460
+ console.warn('GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions.');
19461
+ const httpOpts = this.httpOptions;
19462
+ // Unsupported Options Warnings
19463
+ if (httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.extraBody) {
19464
+ console.warn('GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.');
19465
+ }
19466
+ const nextGenClient = new GeminiNextGenAPIClient({
19467
+ baseURL: this.apiClient.getBaseUrl(),
19468
+ apiKey: this.apiKey,
19469
+ apiVersion: this.apiClient.getApiVersion(),
19470
+ clientAdapter: this.apiClient,
19471
+ defaultHeaders: this.apiClient.getDefaultHeaders(),
19472
+ timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19473
+ });
19474
+ this._interactions = nextGenClient.interactions;
19475
+ return this._interactions;
19476
+ }
17423
19477
  constructor(options) {
17424
19478
  var _a, _b, _c, _d, _e, _f;
17425
19479
  // Validate explicitly set initializer values.
@@ -17527,5 +19581,5 @@ function getApiKeyFromEnv() {
17527
19581
  return envGoogleApiKey || envGeminiApiKey || undefined;
17528
19582
  }
17529
19583
 
17530
- export { ActivityHandling, AdapterSize, ApiError, ApiSpec, AuthType, Batches, Behavior, BlockedReason, Caches, CancelTuningJobResponse, Chat, Chats, ComputeTokensResponse, ContentReferenceImage, ControlReferenceImage, ControlReferenceType, CountTokensResponse, CreateFileResponse, DeleteCachedContentResponse, DeleteFileResponse, DeleteModelResponse, DocumentState, DynamicRetrievalConfigMode, EditImageResponse, EditMode, EmbedContentResponse, EndSensitivity, Environment, FeatureSelectionPreference, FileSource, FileState, Files, FinishReason, FunctionCallingConfigMode, FunctionResponse, FunctionResponseBlob, FunctionResponseFileData, FunctionResponsePart, FunctionResponseScheduling, GenerateContentResponse, GenerateContentResponsePromptFeedback, GenerateContentResponseUsageMetadata, GenerateImagesResponse, GenerateVideosOperation, GenerateVideosResponse, GoogleGenAI, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, HttpElementLocation, HttpResponse, ImagePromptLanguage, ImportFileOperation, ImportFileResponse, InlinedEmbedContentResponse, InlinedResponse, JobState, Language, ListBatchJobsResponse, ListCachedContentsResponse, ListDocumentsResponse, ListFileSearchStoresResponse, ListFilesResponse, ListModelsResponse, ListTuningJobsResponse, Live, LiveClientToolResponse, LiveMusicPlaybackControl, LiveMusicServerMessage, LiveSendToolResponseParameters, LiveServerMessage, MaskReferenceImage, MaskReferenceMode, MediaModality, MediaResolution, Modality, Mode, Models, MusicGenerationMode, Operations, Outcome, PagedItem, Pager, PartMediaResolutionLevel, PersonGeneration, PhishBlockThreshold, RawReferenceImage, RecontextImageResponse, ReplayResponse, SafetyFilterLevel, Scale, SegmentImageResponse, SegmentMode, Session, SingleEmbedContentResponse, StartSensitivity, StyleReferenceImage, SubjectReferenceImage, SubjectReferenceType, ThinkingLevel, Tokens, TrafficType, TuningMethod, TuningMode, TuningTask, TurnCompleteReason, TurnCoverage, Type, UploadToFileSearchStoreOperation, UploadToFileSearchStoreResponse, UploadToFileSearchStoreResumableResponse, UpscaleImageResponse, UrlRetrievalStatus, VideoCompressionQuality, VideoGenerationMaskMode, VideoGenerationReferenceType, createFunctionResponsePartFromBase64, createFunctionResponsePartFromUri, createModelContent, createPartFromBase64, createPartFromCodeExecutionResult, createPartFromExecutableCode, createPartFromFunctionCall, createPartFromFunctionResponse, createPartFromText, createPartFromUri, createUserContent, mcpToTool, setDefaultBaseUrls };
19584
+ export { ActivityHandling, AdapterSize, ApiError, ApiSpec, AuthType, Batches, Behavior, BlockedReason, Caches, CancelTuningJobResponse, Chat, Chats, ComputeTokensResponse, ContentReferenceImage, ControlReferenceImage, ControlReferenceType, CountTokensResponse, CreateFileResponse, DeleteCachedContentResponse, DeleteFileResponse, DeleteModelResponse, DocumentState, DynamicRetrievalConfigMode, EditImageResponse, EditMode, EmbedContentResponse, EndSensitivity, Environment, FeatureSelectionPreference, FileSource, FileState, Files, FinishReason, FunctionCallingConfigMode, FunctionResponse, FunctionResponseBlob, FunctionResponseFileData, FunctionResponsePart, FunctionResponseScheduling, GenerateContentResponse, GenerateContentResponsePromptFeedback, GenerateContentResponseUsageMetadata, GenerateImagesResponse, GenerateVideosOperation, GenerateVideosResponse, GoogleGenAI, HarmBlockMethod, HarmBlockThreshold, HarmCategory, HarmProbability, HarmSeverity, HttpElementLocation, HttpResponse, ImagePromptLanguage, ImportFileOperation, ImportFileResponse, InlinedEmbedContentResponse, InlinedResponse, JobState, Language, ListBatchJobsResponse, ListCachedContentsResponse, ListDocumentsResponse, ListFileSearchStoresResponse, ListFilesResponse, ListModelsResponse, ListTuningJobsResponse, Live, LiveClientToolResponse, LiveMusicPlaybackControl, LiveMusicServerMessage, LiveSendToolResponseParameters, LiveServerMessage, MaskReferenceImage, MaskReferenceMode, MediaModality, MediaResolution, Modality, Mode, Models, MusicGenerationMode, Operations, Outcome, PagedItem, Pager, PartMediaResolutionLevel, PersonGeneration, PhishBlockThreshold, RawReferenceImage, RecontextImageResponse, ReplayResponse, SafetyFilterLevel, Scale, SegmentImageResponse, SegmentMode, Session, SingleEmbedContentResponse, StartSensitivity, StyleReferenceImage, SubjectReferenceImage, SubjectReferenceType, ThinkingLevel, Tokens, TrafficType, TuningMethod, TuningMode, TuningTask, TurnCompleteReason, TurnCoverage, Type, UploadToFileSearchStoreOperation, UploadToFileSearchStoreResponse, UploadToFileSearchStoreResumableResponse, UpscaleImageResponse, UrlRetrievalStatus, VadSignalType, VideoCompressionQuality, VideoGenerationMaskMode, VideoGenerationReferenceType, createFunctionResponsePartFromBase64, createFunctionResponsePartFromUri, createModelContent, createPartFromBase64, createPartFromCodeExecutionResult, createPartFromExecutableCode, createPartFromFunctionCall, createPartFromFunctionResponse, createPartFromText, createPartFromUri, createUserContent, mcpToTool, setDefaultBaseUrls };
17531
19585
  //# sourceMappingURL=index.mjs.map