@google/genai 1.31.0 → 1.33.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
@@ -968,6 +968,14 @@ var FinishReason;
968
968
  * The model was expected to generate an image, but none was generated.
969
969
  */
970
970
  FinishReason["NO_IMAGE"] = "NO_IMAGE";
971
+ /**
972
+ * Image generation stopped because the generated image may be a recitation from a source.
973
+ */
974
+ FinishReason["IMAGE_RECITATION"] = "IMAGE_RECITATION";
975
+ /**
976
+ * Image generation stopped for a reason not otherwise specified.
977
+ */
978
+ FinishReason["IMAGE_OTHER"] = "IMAGE_OTHER";
971
979
  })(FinishReason || (FinishReason = {}));
972
980
  /** Output only. Harm probability levels in the content. */
973
981
  var HarmProbability;
@@ -1590,6 +1598,22 @@ var MediaModality;
1590
1598
  */
1591
1599
  MediaModality["DOCUMENT"] = "DOCUMENT";
1592
1600
  })(MediaModality || (MediaModality = {}));
1601
+ /** The type of the VAD signal. */
1602
+ var VadSignalType;
1603
+ (function (VadSignalType) {
1604
+ /**
1605
+ * The default is VAD_SIGNAL_TYPE_UNSPECIFIED.
1606
+ */
1607
+ VadSignalType["VAD_SIGNAL_TYPE_UNSPECIFIED"] = "VAD_SIGNAL_TYPE_UNSPECIFIED";
1608
+ /**
1609
+ * Start of sentence signal.
1610
+ */
1611
+ VadSignalType["VAD_SIGNAL_TYPE_SOS"] = "VAD_SIGNAL_TYPE_SOS";
1612
+ /**
1613
+ * End of sentence signal.
1614
+ */
1615
+ VadSignalType["VAD_SIGNAL_TYPE_EOS"] = "VAD_SIGNAL_TYPE_EOS";
1616
+ })(VadSignalType || (VadSignalType = {}));
1593
1617
  /** Start of speech sensitivity. */
1594
1618
  var StartSensitivity;
1595
1619
  (function (StartSensitivity) {
@@ -4122,6 +4146,12 @@ function generateContentConfigToMldev$1(apiClient, fromObject, parentObject) {
4122
4146
  if (fromImageConfig != null) {
4123
4147
  setValueByPath(toObject, ['imageConfig'], imageConfigToMldev$1(fromImageConfig));
4124
4148
  }
4149
+ const fromEnableEnhancedCivicAnswers = getValueByPath(fromObject, [
4150
+ 'enableEnhancedCivicAnswers',
4151
+ ]);
4152
+ if (fromEnableEnhancedCivicAnswers != null) {
4153
+ setValueByPath(toObject, ['enableEnhancedCivicAnswers'], fromEnableEnhancedCivicAnswers);
4154
+ }
4125
4155
  return toObject;
4126
4156
  }
4127
4157
  function generateContentResponseFromMldev$1(fromObject) {
@@ -6254,6 +6284,18 @@ PERFORMANCE OF THIS SOFTWARE.
6254
6284
  /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
6255
6285
 
6256
6286
 
6287
+ function __rest(s, e) {
6288
+ var t = {};
6289
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
6290
+ t[p] = s[p];
6291
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6292
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
6293
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
6294
+ t[p[i]] = s[p[i]];
6295
+ }
6296
+ return t;
6297
+ }
6298
+
6257
6299
  function __values(o) {
6258
6300
  var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
6259
6301
  if (m) return m.call(o);
@@ -6566,17 +6608,17 @@ class Chat {
6566
6608
  return structuredClone(history);
6567
6609
  }
6568
6610
  processStreamResponse(streamResponse, inputContent) {
6569
- var _a, _b;
6570
6611
  return __asyncGenerator(this, arguments, function* processStreamResponse_1() {
6571
- var _c, e_1, _d, _e;
6612
+ var _a, e_1, _b, _c;
6613
+ var _d, _e;
6572
6614
  const outputContent = [];
6573
6615
  try {
6574
- for (var _f = true, streamResponse_1 = __asyncValues(streamResponse), streamResponse_1_1; streamResponse_1_1 = yield __await(streamResponse_1.next()), _c = streamResponse_1_1.done, !_c; _f = true) {
6575
- _e = streamResponse_1_1.value;
6616
+ for (var _f = true, streamResponse_1 = __asyncValues(streamResponse), streamResponse_1_1; streamResponse_1_1 = yield __await(streamResponse_1.next()), _a = streamResponse_1_1.done, !_a; _f = true) {
6617
+ _c = streamResponse_1_1.value;
6576
6618
  _f = false;
6577
- const chunk = _e;
6619
+ const chunk = _c;
6578
6620
  if (isValidResponse(chunk)) {
6579
- const content = (_b = (_a = chunk.candidates) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.content;
6621
+ const content = (_e = (_d = chunk.candidates) === null || _d === void 0 ? void 0 : _d[0]) === null || _e === void 0 ? void 0 : _e.content;
6580
6622
  if (content !== undefined) {
6581
6623
  outputContent.push(content);
6582
6624
  }
@@ -6587,7 +6629,7 @@ class Chat {
6587
6629
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
6588
6630
  finally {
6589
6631
  try {
6590
- if (!_f && !_c && (_d = streamResponse_1.return)) yield __await(_d.call(streamResponse_1));
6632
+ if (!_f && !_a && (_b = streamResponse_1.return)) yield __await(_b.call(streamResponse_1));
6591
6633
  }
6592
6634
  finally { if (e_1) throw e_1.error; }
6593
6635
  }
@@ -7380,6 +7422,9 @@ function liveConnectConfigToMldev$1(fromObject, parentObject) {
7380
7422
  if (parentObject !== undefined && fromProactivity != null) {
7381
7423
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
7382
7424
  }
7425
+ if (getValueByPath(fromObject, ['explicitVadSignal']) !== undefined) {
7426
+ throw new Error('explicitVadSignal parameter is not supported in Gemini API.');
7427
+ }
7383
7428
  return toObject;
7384
7429
  }
7385
7430
  function liveConnectConfigToVertex(fromObject, parentObject) {
@@ -7490,6 +7535,12 @@ function liveConnectConfigToVertex(fromObject, parentObject) {
7490
7535
  if (parentObject !== undefined && fromProactivity != null) {
7491
7536
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
7492
7537
  }
7538
+ const fromExplicitVadSignal = getValueByPath(fromObject, [
7539
+ 'explicitVadSignal',
7540
+ ]);
7541
+ if (parentObject !== undefined && fromExplicitVadSignal != null) {
7542
+ setValueByPath(parentObject, ['setup', 'explicitVadSignal'], fromExplicitVadSignal);
7543
+ }
7493
7544
  return toObject;
7494
7545
  }
7495
7546
  function liveConnectParametersToMldev(apiClient, fromObject) {
@@ -7666,6 +7717,12 @@ function liveServerMessageFromVertex(fromObject) {
7666
7717
  if (fromSessionResumptionUpdate != null) {
7667
7718
  setValueByPath(toObject, ['sessionResumptionUpdate'], fromSessionResumptionUpdate);
7668
7719
  }
7720
+ const fromVoiceActivityDetectionSignal = getValueByPath(fromObject, [
7721
+ 'voiceActivityDetectionSignal',
7722
+ ]);
7723
+ if (fromVoiceActivityDetectionSignal != null) {
7724
+ setValueByPath(toObject, ['voiceActivityDetectionSignal'], fromVoiceActivityDetectionSignal);
7725
+ }
7669
7726
  return toObject;
7670
7727
  }
7671
7728
  function partToMldev$2(fromObject) {
@@ -7741,14 +7798,14 @@ function sessionResumptionConfigToMldev$1(fromObject) {
7741
7798
  }
7742
7799
  function speechConfigToVertex$1(fromObject) {
7743
7800
  const toObject = {};
7744
- const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
7745
- if (fromLanguageCode != null) {
7746
- setValueByPath(toObject, ['languageCode'], fromLanguageCode);
7747
- }
7748
7801
  const fromVoiceConfig = getValueByPath(fromObject, ['voiceConfig']);
7749
7802
  if (fromVoiceConfig != null) {
7750
7803
  setValueByPath(toObject, ['voiceConfig'], fromVoiceConfig);
7751
7804
  }
7805
+ const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
7806
+ if (fromLanguageCode != null) {
7807
+ setValueByPath(toObject, ['languageCode'], fromLanguageCode);
7808
+ }
7752
7809
  if (getValueByPath(fromObject, ['multiSpeakerVoiceConfig']) !== undefined) {
7753
7810
  throw new Error('multiSpeakerVoiceConfig parameter is not supported in Vertex AI.');
7754
7811
  }
@@ -8844,6 +8901,12 @@ function generateContentConfigToMldev(apiClient, fromObject, parentObject) {
8844
8901
  if (fromImageConfig != null) {
8845
8902
  setValueByPath(toObject, ['imageConfig'], imageConfigToMldev(fromImageConfig));
8846
8903
  }
8904
+ const fromEnableEnhancedCivicAnswers = getValueByPath(fromObject, [
8905
+ 'enableEnhancedCivicAnswers',
8906
+ ]);
8907
+ if (fromEnableEnhancedCivicAnswers != null) {
8908
+ setValueByPath(toObject, ['enableEnhancedCivicAnswers'], fromEnableEnhancedCivicAnswers);
8909
+ }
8847
8910
  return toObject;
8848
8911
  }
8849
8912
  function generateContentConfigToVertex(apiClient, fromObject, parentObject) {
@@ -9008,6 +9071,10 @@ function generateContentConfigToVertex(apiClient, fromObject, parentObject) {
9008
9071
  if (fromImageConfig != null) {
9009
9072
  setValueByPath(toObject, ['imageConfig'], imageConfigToVertex(fromImageConfig));
9010
9073
  }
9074
+ if (getValueByPath(fromObject, ['enableEnhancedCivicAnswers']) !==
9075
+ undefined) {
9076
+ throw new Error('enableEnhancedCivicAnswers parameter is not supported in Vertex AI.');
9077
+ }
9011
9078
  return toObject;
9012
9079
  }
9013
9080
  function generateContentParametersToMldev(apiClient, fromObject) {
@@ -10736,14 +10803,14 @@ function segmentImageSourceToVertex(fromObject, parentObject) {
10736
10803
  }
10737
10804
  function speechConfigToVertex(fromObject) {
10738
10805
  const toObject = {};
10739
- const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
10740
- if (fromLanguageCode != null) {
10741
- setValueByPath(toObject, ['languageCode'], fromLanguageCode);
10742
- }
10743
10806
  const fromVoiceConfig = getValueByPath(fromObject, ['voiceConfig']);
10744
10807
  if (fromVoiceConfig != null) {
10745
10808
  setValueByPath(toObject, ['voiceConfig'], fromVoiceConfig);
10746
10809
  }
10810
+ const fromLanguageCode = getValueByPath(fromObject, ['languageCode']);
10811
+ if (fromLanguageCode != null) {
10812
+ setValueByPath(toObject, ['languageCode'], fromLanguageCode);
10813
+ }
10747
10814
  if (getValueByPath(fromObject, ['multiSpeakerVoiceConfig']) !== undefined) {
10748
10815
  throw new Error('multiSpeakerVoiceConfig parameter is not supported in Vertex AI.');
10749
10816
  }
@@ -11430,11 +11497,10 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
11430
11497
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
11431
11498
  const USER_AGENT_HEADER = 'User-Agent';
11432
11499
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
11433
- const SDK_VERSION = '1.31.0'; // x-release-please-version
11500
+ const SDK_VERSION = '1.33.0'; // x-release-please-version
11434
11501
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
11435
11502
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
11436
11503
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
11437
- const responseLineRE = /^\s*data: (.*)(?:\n\n|\r\r|\r\n\r\n)/;
11438
11504
  /**
11439
11505
  * The ApiClient class is used to send requests to the Gemini API or Vertex AI
11440
11506
  * endpoints.
@@ -11714,8 +11780,8 @@ class ApiClient {
11714
11780
  });
11715
11781
  }
11716
11782
  processStreamResponse(response) {
11717
- var _a;
11718
11783
  return __asyncGenerator(this, arguments, function* processStreamResponse_1() {
11784
+ var _a;
11719
11785
  const reader = (_a = response === null || response === void 0 ? void 0 : response.body) === null || _a === void 0 ? void 0 : _a.getReader();
11720
11786
  const decoder = new TextDecoder('utf-8');
11721
11787
  if (!reader) {
@@ -11723,6 +11789,8 @@ class ApiClient {
11723
11789
  }
11724
11790
  try {
11725
11791
  let buffer = '';
11792
+ const dataPrefix = 'data:';
11793
+ const delimiters = ['\n\n', '\r\r', '\r\n\r\n'];
11726
11794
  while (true) {
11727
11795
  const { done, value } = yield __await(reader.read());
11728
11796
  if (done) {
@@ -11756,21 +11824,40 @@ class ApiClient {
11756
11824
  }
11757
11825
  }
11758
11826
  buffer += chunkString;
11759
- let match = buffer.match(responseLineRE);
11760
- while (match) {
11761
- const processedChunkString = match[1];
11762
- try {
11763
- const partialResponse = new Response(processedChunkString, {
11764
- headers: response === null || response === void 0 ? void 0 : response.headers,
11765
- status: response === null || response === void 0 ? void 0 : response.status,
11766
- statusText: response === null || response === void 0 ? void 0 : response.statusText,
11767
- });
11768
- yield yield __await(new HttpResponse(partialResponse));
11769
- buffer = buffer.slice(match[0].length);
11770
- match = buffer.match(responseLineRE);
11827
+ let delimiterIndex = -1;
11828
+ let delimiterLength = 0;
11829
+ while (true) {
11830
+ delimiterIndex = -1;
11831
+ delimiterLength = 0;
11832
+ for (const delimiter of delimiters) {
11833
+ const index = buffer.indexOf(delimiter);
11834
+ if (index !== -1 &&
11835
+ (delimiterIndex === -1 || index < delimiterIndex)) {
11836
+ delimiterIndex = index;
11837
+ delimiterLength = delimiter.length;
11838
+ }
11839
+ }
11840
+ if (delimiterIndex === -1) {
11841
+ break; // No complete event in buffer
11771
11842
  }
11772
- catch (e) {
11773
- throw new Error(`exception parsing stream chunk ${processedChunkString}. ${e}`);
11843
+ const eventString = buffer.substring(0, delimiterIndex);
11844
+ buffer = buffer.substring(delimiterIndex + delimiterLength);
11845
+ const trimmedEvent = eventString.trim();
11846
+ if (trimmedEvent.startsWith(dataPrefix)) {
11847
+ const processedChunkString = trimmedEvent
11848
+ .substring(dataPrefix.length)
11849
+ .trim();
11850
+ try {
11851
+ const partialResponse = new Response(processedChunkString, {
11852
+ headers: response === null || response === void 0 ? void 0 : response.headers,
11853
+ status: response === null || response === void 0 ? void 0 : response.status,
11854
+ statusText: response === null || response === void 0 ? void 0 : response.statusText,
11855
+ });
11856
+ yield yield __await(new HttpResponse(partialResponse));
11857
+ }
11858
+ catch (e) {
11859
+ throw new Error(`exception parsing stream chunk ${processedChunkString}. ${e}`);
11860
+ }
11774
11861
  }
11775
11862
  }
11776
11863
  }
@@ -11903,7 +11990,7 @@ class ApiClient {
11903
11990
  }
11904
11991
  else {
11905
11992
  httpOptions = {
11906
- apiVersion: '',
11993
+ apiVersion: '', // api-version is set in the path.
11907
11994
  headers: Object.assign({ 'Content-Type': 'application/json', 'X-Goog-Upload-Protocol': 'resumable', 'X-Goog-Upload-Command': 'start', 'X-Goog-Upload-Header-Content-Length': `${sizeBytes}`, 'X-Goog-Upload-Header-Content-Type': `${mimeType}` }, (fileName ? { 'X-Goog-Upload-File-Name': fileName } : {})),
11908
11995
  };
11909
11996
  }
@@ -12065,8 +12152,8 @@ function isMcpCallableTool(object) {
12065
12152
  object instanceof McpCallableTool);
12066
12153
  }
12067
12154
  // List all tools from the MCP client.
12068
- function listAllTools(mcpClient, maxTools = 100) {
12069
- return __asyncGenerator(this, arguments, function* listAllTools_1() {
12155
+ function listAllTools(mcpClient_1) {
12156
+ return __asyncGenerator(this, arguments, function* listAllTools_1(mcpClient, maxTools = 100) {
12070
12157
  let cursor = undefined;
12071
12158
  let numTools = 0;
12072
12159
  while (numTools < maxTools) {
@@ -13386,9 +13473,9 @@ class Models extends BaseModule {
13386
13473
  let remoteCallCount = 0;
13387
13474
  const afcToolsMap = await this.initAfcToolsMap(params);
13388
13475
  return (function (models, afcTools, params) {
13389
- var _a, _b;
13390
13476
  return __asyncGenerator(this, arguments, function* () {
13391
- var _c, e_1, _d, _e;
13477
+ var _a, e_1, _b, _c;
13478
+ var _d, _e;
13392
13479
  while (remoteCallCount < maxRemoteCalls) {
13393
13480
  if (wereFunctionsCalled) {
13394
13481
  remoteCallCount++;
@@ -13399,14 +13486,14 @@ class Models extends BaseModule {
13399
13486
  const functionResponses = [];
13400
13487
  const responseContents = [];
13401
13488
  try {
13402
- for (var _f = true, response_1 = (e_1 = void 0, __asyncValues(response)), response_1_1; response_1_1 = yield __await(response_1.next()), _c = response_1_1.done, !_c; _f = true) {
13403
- _e = response_1_1.value;
13489
+ for (var _f = true, response_1 = (e_1 = void 0, __asyncValues(response)), response_1_1; response_1_1 = yield __await(response_1.next()), _a = response_1_1.done, !_a; _f = true) {
13490
+ _c = response_1_1.value;
13404
13491
  _f = false;
13405
- const chunk = _e;
13492
+ const chunk = _c;
13406
13493
  yield yield __await(chunk);
13407
- if (chunk.candidates && ((_a = chunk.candidates[0]) === null || _a === void 0 ? void 0 : _a.content)) {
13494
+ if (chunk.candidates && ((_d = chunk.candidates[0]) === null || _d === void 0 ? void 0 : _d.content)) {
13408
13495
  responseContents.push(chunk.candidates[0].content);
13409
- for (const part of (_b = chunk.candidates[0].content.parts) !== null && _b !== void 0 ? _b : []) {
13496
+ for (const part of (_e = chunk.candidates[0].content.parts) !== null && _e !== void 0 ? _e : []) {
13410
13497
  if (remoteCallCount < maxRemoteCalls && part.functionCall) {
13411
13498
  if (!part.functionCall.name) {
13412
13499
  throw new Error('Function call name was not returned by the model.');
@@ -13428,7 +13515,7 @@ class Models extends BaseModule {
13428
13515
  catch (e_1_1) { e_1 = { error: e_1_1 }; }
13429
13516
  finally {
13430
13517
  try {
13431
- if (!_f && !_c && (_d = response_1.return)) yield __await(_d.call(response_1));
13518
+ if (!_f && !_a && (_b = response_1.return)) yield __await(_b.call(response_1));
13432
13519
  }
13433
13520
  finally { if (e_1) throw e_1.error; }
13434
13521
  }
@@ -14882,6 +14969,9 @@ function liveConnectConfigToMldev(fromObject, parentObject) {
14882
14969
  if (parentObject !== undefined && fromProactivity != null) {
14883
14970
  setValueByPath(parentObject, ['setup', 'proactivity'], fromProactivity);
14884
14971
  }
14972
+ if (getValueByPath(fromObject, ['explicitVadSignal']) !== undefined) {
14973
+ throw new Error('explicitVadSignal parameter is not supported in Gemini API.');
14974
+ }
14885
14975
  return toObject;
14886
14976
  }
14887
14977
  function liveConnectConstraintsToMldev(apiClient, fromObject) {
@@ -15794,203 +15884,2174 @@ class FileSearchStores extends BaseModule {
15794
15884
  * Copyright 2025 Google LLC
15795
15885
  * SPDX-License-Identifier: Apache-2.0
15796
15886
  */
15797
- const GOOGLE_API_KEY_HEADER = 'x-goog-api-key';
15798
- const REQUIRED_VERTEX_AI_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
15799
- class NodeAuth {
15800
- constructor(opts) {
15801
- if (opts.apiKey !== undefined) {
15802
- this.apiKey = opts.apiKey;
15803
- return;
15804
- }
15805
- const vertexAuthOptions = buildGoogleAuthOptions(opts.googleAuthOptions);
15806
- this.googleAuth = new GoogleAuth(vertexAuthOptions);
15807
- }
15808
- async addAuthHeaders(headers, url) {
15809
- if (this.apiKey !== undefined) {
15810
- if (this.apiKey.startsWith('auth_tokens/')) {
15811
- throw new Error('Ephemeral tokens are only supported by the live API.');
15812
- }
15813
- this.addKeyHeader(headers);
15814
- return;
15815
- }
15816
- return this.addGoogleAuthHeaders(headers, url);
15817
- }
15818
- addKeyHeader(headers) {
15819
- if (headers.get(GOOGLE_API_KEY_HEADER) !== null) {
15820
- return;
15821
- }
15822
- if (this.apiKey === undefined) {
15823
- // This should never happen, this method is only called
15824
- // when apiKey is set.
15825
- throw new Error('Trying to set API key header but apiKey is not set');
15826
- }
15827
- headers.append(GOOGLE_API_KEY_HEADER, this.apiKey);
15828
- }
15829
- async addGoogleAuthHeaders(headers, url) {
15830
- if (this.googleAuth === undefined) {
15831
- // This should never happen, addGoogleAuthHeaders should only be
15832
- // called when there is no apiKey set and in these cases googleAuth
15833
- // is set.
15834
- throw new Error('Trying to set google-auth headers but googleAuth is unset');
15835
- }
15836
- const authHeaders = await this.googleAuth.getRequestHeaders(url);
15837
- for (const [key, value] of authHeaders) {
15838
- if (headers.get(key) !== null) {
15839
- continue;
15887
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15888
+ /**
15889
+ * https://stackoverflow.com/a/2117523
15890
+ */
15891
+ let uuid4Internal = function () {
15892
+ const { crypto } = globalThis;
15893
+ if (crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) {
15894
+ uuid4Internal = crypto.randomUUID.bind(crypto);
15895
+ return crypto.randomUUID();
15896
+ }
15897
+ const u8 = new Uint8Array(1);
15898
+ const randomByte = crypto ? () => crypto.getRandomValues(u8)[0] : () => (Math.random() * 0xff) & 0xff;
15899
+ return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) => (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16));
15900
+ };
15901
+ const uuid4 = () => uuid4Internal();
15902
+
15903
+ /**
15904
+ * @license
15905
+ * Copyright 2025 Google LLC
15906
+ * SPDX-License-Identifier: Apache-2.0
15907
+ */
15908
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15909
+ function isAbortError(err) {
15910
+ return (typeof err === 'object' &&
15911
+ err !== null &&
15912
+ // Spec-compliant fetch implementations
15913
+ (('name' in err && err.name === 'AbortError') ||
15914
+ // Expo fetch
15915
+ ('message' in err && String(err.message).includes('FetchRequestCanceledException'))));
15916
+ }
15917
+ const castToError = (err) => {
15918
+ if (err instanceof Error)
15919
+ return err;
15920
+ if (typeof err === 'object' && err !== null) {
15921
+ try {
15922
+ if (Object.prototype.toString.call(err) === '[object Error]') {
15923
+ // @ts-ignore - not all envs have native support for cause yet
15924
+ const error = new Error(err.message, err.cause ? { cause: err.cause } : {});
15925
+ if (err.stack)
15926
+ error.stack = err.stack;
15927
+ // @ts-ignore - not all envs have native support for cause yet
15928
+ if (err.cause && !error.cause)
15929
+ error.cause = err.cause;
15930
+ if (err.name)
15931
+ error.name = err.name;
15932
+ return error;
15840
15933
  }
15841
- headers.append(key, value);
15842
- }
15843
- }
15844
- }
15845
- function buildGoogleAuthOptions(googleAuthOptions) {
15846
- let authOptions;
15847
- if (!googleAuthOptions) {
15848
- authOptions = {
15849
- scopes: [REQUIRED_VERTEX_AI_SCOPE],
15850
- };
15851
- return authOptions;
15852
- }
15853
- else {
15854
- authOptions = googleAuthOptions;
15855
- if (!authOptions.scopes) {
15856
- authOptions.scopes = [REQUIRED_VERTEX_AI_SCOPE];
15857
- return authOptions;
15858
15934
  }
15859
- else if ((typeof authOptions.scopes === 'string' &&
15860
- authOptions.scopes !== REQUIRED_VERTEX_AI_SCOPE) ||
15861
- (Array.isArray(authOptions.scopes) &&
15862
- authOptions.scopes.indexOf(REQUIRED_VERTEX_AI_SCOPE) < 0)) {
15863
- throw new Error(`Invalid auth scopes. Scopes must include: ${REQUIRED_VERTEX_AI_SCOPE}`);
15935
+ catch (_a) { }
15936
+ try {
15937
+ return new Error(JSON.stringify(err));
15864
15938
  }
15865
- return authOptions;
15939
+ catch (_b) { }
15866
15940
  }
15867
- }
15941
+ return new Error(err);
15942
+ };
15868
15943
 
15869
15944
  /**
15870
15945
  * @license
15871
15946
  * Copyright 2025 Google LLC
15872
15947
  * SPDX-License-Identifier: Apache-2.0
15873
15948
  */
15874
- class NodeDownloader {
15875
- async download(params, apiClient) {
15876
- if (params.downloadPath) {
15877
- const response = await downloadFile(params, apiClient);
15878
- if (response instanceof HttpResponse) {
15879
- const writer = createWriteStream(params.downloadPath);
15880
- const body = Readable.fromWeb(response.responseInternal.body);
15881
- body.pipe(writer);
15882
- await finished(writer);
15883
- }
15884
- else {
15885
- try {
15886
- await writeFile(params.downloadPath, response, {
15887
- encoding: 'base64',
15888
- });
15889
- }
15890
- catch (error) {
15891
- throw new Error(`Failed to write file to ${params.downloadPath}: ${error}`);
15892
- }
15893
- }
15894
- }
15895
- }
15949
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
15950
+ class GeminiNextGenAPIClientError extends Error {
15896
15951
  }
15897
- async function downloadFile(params, apiClient) {
15898
- var _a, _b, _c;
15899
- const name = tFileName(params.file);
15900
- if (name !== undefined) {
15901
- return await apiClient.request({
15902
- path: `files/${name}:download`,
15903
- httpMethod: 'GET',
15904
- queryParams: {
15905
- 'alt': 'media',
15906
- },
15907
- httpOptions: (_a = params.config) === null || _a === void 0 ? void 0 : _a.httpOptions,
15908
- abortSignal: (_b = params.config) === null || _b === void 0 ? void 0 : _b.abortSignal,
15909
- });
15952
+ class APIError extends GeminiNextGenAPIClientError {
15953
+ constructor(status, error, message, headers) {
15954
+ super(`${APIError.makeMessage(status, error, message)}`);
15955
+ this.status = status;
15956
+ this.headers = headers;
15957
+ this.error = error;
15910
15958
  }
15911
- else if (isGeneratedVideo(params.file)) {
15912
- const videoBytes = (_c = params.file.video) === null || _c === void 0 ? void 0 : _c.videoBytes;
15913
- if (typeof videoBytes === 'string') {
15914
- return videoBytes;
15959
+ static makeMessage(status, error, message) {
15960
+ const msg = (error === null || error === void 0 ? void 0 : error.message) ?
15961
+ typeof error.message === 'string' ?
15962
+ error.message
15963
+ : JSON.stringify(error.message)
15964
+ : error ? JSON.stringify(error)
15965
+ : message;
15966
+ if (status && msg) {
15967
+ return `${status} ${msg}`;
15915
15968
  }
15916
- else {
15917
- throw new Error('Failed to download generated video, Uri or videoBytes not found.');
15969
+ if (status) {
15970
+ return `${status} status code (no body)`;
15918
15971
  }
15972
+ if (msg) {
15973
+ return msg;
15974
+ }
15975
+ return '(no status code or body)';
15919
15976
  }
15920
- else if (isVideo(params.file)) {
15921
- const videoBytes = params.file.videoBytes;
15922
- if (typeof videoBytes === 'string') {
15923
- return videoBytes;
15977
+ static generate(status, errorResponse, message, headers) {
15978
+ if (!status || !headers) {
15979
+ return new APIConnectionError({ message, cause: castToError(errorResponse) });
15924
15980
  }
15925
- else {
15926
- throw new Error('Failed to download video, Uri or videoBytes not found.');
15981
+ const error = errorResponse;
15982
+ if (status === 400) {
15983
+ return new BadRequestError(status, error, message, headers);
15984
+ }
15985
+ if (status === 401) {
15986
+ return new AuthenticationError(status, error, message, headers);
15987
+ }
15988
+ if (status === 403) {
15989
+ return new PermissionDeniedError(status, error, message, headers);
15990
+ }
15991
+ if (status === 404) {
15992
+ return new NotFoundError(status, error, message, headers);
15927
15993
  }
15994
+ if (status === 409) {
15995
+ return new ConflictError(status, error, message, headers);
15996
+ }
15997
+ if (status === 422) {
15998
+ return new UnprocessableEntityError(status, error, message, headers);
15999
+ }
16000
+ if (status === 429) {
16001
+ return new RateLimitError(status, error, message, headers);
16002
+ }
16003
+ if (status >= 500) {
16004
+ return new InternalServerError(status, error, message, headers);
16005
+ }
16006
+ return new APIError(status, error, message, headers);
15928
16007
  }
15929
- else {
15930
- throw new Error('Unsupported file type');
16008
+ }
16009
+ class APIUserAbortError extends APIError {
16010
+ constructor({ message } = {}) {
16011
+ super(undefined, undefined, message || 'Request was aborted.', undefined);
16012
+ }
16013
+ }
16014
+ class APIConnectionError extends APIError {
16015
+ constructor({ message, cause }) {
16016
+ super(undefined, undefined, message || 'Connection error.', undefined);
16017
+ // in some environments the 'cause' property is already declared
16018
+ // @ts-ignore
16019
+ if (cause)
16020
+ this.cause = cause;
16021
+ }
16022
+ }
16023
+ class APIConnectionTimeoutError extends APIConnectionError {
16024
+ constructor({ message } = {}) {
16025
+ super({ message: message !== null && message !== void 0 ? message : 'Request timed out.' });
15931
16026
  }
15932
16027
  }
16028
+ class BadRequestError extends APIError {
16029
+ }
16030
+ class AuthenticationError extends APIError {
16031
+ }
16032
+ class PermissionDeniedError extends APIError {
16033
+ }
16034
+ class NotFoundError extends APIError {
16035
+ }
16036
+ class ConflictError extends APIError {
16037
+ }
16038
+ class UnprocessableEntityError extends APIError {
16039
+ }
16040
+ class RateLimitError extends APIError {
16041
+ }
16042
+ class InternalServerError extends APIError {
16043
+ }
15933
16044
 
15934
16045
  /**
15935
16046
  * @license
15936
16047
  * Copyright 2025 Google LLC
15937
16048
  * SPDX-License-Identifier: Apache-2.0
15938
16049
  */
15939
- class NodeWebSocketFactory {
15940
- create(url, headers, callbacks) {
15941
- return new NodeWebSocket(url, headers, callbacks);
15942
- }
16050
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16051
+ // https://url.spec.whatwg.org/#url-scheme-string
16052
+ const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
16053
+ const isAbsoluteURL = (url) => {
16054
+ return startsWithSchemeRegexp.test(url);
16055
+ };
16056
+ let isArrayInternal = (val) => ((isArrayInternal = Array.isArray), isArrayInternal(val));
16057
+ const isArray = isArrayInternal;
16058
+ let isReadonlyArrayInternal = isArray;
16059
+ const isReadonlyArray = isReadonlyArrayInternal;
16060
+ // https://stackoverflow.com/a/34491287
16061
+ function isEmptyObj(obj) {
16062
+ if (!obj)
16063
+ return true;
16064
+ for (const _k in obj)
16065
+ return false;
16066
+ return true;
15943
16067
  }
15944
- class NodeWebSocket {
15945
- constructor(url, headers, callbacks) {
15946
- this.url = url;
15947
- this.headers = headers;
15948
- this.callbacks = callbacks;
16068
+ // https://eslint.org/docs/latest/rules/no-prototype-builtins
16069
+ function hasOwn(obj, key) {
16070
+ return Object.prototype.hasOwnProperty.call(obj, key);
16071
+ }
16072
+ const validatePositiveInteger = (name, n) => {
16073
+ if (typeof n !== 'number' || !Number.isInteger(n)) {
16074
+ throw new GeminiNextGenAPIClientError(`${name} must be an integer`);
15949
16075
  }
15950
- connect() {
15951
- this.ws = new NodeWs.WebSocket(this.url, { headers: this.headers });
15952
- this.ws.onopen = this.callbacks.onopen;
15953
- this.ws.onerror = this.callbacks.onerror;
15954
- this.ws.onclose = this.callbacks.onclose;
15955
- this.ws.onmessage = this.callbacks.onmessage;
16076
+ if (n < 0) {
16077
+ throw new GeminiNextGenAPIClientError(`${name} must be a positive integer`);
15956
16078
  }
15957
- send(message) {
15958
- if (this.ws === undefined) {
15959
- throw new Error('WebSocket is not connected');
15960
- }
15961
- this.ws.send(message);
16079
+ return n;
16080
+ };
16081
+ const safeJSON = (text) => {
16082
+ try {
16083
+ return JSON.parse(text);
15962
16084
  }
15963
- close() {
15964
- if (this.ws === undefined) {
15965
- throw new Error('WebSocket is not connected');
15966
- }
15967
- this.ws.close();
16085
+ catch (err) {
16086
+ return undefined;
15968
16087
  }
15969
- }
16088
+ };
15970
16089
 
15971
16090
  /**
15972
16091
  * @license
15973
16092
  * Copyright 2025 Google LLC
15974
16093
  * SPDX-License-Identifier: Apache-2.0
15975
16094
  */
15976
- // Code generated by the Google Gen AI SDK generator DO NOT EDIT.
15977
- function cancelTuningJobParametersToMldev(fromObject, _rootObject) {
15978
- const toObject = {};
15979
- const fromName = getValueByPath(fromObject, ['name']);
15980
- if (fromName != null) {
15981
- setValueByPath(toObject, ['_url', 'name'], fromName);
15982
- }
15983
- return toObject;
15984
- }
15985
- function cancelTuningJobParametersToVertex(fromObject, _rootObject) {
15986
- const toObject = {};
15987
- const fromName = getValueByPath(fromObject, ['name']);
15988
- if (fromName != null) {
15989
- setValueByPath(toObject, ['_url', 'name'], fromName);
15990
- }
15991
- return toObject;
15992
- }
15993
- function cancelTuningJobResponseFromMldev(fromObject, _rootObject) {
16095
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16096
+ const sleep$1 = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
16097
+
16098
+ /**
16099
+ * @license
16100
+ * Copyright 2025 Google LLC
16101
+ * SPDX-License-Identifier: Apache-2.0
16102
+ */
16103
+ const VERSION = '0.0.1';
16104
+
16105
+ /**
16106
+ * @license
16107
+ * Copyright 2025 Google LLC
16108
+ * SPDX-License-Identifier: Apache-2.0
16109
+ */
16110
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16111
+ /**
16112
+ * Note this does not detect 'browser'; for that, use getBrowserInfo().
16113
+ */
16114
+ function getDetectedPlatform() {
16115
+ if (typeof Deno !== 'undefined' && Deno.build != null) {
16116
+ return 'deno';
16117
+ }
16118
+ if (typeof EdgeRuntime !== 'undefined') {
16119
+ return 'edge';
16120
+ }
16121
+ if (Object.prototype.toString.call(typeof globalThis.process !== 'undefined' ? globalThis.process : 0) === '[object process]') {
16122
+ return 'node';
16123
+ }
16124
+ return 'unknown';
16125
+ }
16126
+ const getPlatformProperties = () => {
16127
+ var _a, _b, _c, _d, _e;
16128
+ const detectedPlatform = getDetectedPlatform();
16129
+ if (detectedPlatform === 'deno') {
16130
+ return {
16131
+ 'X-Stainless-Lang': 'js',
16132
+ 'X-Stainless-Package-Version': VERSION,
16133
+ 'X-Stainless-OS': normalizePlatform(Deno.build.os),
16134
+ 'X-Stainless-Arch': normalizeArch(Deno.build.arch),
16135
+ 'X-Stainless-Runtime': 'deno',
16136
+ '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',
16137
+ };
16138
+ }
16139
+ if (typeof EdgeRuntime !== 'undefined') {
16140
+ return {
16141
+ 'X-Stainless-Lang': 'js',
16142
+ 'X-Stainless-Package-Version': VERSION,
16143
+ 'X-Stainless-OS': 'Unknown',
16144
+ 'X-Stainless-Arch': `other:${EdgeRuntime}`,
16145
+ 'X-Stainless-Runtime': 'edge',
16146
+ 'X-Stainless-Runtime-Version': globalThis.process.version,
16147
+ };
16148
+ }
16149
+ // Check if Node.js
16150
+ if (detectedPlatform === 'node') {
16151
+ return {
16152
+ 'X-Stainless-Lang': 'js',
16153
+ 'X-Stainless-Package-Version': VERSION,
16154
+ 'X-Stainless-OS': normalizePlatform((_c = globalThis.process.platform) !== null && _c !== void 0 ? _c : 'unknown'),
16155
+ 'X-Stainless-Arch': normalizeArch((_d = globalThis.process.arch) !== null && _d !== void 0 ? _d : 'unknown'),
16156
+ 'X-Stainless-Runtime': 'node',
16157
+ 'X-Stainless-Runtime-Version': (_e = globalThis.process.version) !== null && _e !== void 0 ? _e : 'unknown',
16158
+ };
16159
+ }
16160
+ const browserInfo = getBrowserInfo();
16161
+ if (browserInfo) {
16162
+ return {
16163
+ 'X-Stainless-Lang': 'js',
16164
+ 'X-Stainless-Package-Version': VERSION,
16165
+ 'X-Stainless-OS': 'Unknown',
16166
+ 'X-Stainless-Arch': 'unknown',
16167
+ 'X-Stainless-Runtime': `browser:${browserInfo.browser}`,
16168
+ 'X-Stainless-Runtime-Version': browserInfo.version,
16169
+ };
16170
+ }
16171
+ // TODO add support for Cloudflare workers, etc.
16172
+ return {
16173
+ 'X-Stainless-Lang': 'js',
16174
+ 'X-Stainless-Package-Version': VERSION,
16175
+ 'X-Stainless-OS': 'Unknown',
16176
+ 'X-Stainless-Arch': 'unknown',
16177
+ 'X-Stainless-Runtime': 'unknown',
16178
+ 'X-Stainless-Runtime-Version': 'unknown',
16179
+ };
16180
+ };
16181
+ // Note: modified from https://github.com/JS-DevTools/host-environment/blob/b1ab79ecde37db5d6e163c050e54fe7d287d7c92/src/isomorphic.browser.ts
16182
+ function getBrowserInfo() {
16183
+ if (typeof navigator === 'undefined' || !navigator) {
16184
+ return null;
16185
+ }
16186
+ // NOTE: The order matters here!
16187
+ const browserPatterns = [
16188
+ { key: 'edge', pattern: /Edge(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16189
+ { key: 'ie', pattern: /MSIE(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16190
+ { key: 'ie', pattern: /Trident(?:.*rv\:(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16191
+ { key: 'chrome', pattern: /Chrome(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16192
+ { key: 'firefox', pattern: /Firefox(?:\W+(\d+)\.(\d+)(?:\.(\d+))?)?/ },
16193
+ { key: 'safari', pattern: /(?:Version\W+(\d+)\.(\d+)(?:\.(\d+))?)?(?:\W+Mobile\S*)?\W+Safari/ },
16194
+ ];
16195
+ // Find the FIRST matching browser
16196
+ for (const { key, pattern } of browserPatterns) {
16197
+ const match = pattern.exec(navigator.userAgent);
16198
+ if (match) {
16199
+ const major = match[1] || 0;
16200
+ const minor = match[2] || 0;
16201
+ const patch = match[3] || 0;
16202
+ return { browser: key, version: `${major}.${minor}.${patch}` };
16203
+ }
16204
+ }
16205
+ return null;
16206
+ }
16207
+ const normalizeArch = (arch) => {
16208
+ // Node docs:
16209
+ // - https://nodejs.org/api/process.html#processarch
16210
+ // Deno docs:
16211
+ // - https://doc.deno.land/deno/stable/~/Deno.build
16212
+ if (arch === 'x32')
16213
+ return 'x32';
16214
+ if (arch === 'x86_64' || arch === 'x64')
16215
+ return 'x64';
16216
+ if (arch === 'arm')
16217
+ return 'arm';
16218
+ if (arch === 'aarch64' || arch === 'arm64')
16219
+ return 'arm64';
16220
+ if (arch)
16221
+ return `other:${arch}`;
16222
+ return 'unknown';
16223
+ };
16224
+ const normalizePlatform = (platform) => {
16225
+ // Node platforms:
16226
+ // - https://nodejs.org/api/process.html#processplatform
16227
+ // Deno platforms:
16228
+ // - https://doc.deno.land/deno/stable/~/Deno.build
16229
+ // - https://github.com/denoland/deno/issues/14799
16230
+ platform = platform.toLowerCase();
16231
+ // NOTE: this iOS check is untested and may not work
16232
+ // Node does not work natively on IOS, there is a fork at
16233
+ // https://github.com/nodejs-mobile/nodejs-mobile
16234
+ // however it is unknown at the time of writing how to detect if it is running
16235
+ if (platform.includes('ios'))
16236
+ return 'iOS';
16237
+ if (platform === 'android')
16238
+ return 'Android';
16239
+ if (platform === 'darwin')
16240
+ return 'MacOS';
16241
+ if (platform === 'win32')
16242
+ return 'Windows';
16243
+ if (platform === 'freebsd')
16244
+ return 'FreeBSD';
16245
+ if (platform === 'openbsd')
16246
+ return 'OpenBSD';
16247
+ if (platform === 'linux')
16248
+ return 'Linux';
16249
+ if (platform)
16250
+ return `Other:${platform}`;
16251
+ return 'Unknown';
16252
+ };
16253
+ let _platformHeaders;
16254
+ const getPlatformHeaders = () => {
16255
+ return (_platformHeaders !== null && _platformHeaders !== void 0 ? _platformHeaders : (_platformHeaders = getPlatformProperties()));
16256
+ };
16257
+
16258
+ /**
16259
+ * @license
16260
+ * Copyright 2025 Google LLC
16261
+ * SPDX-License-Identifier: Apache-2.0
16262
+ */
16263
+ function getDefaultFetch() {
16264
+ if (typeof fetch !== 'undefined') {
16265
+ return fetch;
16266
+ }
16267
+ 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`');
16268
+ }
16269
+ function makeReadableStream(...args) {
16270
+ const ReadableStream = globalThis.ReadableStream;
16271
+ if (typeof ReadableStream === 'undefined') {
16272
+ // Note: All of the platforms / runtimes we officially support already define
16273
+ // `ReadableStream` as a global, so this should only ever be hit on unsupported runtimes.
16274
+ throw new Error('`ReadableStream` is not defined as a global; You will need to polyfill it, `globalThis.ReadableStream = ReadableStream`');
16275
+ }
16276
+ return new ReadableStream(...args);
16277
+ }
16278
+ function ReadableStreamFrom(iterable) {
16279
+ let iter = Symbol.asyncIterator in iterable ? iterable[Symbol.asyncIterator]() : iterable[Symbol.iterator]();
16280
+ return makeReadableStream({
16281
+ start() { },
16282
+ async pull(controller) {
16283
+ const { done, value } = await iter.next();
16284
+ if (done) {
16285
+ controller.close();
16286
+ }
16287
+ else {
16288
+ controller.enqueue(value);
16289
+ }
16290
+ },
16291
+ async cancel() {
16292
+ var _a;
16293
+ await ((_a = iter.return) === null || _a === void 0 ? void 0 : _a.call(iter));
16294
+ },
16295
+ });
16296
+ }
16297
+ /**
16298
+ * Most browsers don't yet have async iterable support for ReadableStream,
16299
+ * and Node has a very different way of reading bytes from its "ReadableStream".
16300
+ *
16301
+ * This polyfill was pulled from https://github.com/MattiasBuelens/web-streams-polyfill/pull/122#issuecomment-1627354490
16302
+ */
16303
+ function ReadableStreamToAsyncIterable(stream) {
16304
+ if (stream[Symbol.asyncIterator])
16305
+ return stream;
16306
+ const reader = stream.getReader();
16307
+ return {
16308
+ async next() {
16309
+ try {
16310
+ const result = await reader.read();
16311
+ if (result === null || result === void 0 ? void 0 : result.done)
16312
+ reader.releaseLock(); // release lock when stream becomes closed
16313
+ return result;
16314
+ }
16315
+ catch (e) {
16316
+ reader.releaseLock(); // release lock when stream becomes errored
16317
+ throw e;
16318
+ }
16319
+ },
16320
+ async return() {
16321
+ const cancelPromise = reader.cancel();
16322
+ reader.releaseLock();
16323
+ await cancelPromise;
16324
+ return { done: true, value: undefined };
16325
+ },
16326
+ [Symbol.asyncIterator]() {
16327
+ return this;
16328
+ },
16329
+ };
16330
+ }
16331
+ /**
16332
+ * Cancels a ReadableStream we don't need to consume.
16333
+ * See https://undici.nodejs.org/#/?id=garbage-collection
16334
+ */
16335
+ async function CancelReadableStream(stream) {
16336
+ var _a, _b;
16337
+ if (stream === null || typeof stream !== 'object')
16338
+ return;
16339
+ if (stream[Symbol.asyncIterator]) {
16340
+ await ((_b = (_a = stream[Symbol.asyncIterator]()).return) === null || _b === void 0 ? void 0 : _b.call(_a));
16341
+ return;
16342
+ }
16343
+ const reader = stream.getReader();
16344
+ const cancelPromise = reader.cancel();
16345
+ reader.releaseLock();
16346
+ await cancelPromise;
16347
+ }
16348
+
16349
+ /**
16350
+ * @license
16351
+ * Copyright 2025 Google LLC
16352
+ * SPDX-License-Identifier: Apache-2.0
16353
+ */
16354
+ const FallbackEncoder = ({ headers, body }) => {
16355
+ return {
16356
+ bodyHeaders: {
16357
+ 'content-type': 'application/json',
16358
+ },
16359
+ body: JSON.stringify(body),
16360
+ };
16361
+ };
16362
+
16363
+ /**
16364
+ * @license
16365
+ * Copyright 2025 Google LLC
16366
+ * SPDX-License-Identifier: Apache-2.0
16367
+ */
16368
+ const checkFileSupport = () => {
16369
+ var _a;
16370
+ if (typeof File === 'undefined') {
16371
+ const { process } = globalThis;
16372
+ 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;
16373
+ throw new Error('`File` is not defined as a global, which is required for file uploads.' +
16374
+ (isOldNode ?
16375
+ " Update to Node 20 LTS or newer, or set `globalThis.File` to `import('node:buffer').File`."
16376
+ : ''));
16377
+ }
16378
+ };
16379
+ /**
16380
+ * Construct a `File` instance. This is used to ensure a helpful error is thrown
16381
+ * for environments that don't define a global `File` yet.
16382
+ */
16383
+ function makeFile(fileBits, fileName, options) {
16384
+ checkFileSupport();
16385
+ return new File(fileBits, fileName !== null && fileName !== void 0 ? fileName : 'unknown_file', options);
16386
+ }
16387
+ function getName(value) {
16388
+ return (((typeof value === 'object' &&
16389
+ value !== null &&
16390
+ (('name' in value && value.name && String(value.name)) ||
16391
+ ('url' in value && value.url && String(value.url)) ||
16392
+ ('filename' in value && value.filename && String(value.filename)) ||
16393
+ ('path' in value && value.path && String(value.path)))) ||
16394
+ '')
16395
+ .split(/[\\/]/)
16396
+ .pop() || undefined);
16397
+ }
16398
+ const isAsyncIterable = (value) => value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
16399
+
16400
+ /**
16401
+ * @license
16402
+ * Copyright 2025 Google LLC
16403
+ * SPDX-License-Identifier: Apache-2.0
16404
+ */
16405
+ /**
16406
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
16407
+ */
16408
+ const isBlobLike = (value) => value != null &&
16409
+ typeof value === 'object' &&
16410
+ typeof value.size === 'number' &&
16411
+ typeof value.type === 'string' &&
16412
+ typeof value.text === 'function' &&
16413
+ typeof value.slice === 'function' &&
16414
+ typeof value.arrayBuffer === 'function';
16415
+ /**
16416
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
16417
+ */
16418
+ const isFileLike = (value) => value != null &&
16419
+ typeof value === 'object' &&
16420
+ typeof value.name === 'string' &&
16421
+ typeof value.lastModified === 'number' &&
16422
+ isBlobLike(value);
16423
+ const isResponseLike = (value) => value != null &&
16424
+ typeof value === 'object' &&
16425
+ typeof value.url === 'string' &&
16426
+ typeof value.blob === 'function';
16427
+ /**
16428
+ * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
16429
+ * @param value the raw content of the file. Can be an {@link Uploadable}, BlobLikePart, or AsyncIterable of BlobLikeParts
16430
+ * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
16431
+ * @param {Object=} options additional properties
16432
+ * @param {string=} options.type the MIME type of the content
16433
+ * @param {number=} options.lastModified the last modified timestamp
16434
+ * @returns a {@link File} with the given properties
16435
+ */
16436
+ async function toFile(value, name, options) {
16437
+ checkFileSupport();
16438
+ // If it's a promise, resolve it.
16439
+ value = await value;
16440
+ // If we've been given a `File` we don't need to do anything
16441
+ if (isFileLike(value)) {
16442
+ if (value instanceof File) {
16443
+ return value;
16444
+ }
16445
+ return makeFile([await value.arrayBuffer()], value.name);
16446
+ }
16447
+ if (isResponseLike(value)) {
16448
+ const blob = await value.blob();
16449
+ name || (name = new URL(value.url).pathname.split(/[\\/]/).pop());
16450
+ return makeFile(await getBytes(blob), name, options);
16451
+ }
16452
+ const parts = await getBytes(value);
16453
+ name || (name = getName(value));
16454
+ if (!(options === null || options === void 0 ? void 0 : options.type)) {
16455
+ const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type);
16456
+ if (typeof type === 'string') {
16457
+ options = Object.assign(Object.assign({}, options), { type });
16458
+ }
16459
+ }
16460
+ return makeFile(parts, name, options);
16461
+ }
16462
+ async function getBytes(value) {
16463
+ var _a, e_1, _b, _c;
16464
+ var _d;
16465
+ let parts = [];
16466
+ if (typeof value === 'string' ||
16467
+ ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
16468
+ value instanceof ArrayBuffer) {
16469
+ parts.push(value);
16470
+ }
16471
+ else if (isBlobLike(value)) {
16472
+ parts.push(value instanceof Blob ? value : await value.arrayBuffer());
16473
+ }
16474
+ else if (isAsyncIterable(value) // includes Readable, ReadableStream, etc.
16475
+ ) {
16476
+ try {
16477
+ 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) {
16478
+ _c = value_1_1.value;
16479
+ _e = false;
16480
+ const chunk = _c;
16481
+ parts.push(...(await getBytes(chunk))); // TODO, consider validating?
16482
+ }
16483
+ }
16484
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
16485
+ finally {
16486
+ try {
16487
+ if (!_e && !_a && (_b = value_1.return)) await _b.call(value_1);
16488
+ }
16489
+ finally { if (e_1) throw e_1.error; }
16490
+ }
16491
+ }
16492
+ else {
16493
+ const constructor = (_d = value === null || value === void 0 ? void 0 : value.constructor) === null || _d === void 0 ? void 0 : _d.name;
16494
+ throw new Error(`Unexpected data type: ${typeof value}${constructor ? `; constructor: ${constructor}` : ''}${propsForError(value)}`);
16495
+ }
16496
+ return parts;
16497
+ }
16498
+ function propsForError(value) {
16499
+ if (typeof value !== 'object' || value === null)
16500
+ return '';
16501
+ const props = Object.getOwnPropertyNames(value);
16502
+ return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`;
16503
+ }
16504
+
16505
+ /**
16506
+ * @license
16507
+ * Copyright 2025 Google LLC
16508
+ * SPDX-License-Identifier: Apache-2.0
16509
+ */
16510
+ class APIResource {
16511
+ constructor(client) {
16512
+ this._client = client;
16513
+ }
16514
+ }
16515
+ /**
16516
+ * The key path from the client. For example, a resource accessible as `client.resource.subresource` would
16517
+ * have a property `static override readonly _key = Object.freeze(['resource', 'subresource'] as const);`.
16518
+ */
16519
+ APIResource._key = [];
16520
+
16521
+ /**
16522
+ * @license
16523
+ * Copyright 2025 Google LLC
16524
+ * SPDX-License-Identifier: Apache-2.0
16525
+ */
16526
+ /**
16527
+ * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
16528
+ *
16529
+ * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3:
16530
+ * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
16531
+ * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
16532
+ * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
16533
+ */
16534
+ function encodeURIPath(str) {
16535
+ return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
16536
+ }
16537
+ const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
16538
+ const createPathTagFunction = (pathEncoder = encodeURIPath) => (function path(statics, ...params) {
16539
+ // If there are no params, no processing is needed.
16540
+ if (statics.length === 1)
16541
+ return statics[0];
16542
+ let postPath = false;
16543
+ const invalidSegments = [];
16544
+ const path = statics.reduce((previousValue, currentValue, index) => {
16545
+ var _a, _b, _c;
16546
+ if (/[?#]/.test(currentValue)) {
16547
+ postPath = true;
16548
+ }
16549
+ const value = params[index];
16550
+ let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
16551
+ if (index !== params.length &&
16552
+ (value == null ||
16553
+ (typeof value === 'object' &&
16554
+ // handle values from other realms
16555
+ value.toString ===
16556
+ ((_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)))) {
16557
+ encoded = value + '';
16558
+ invalidSegments.push({
16559
+ start: previousValue.length + currentValue.length,
16560
+ length: encoded.length,
16561
+ error: `Value of type ${Object.prototype.toString
16562
+ .call(value)
16563
+ .slice(8, -1)} is not a valid path parameter`,
16564
+ });
16565
+ }
16566
+ return previousValue + currentValue + (index === params.length ? '' : encoded);
16567
+ }, '');
16568
+ const pathOnly = path.split(/[?#]/, 1)[0];
16569
+ const invalidSegmentPattern = /(?<=^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
16570
+ let match;
16571
+ // Find all invalid segments
16572
+ while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
16573
+ invalidSegments.push({
16574
+ start: match.index,
16575
+ length: match[0].length,
16576
+ error: `Value "${match[0]}" can\'t be safely passed as a path parameter`,
16577
+ });
16578
+ }
16579
+ invalidSegments.sort((a, b) => a.start - b.start);
16580
+ if (invalidSegments.length > 0) {
16581
+ let lastEnd = 0;
16582
+ const underline = invalidSegments.reduce((acc, segment) => {
16583
+ const spaces = ' '.repeat(segment.start - lastEnd);
16584
+ const arrows = '^'.repeat(segment.length);
16585
+ lastEnd = segment.start + segment.length;
16586
+ return acc + spaces + arrows;
16587
+ }, '');
16588
+ throw new GeminiNextGenAPIClientError(`Path parameters result in path with invalid segments:\n${invalidSegments
16589
+ .map((e) => e.error)
16590
+ .join('\n')}\n${path}\n${underline}`);
16591
+ }
16592
+ return path;
16593
+ });
16594
+ /**
16595
+ * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
16596
+ */
16597
+ const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
16598
+
16599
+ /**
16600
+ * @license
16601
+ * Copyright 2025 Google LLC
16602
+ * SPDX-License-Identifier: Apache-2.0
16603
+ */
16604
+ class BaseInteractions extends APIResource {
16605
+ create(params, options) {
16606
+ var _a;
16607
+ const { api_version = this._client.apiVersion } = params, body = __rest(params, ["api_version"]);
16608
+ if ('model' in body && 'agent_config' in body) {
16609
+ throw new GeminiNextGenAPIClientError(`Invalid request: specified \`model\` and \`agent_config\`. If specifying \`model\`, use \`generation_config\`.`);
16610
+ }
16611
+ if ('agent' in body && 'generation_config' in body) {
16612
+ throw new GeminiNextGenAPIClientError(`Invalid request: specified \`agent\` and \`generation_config\`. If specifying \`agent\`, use \`agent_config\`.`);
16613
+ }
16614
+ return this._client.post(path `/${api_version}/interactions`, Object.assign(Object.assign({ body }, options), { stream: (_a = params.stream) !== null && _a !== void 0 ? _a : false }));
16615
+ }
16616
+ /**
16617
+ * Deletes the interaction by id.
16618
+ *
16619
+ * @example
16620
+ * ```ts
16621
+ * const interaction = await client.interactions.delete('id');
16622
+ * ```
16623
+ */
16624
+ delete(id, params = {}, options) {
16625
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
16626
+ return this._client.delete(path `/${api_version}/interactions/${id}`, options);
16627
+ }
16628
+ /**
16629
+ * Cancels an interaction by id. This only applies to background interactions that are still running.
16630
+ *
16631
+ * @example
16632
+ * ```ts
16633
+ * const interaction = await client.interactions.cancel('id');
16634
+ * ```
16635
+ */
16636
+ cancel(id, params = {}, options) {
16637
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
16638
+ return this._client.post(path `/${api_version}/interactions/${id}/cancel`, options);
16639
+ }
16640
+ get(id, params = {}, options) {
16641
+ var _a;
16642
+ const _b = params !== null && params !== void 0 ? params : {}, { api_version = this._client.apiVersion } = _b, query = __rest(_b, ["api_version"]);
16643
+ 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 }));
16644
+ }
16645
+ }
16646
+ BaseInteractions._key = Object.freeze(['interactions']);
16647
+ class Interactions extends BaseInteractions {
16648
+ }
16649
+
16650
+ /**
16651
+ * @license
16652
+ * Copyright 2025 Google LLC
16653
+ * SPDX-License-Identifier: Apache-2.0
16654
+ */
16655
+ function concatBytes(buffers) {
16656
+ let length = 0;
16657
+ for (const buffer of buffers) {
16658
+ length += buffer.length;
16659
+ }
16660
+ const output = new Uint8Array(length);
16661
+ let index = 0;
16662
+ for (const buffer of buffers) {
16663
+ output.set(buffer, index);
16664
+ index += buffer.length;
16665
+ }
16666
+ return output;
16667
+ }
16668
+ let encodeUTF8_;
16669
+ function encodeUTF8(str) {
16670
+ let encoder;
16671
+ return (encodeUTF8_ !== null && encodeUTF8_ !== void 0 ? encodeUTF8_ : ((encoder = new globalThis.TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder))))(str);
16672
+ }
16673
+ let decodeUTF8_;
16674
+ function decodeUTF8(bytes) {
16675
+ let decoder;
16676
+ return (decodeUTF8_ !== null && decodeUTF8_ !== void 0 ? decodeUTF8_ : ((decoder = new globalThis.TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder))))(bytes);
16677
+ }
16678
+
16679
+ /**
16680
+ * @license
16681
+ * Copyright 2025 Google LLC
16682
+ * SPDX-License-Identifier: Apache-2.0
16683
+ */
16684
+ /**
16685
+ * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally
16686
+ * reading lines from text.
16687
+ *
16688
+ * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258
16689
+ */
16690
+ class LineDecoder {
16691
+ constructor() {
16692
+ this.buffer = new Uint8Array();
16693
+ this.carriageReturnIndex = null;
16694
+ }
16695
+ decode(chunk) {
16696
+ if (chunk == null) {
16697
+ return [];
16698
+ }
16699
+ const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
16700
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
16701
+ : chunk;
16702
+ this.buffer = concatBytes([this.buffer, binaryChunk]);
16703
+ const lines = [];
16704
+ let patternIndex;
16705
+ while ((patternIndex = findNewlineIndex(this.buffer, this.carriageReturnIndex)) != null) {
16706
+ if (patternIndex.carriage && this.carriageReturnIndex == null) {
16707
+ // skip until we either get a corresponding `\n`, a new `\r` or nothing
16708
+ this.carriageReturnIndex = patternIndex.index;
16709
+ continue;
16710
+ }
16711
+ // we got double \r or \rtext\n
16712
+ if (this.carriageReturnIndex != null &&
16713
+ (patternIndex.index !== this.carriageReturnIndex + 1 || patternIndex.carriage)) {
16714
+ lines.push(decodeUTF8(this.buffer.subarray(0, this.carriageReturnIndex - 1)));
16715
+ this.buffer = this.buffer.subarray(this.carriageReturnIndex);
16716
+ this.carriageReturnIndex = null;
16717
+ continue;
16718
+ }
16719
+ const endIndex = this.carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
16720
+ const line = decodeUTF8(this.buffer.subarray(0, endIndex));
16721
+ lines.push(line);
16722
+ this.buffer = this.buffer.subarray(patternIndex.index);
16723
+ this.carriageReturnIndex = null;
16724
+ }
16725
+ return lines;
16726
+ }
16727
+ flush() {
16728
+ if (!this.buffer.length) {
16729
+ return [];
16730
+ }
16731
+ return this.decode('\n');
16732
+ }
16733
+ }
16734
+ // prettier-ignore
16735
+ LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']);
16736
+ LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g;
16737
+ /**
16738
+ * This function searches the buffer for the end patterns, (\r or \n)
16739
+ * and returns an object with the index preceding the matched newline and the
16740
+ * index after the newline char. `null` is returned if no new line is found.
16741
+ *
16742
+ * ```ts
16743
+ * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 }
16744
+ * ```
16745
+ */
16746
+ function findNewlineIndex(buffer, startIndex) {
16747
+ const newline = 0x0a; // \n
16748
+ const carriage = 0x0d; // \r
16749
+ for (let i = startIndex !== null && startIndex !== void 0 ? startIndex : 0; i < buffer.length; i++) {
16750
+ if (buffer[i] === newline) {
16751
+ return { preceding: i, index: i + 1, carriage: false };
16752
+ }
16753
+ if (buffer[i] === carriage) {
16754
+ return { preceding: i, index: i + 1, carriage: true };
16755
+ }
16756
+ }
16757
+ return null;
16758
+ }
16759
+ function findDoubleNewlineIndex(buffer) {
16760
+ // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n)
16761
+ // and returns the index right after the first occurrence of any pattern,
16762
+ // or -1 if none of the patterns are found.
16763
+ const newline = 0x0a; // \n
16764
+ const carriage = 0x0d; // \r
16765
+ for (let i = 0; i < buffer.length - 1; i++) {
16766
+ if (buffer[i] === newline && buffer[i + 1] === newline) {
16767
+ // \n\n
16768
+ return i + 2;
16769
+ }
16770
+ if (buffer[i] === carriage && buffer[i + 1] === carriage) {
16771
+ // \r\r
16772
+ return i + 2;
16773
+ }
16774
+ if (buffer[i] === carriage &&
16775
+ buffer[i + 1] === newline &&
16776
+ i + 3 < buffer.length &&
16777
+ buffer[i + 2] === carriage &&
16778
+ buffer[i + 3] === newline) {
16779
+ // \r\n\r\n
16780
+ return i + 4;
16781
+ }
16782
+ }
16783
+ return -1;
16784
+ }
16785
+
16786
+ /**
16787
+ * @license
16788
+ * Copyright 2025 Google LLC
16789
+ * SPDX-License-Identifier: Apache-2.0
16790
+ */
16791
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
16792
+ const levelNumbers = {
16793
+ off: 0,
16794
+ error: 200,
16795
+ warn: 300,
16796
+ info: 400,
16797
+ debug: 500,
16798
+ };
16799
+ const parseLogLevel = (maybeLevel, sourceName, client) => {
16800
+ if (!maybeLevel) {
16801
+ return undefined;
16802
+ }
16803
+ if (hasOwn(levelNumbers, maybeLevel)) {
16804
+ return maybeLevel;
16805
+ }
16806
+ loggerFor(client).warn(`${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(Object.keys(levelNumbers))}`);
16807
+ return undefined;
16808
+ };
16809
+ function noop() { }
16810
+ function makeLogFn(fnLevel, logger, logLevel) {
16811
+ if (!logger || levelNumbers[fnLevel] > levelNumbers[logLevel]) {
16812
+ return noop;
16813
+ }
16814
+ else {
16815
+ // Don't wrap logger functions, we want the stacktrace intact!
16816
+ return logger[fnLevel].bind(logger);
16817
+ }
16818
+ }
16819
+ const noopLogger = {
16820
+ error: noop,
16821
+ warn: noop,
16822
+ info: noop,
16823
+ debug: noop,
16824
+ };
16825
+ let cachedLoggers = /* @__PURE__ */ new WeakMap();
16826
+ function loggerFor(client) {
16827
+ var _a;
16828
+ const logger = client.logger;
16829
+ const logLevel = (_a = client.logLevel) !== null && _a !== void 0 ? _a : 'off';
16830
+ if (!logger) {
16831
+ return noopLogger;
16832
+ }
16833
+ const cachedLogger = cachedLoggers.get(logger);
16834
+ if (cachedLogger && cachedLogger[0] === logLevel) {
16835
+ return cachedLogger[1];
16836
+ }
16837
+ const levelLogger = {
16838
+ error: makeLogFn('error', logger, logLevel),
16839
+ warn: makeLogFn('warn', logger, logLevel),
16840
+ info: makeLogFn('info', logger, logLevel),
16841
+ debug: makeLogFn('debug', logger, logLevel),
16842
+ };
16843
+ cachedLoggers.set(logger, [logLevel, levelLogger]);
16844
+ return levelLogger;
16845
+ }
16846
+ const formatRequestDetails = (details) => {
16847
+ if (details.options) {
16848
+ details.options = Object.assign({}, details.options);
16849
+ delete details.options['headers']; // redundant + leaks internals
16850
+ }
16851
+ if (details.headers) {
16852
+ details.headers = Object.fromEntries((details.headers instanceof Headers ? [...details.headers] : Object.entries(details.headers)).map(([name, value]) => [
16853
+ name,
16854
+ (name.toLowerCase() === 'x-goog-api-key' ||
16855
+ name.toLowerCase() === 'authorization' ||
16856
+ name.toLowerCase() === 'cookie' ||
16857
+ name.toLowerCase() === 'set-cookie') ?
16858
+ '***'
16859
+ : value,
16860
+ ]));
16861
+ }
16862
+ if ('retryOfRequestLogID' in details) {
16863
+ if (details.retryOfRequestLogID) {
16864
+ details.retryOf = details.retryOfRequestLogID;
16865
+ }
16866
+ delete details.retryOfRequestLogID;
16867
+ }
16868
+ return details;
16869
+ };
16870
+
16871
+ /**
16872
+ * @license
16873
+ * Copyright 2025 Google LLC
16874
+ * SPDX-License-Identifier: Apache-2.0
16875
+ */
16876
+ class Stream {
16877
+ constructor(iterator, controller, client) {
16878
+ this.iterator = iterator;
16879
+ this.controller = controller;
16880
+ this.client = client;
16881
+ }
16882
+ static fromSSEResponse(response, controller, client) {
16883
+ let consumed = false;
16884
+ const logger = client ? loggerFor(client) : console;
16885
+ function iterator() {
16886
+ return __asyncGenerator(this, arguments, function* iterator_1() {
16887
+ var _a, e_1, _b, _c;
16888
+ if (consumed) {
16889
+ throw new GeminiNextGenAPIClientError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
16890
+ }
16891
+ consumed = true;
16892
+ let done = false;
16893
+ try {
16894
+ try {
16895
+ for (var _d = true, _e = __asyncValues(_iterSSEMessages(response, controller)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
16896
+ _c = _f.value;
16897
+ _d = false;
16898
+ const sse = _c;
16899
+ if (done)
16900
+ continue;
16901
+ if (sse.data.startsWith('[DONE]')) {
16902
+ done = true;
16903
+ continue;
16904
+ }
16905
+ else {
16906
+ try {
16907
+ // @ts-ignore
16908
+ yield yield __await(JSON.parse(sse.data));
16909
+ }
16910
+ catch (e) {
16911
+ logger.error(`Could not parse message into JSON:`, sse.data);
16912
+ logger.error(`From chunk:`, sse.raw);
16913
+ throw e;
16914
+ }
16915
+ }
16916
+ }
16917
+ }
16918
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
16919
+ finally {
16920
+ try {
16921
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
16922
+ }
16923
+ finally { if (e_1) throw e_1.error; }
16924
+ }
16925
+ done = true;
16926
+ }
16927
+ catch (e) {
16928
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
16929
+ if (isAbortError(e))
16930
+ return yield __await(void 0);
16931
+ throw e;
16932
+ }
16933
+ finally {
16934
+ // If the user `break`s, abort the ongoing request.
16935
+ if (!done)
16936
+ controller.abort();
16937
+ }
16938
+ });
16939
+ }
16940
+ return new Stream(iterator, controller, client);
16941
+ }
16942
+ /**
16943
+ * Generates a Stream from a newline-separated ReadableStream
16944
+ * where each item is a JSON value.
16945
+ */
16946
+ static fromReadableStream(readableStream, controller, client) {
16947
+ let consumed = false;
16948
+ function iterLines() {
16949
+ return __asyncGenerator(this, arguments, function* iterLines_1() {
16950
+ var _a, e_2, _b, _c;
16951
+ const lineDecoder = new LineDecoder();
16952
+ const iter = ReadableStreamToAsyncIterable(readableStream);
16953
+ try {
16954
+ 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) {
16955
+ _c = iter_1_1.value;
16956
+ _d = false;
16957
+ const chunk = _c;
16958
+ for (const line of lineDecoder.decode(chunk)) {
16959
+ yield yield __await(line);
16960
+ }
16961
+ }
16962
+ }
16963
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
16964
+ finally {
16965
+ try {
16966
+ if (!_d && !_a && (_b = iter_1.return)) yield __await(_b.call(iter_1));
16967
+ }
16968
+ finally { if (e_2) throw e_2.error; }
16969
+ }
16970
+ for (const line of lineDecoder.flush()) {
16971
+ yield yield __await(line);
16972
+ }
16973
+ });
16974
+ }
16975
+ function iterator() {
16976
+ return __asyncGenerator(this, arguments, function* iterator_2() {
16977
+ var _a, e_3, _b, _c;
16978
+ if (consumed) {
16979
+ throw new GeminiNextGenAPIClientError('Cannot iterate over a consumed stream, use `.tee()` to split the stream.');
16980
+ }
16981
+ consumed = true;
16982
+ let done = false;
16983
+ try {
16984
+ try {
16985
+ for (var _d = true, _e = __asyncValues(iterLines()), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
16986
+ _c = _f.value;
16987
+ _d = false;
16988
+ const line = _c;
16989
+ if (done)
16990
+ continue;
16991
+ // @ts-ignore
16992
+ if (line)
16993
+ yield yield __await(JSON.parse(line));
16994
+ }
16995
+ }
16996
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
16997
+ finally {
16998
+ try {
16999
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
17000
+ }
17001
+ finally { if (e_3) throw e_3.error; }
17002
+ }
17003
+ done = true;
17004
+ }
17005
+ catch (e) {
17006
+ // If the user calls `stream.controller.abort()`, we should exit without throwing.
17007
+ if (isAbortError(e))
17008
+ return yield __await(void 0);
17009
+ throw e;
17010
+ }
17011
+ finally {
17012
+ // If the user `break`s, abort the ongoing request.
17013
+ if (!done)
17014
+ controller.abort();
17015
+ }
17016
+ });
17017
+ }
17018
+ return new Stream(iterator, controller, client);
17019
+ }
17020
+ [Symbol.asyncIterator]() {
17021
+ return this.iterator();
17022
+ }
17023
+ /**
17024
+ * Splits the stream into two streams which can be
17025
+ * independently read from at different speeds.
17026
+ */
17027
+ tee() {
17028
+ const left = [];
17029
+ const right = [];
17030
+ const iterator = this.iterator();
17031
+ const teeIterator = (queue) => {
17032
+ return {
17033
+ next: () => {
17034
+ if (queue.length === 0) {
17035
+ const result = iterator.next();
17036
+ left.push(result);
17037
+ right.push(result);
17038
+ }
17039
+ return queue.shift();
17040
+ },
17041
+ };
17042
+ };
17043
+ return [
17044
+ new Stream(() => teeIterator(left), this.controller, this.client),
17045
+ new Stream(() => teeIterator(right), this.controller, this.client),
17046
+ ];
17047
+ }
17048
+ /**
17049
+ * Converts this stream to a newline-separated ReadableStream of
17050
+ * JSON stringified values in the stream
17051
+ * which can be turned back into a Stream with `Stream.fromReadableStream()`.
17052
+ */
17053
+ toReadableStream() {
17054
+ const self = this;
17055
+ let iter;
17056
+ return makeReadableStream({
17057
+ async start() {
17058
+ iter = self[Symbol.asyncIterator]();
17059
+ },
17060
+ async pull(ctrl) {
17061
+ try {
17062
+ const { value, done } = await iter.next();
17063
+ if (done)
17064
+ return ctrl.close();
17065
+ const bytes = encodeUTF8(JSON.stringify(value) + '\n');
17066
+ ctrl.enqueue(bytes);
17067
+ }
17068
+ catch (err) {
17069
+ ctrl.error(err);
17070
+ }
17071
+ },
17072
+ async cancel() {
17073
+ var _a;
17074
+ await ((_a = iter.return) === null || _a === void 0 ? void 0 : _a.call(iter));
17075
+ },
17076
+ });
17077
+ }
17078
+ }
17079
+ function _iterSSEMessages(response, controller) {
17080
+ return __asyncGenerator(this, arguments, function* _iterSSEMessages_1() {
17081
+ var _a, e_4, _b, _c;
17082
+ if (!response.body) {
17083
+ controller.abort();
17084
+ if (typeof globalThis.navigator !== 'undefined' &&
17085
+ globalThis.navigator.product === 'ReactNative') {
17086
+ 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`);
17087
+ }
17088
+ throw new GeminiNextGenAPIClientError(`Attempted to iterate over a response with no body`);
17089
+ }
17090
+ const sseDecoder = new SSEDecoder();
17091
+ const lineDecoder = new LineDecoder();
17092
+ const iter = ReadableStreamToAsyncIterable(response.body);
17093
+ try {
17094
+ for (var _d = true, _e = __asyncValues(iterSSEChunks(iter)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
17095
+ _c = _f.value;
17096
+ _d = false;
17097
+ const sseChunk = _c;
17098
+ for (const line of lineDecoder.decode(sseChunk)) {
17099
+ const sse = sseDecoder.decode(line);
17100
+ if (sse)
17101
+ yield yield __await(sse);
17102
+ }
17103
+ }
17104
+ }
17105
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
17106
+ finally {
17107
+ try {
17108
+ if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
17109
+ }
17110
+ finally { if (e_4) throw e_4.error; }
17111
+ }
17112
+ for (const line of lineDecoder.flush()) {
17113
+ const sse = sseDecoder.decode(line);
17114
+ if (sse)
17115
+ yield yield __await(sse);
17116
+ }
17117
+ });
17118
+ }
17119
+ /**
17120
+ * Given an async iterable iterator, iterates over it and yields full
17121
+ * SSE chunks, i.e. yields when a double new-line is encountered.
17122
+ */
17123
+ function iterSSEChunks(iterator) {
17124
+ return __asyncGenerator(this, arguments, function* iterSSEChunks_1() {
17125
+ var _a, e_5, _b, _c;
17126
+ let data = new Uint8Array();
17127
+ try {
17128
+ 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) {
17129
+ _c = iterator_3_1.value;
17130
+ _d = false;
17131
+ const chunk = _c;
17132
+ if (chunk == null) {
17133
+ continue;
17134
+ }
17135
+ const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
17136
+ : typeof chunk === 'string' ? encodeUTF8(chunk)
17137
+ : chunk;
17138
+ let newData = new Uint8Array(data.length + binaryChunk.length);
17139
+ newData.set(data);
17140
+ newData.set(binaryChunk, data.length);
17141
+ data = newData;
17142
+ let patternIndex;
17143
+ while ((patternIndex = findDoubleNewlineIndex(data)) !== -1) {
17144
+ yield yield __await(data.slice(0, patternIndex));
17145
+ data = data.slice(patternIndex);
17146
+ }
17147
+ }
17148
+ }
17149
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
17150
+ finally {
17151
+ try {
17152
+ if (!_d && !_a && (_b = iterator_3.return)) yield __await(_b.call(iterator_3));
17153
+ }
17154
+ finally { if (e_5) throw e_5.error; }
17155
+ }
17156
+ if (data.length > 0) {
17157
+ yield yield __await(data);
17158
+ }
17159
+ });
17160
+ }
17161
+ class SSEDecoder {
17162
+ constructor() {
17163
+ this.event = null;
17164
+ this.data = [];
17165
+ this.chunks = [];
17166
+ }
17167
+ decode(line) {
17168
+ if (line.endsWith('\r')) {
17169
+ line = line.substring(0, line.length - 1);
17170
+ }
17171
+ if (!line) {
17172
+ // empty line and we didn't previously encounter any messages
17173
+ if (!this.event && !this.data.length)
17174
+ return null;
17175
+ const sse = {
17176
+ event: this.event,
17177
+ data: this.data.join('\n'),
17178
+ raw: this.chunks,
17179
+ };
17180
+ this.event = null;
17181
+ this.data = [];
17182
+ this.chunks = [];
17183
+ return sse;
17184
+ }
17185
+ this.chunks.push(line);
17186
+ if (line.startsWith(':')) {
17187
+ return null;
17188
+ }
17189
+ let [fieldname, _, value] = partition(line, ':');
17190
+ if (value.startsWith(' ')) {
17191
+ value = value.substring(1);
17192
+ }
17193
+ if (fieldname === 'event') {
17194
+ this.event = value;
17195
+ }
17196
+ else if (fieldname === 'data') {
17197
+ this.data.push(value);
17198
+ }
17199
+ return null;
17200
+ }
17201
+ }
17202
+ function partition(str, delimiter) {
17203
+ const index = str.indexOf(delimiter);
17204
+ if (index !== -1) {
17205
+ return [str.substring(0, index), delimiter, str.substring(index + delimiter.length)];
17206
+ }
17207
+ return [str, '', ''];
17208
+ }
17209
+
17210
+ /**
17211
+ * @license
17212
+ * Copyright 2025 Google LLC
17213
+ * SPDX-License-Identifier: Apache-2.0
17214
+ */
17215
+ async function defaultParseResponse(client, props) {
17216
+ const { response, requestLogID, retryOfRequestLogID, startTime } = props;
17217
+ const body = await (async () => {
17218
+ var _a;
17219
+ if (props.options.stream) {
17220
+ loggerFor(client).debug('response', response.status, response.url, response.headers, response.body);
17221
+ // Note: there is an invariant here that isn't represented in the type system
17222
+ // that if you set `stream: true` the response type must also be `Stream<T>`
17223
+ if (props.options.__streamClass) {
17224
+ return props.options.__streamClass.fromSSEResponse(response, props.controller, client);
17225
+ }
17226
+ return Stream.fromSSEResponse(response, props.controller, client);
17227
+ }
17228
+ // fetch refuses to read the body when the status code is 204.
17229
+ if (response.status === 204) {
17230
+ return null;
17231
+ }
17232
+ if (props.options.__binaryResponse) {
17233
+ return response;
17234
+ }
17235
+ const contentType = response.headers.get('content-type');
17236
+ const mediaType = (_a = contentType === null || contentType === void 0 ? void 0 : contentType.split(';')[0]) === null || _a === void 0 ? void 0 : _a.trim();
17237
+ const isJSON = (mediaType === null || mediaType === void 0 ? void 0 : mediaType.includes('application/json')) || (mediaType === null || mediaType === void 0 ? void 0 : mediaType.endsWith('+json'));
17238
+ if (isJSON) {
17239
+ const json = await response.json();
17240
+ return json;
17241
+ }
17242
+ const text = await response.text();
17243
+ return text;
17244
+ })();
17245
+ loggerFor(client).debug(`[${requestLogID}] response parsed`, formatRequestDetails({
17246
+ retryOfRequestLogID,
17247
+ url: response.url,
17248
+ status: response.status,
17249
+ body,
17250
+ durationMs: Date.now() - startTime,
17251
+ }));
17252
+ return body;
17253
+ }
17254
+
17255
+ /**
17256
+ * @license
17257
+ * Copyright 2025 Google LLC
17258
+ * SPDX-License-Identifier: Apache-2.0
17259
+ */
17260
+ /**
17261
+ * A subclass of `Promise` providing additional helper methods
17262
+ * for interacting with the SDK.
17263
+ */
17264
+ class APIPromise extends Promise {
17265
+ constructor(client, responsePromise, parseResponse = defaultParseResponse) {
17266
+ super((resolve) => {
17267
+ // this is maybe a bit weird but this has to be a no-op to not implicitly
17268
+ // parse the response body; instead .then, .catch, .finally are overridden
17269
+ // to parse the response
17270
+ resolve(null);
17271
+ });
17272
+ this.responsePromise = responsePromise;
17273
+ this.parseResponse = parseResponse;
17274
+ this.client = client;
17275
+ }
17276
+ _thenUnwrap(transform) {
17277
+ return new APIPromise(this.client, this.responsePromise, async (client, props) => transform(await this.parseResponse(client, props), props));
17278
+ }
17279
+ /**
17280
+ * Gets the raw `Response` instance instead of parsing the response
17281
+ * data.
17282
+ *
17283
+ * If you want to parse the response body but still get the `Response`
17284
+ * instance, you can use {@link withResponse()}.
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
+ asResponse() {
17291
+ return this.responsePromise.then((p) => p.response);
17292
+ }
17293
+ /**
17294
+ * Gets the parsed response data and the raw `Response` instance.
17295
+ *
17296
+ * If you just want to get the raw `Response` instance without parsing it,
17297
+ * you can use {@link asResponse()}.
17298
+ *
17299
+ * 👋 Getting the wrong TypeScript type for `Response`?
17300
+ * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
17301
+ * to your `tsconfig.json`.
17302
+ */
17303
+ async withResponse() {
17304
+ const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
17305
+ return { data, response };
17306
+ }
17307
+ parse() {
17308
+ if (!this.parsedPromise) {
17309
+ this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.client, data));
17310
+ }
17311
+ return this.parsedPromise;
17312
+ }
17313
+ then(onfulfilled, onrejected) {
17314
+ return this.parse().then(onfulfilled, onrejected);
17315
+ }
17316
+ catch(onrejected) {
17317
+ return this.parse().catch(onrejected);
17318
+ }
17319
+ finally(onfinally) {
17320
+ return this.parse().finally(onfinally);
17321
+ }
17322
+ }
17323
+
17324
+ /**
17325
+ * @license
17326
+ * Copyright 2025 Google LLC
17327
+ * SPDX-License-Identifier: Apache-2.0
17328
+ */
17329
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17330
+ const brand_privateNullableHeaders = /* @__PURE__ */ Symbol('brand.privateNullableHeaders');
17331
+ function* iterateHeaders(headers) {
17332
+ if (!headers)
17333
+ return;
17334
+ if (brand_privateNullableHeaders in headers) {
17335
+ const { values, nulls } = headers;
17336
+ yield* values.entries();
17337
+ for (const name of nulls) {
17338
+ yield [name, null];
17339
+ }
17340
+ return;
17341
+ }
17342
+ let shouldClear = false;
17343
+ let iter;
17344
+ if (headers instanceof Headers) {
17345
+ iter = headers.entries();
17346
+ }
17347
+ else if (isReadonlyArray(headers)) {
17348
+ iter = headers;
17349
+ }
17350
+ else {
17351
+ shouldClear = true;
17352
+ iter = Object.entries(headers !== null && headers !== void 0 ? headers : {});
17353
+ }
17354
+ for (let row of iter) {
17355
+ const name = row[0];
17356
+ if (typeof name !== 'string')
17357
+ throw new TypeError('expected header name to be a string');
17358
+ const values = isReadonlyArray(row[1]) ? row[1] : [row[1]];
17359
+ let didClear = false;
17360
+ for (const value of values) {
17361
+ if (value === undefined)
17362
+ continue;
17363
+ // Objects keys always overwrite older headers, they never append.
17364
+ // Yield a null to clear the header before adding the new values.
17365
+ if (shouldClear && !didClear) {
17366
+ didClear = true;
17367
+ yield [name, null];
17368
+ }
17369
+ yield [name, value];
17370
+ }
17371
+ }
17372
+ }
17373
+ const buildHeaders = (newHeaders) => {
17374
+ const targetHeaders = new Headers();
17375
+ const nullHeaders = new Set();
17376
+ for (const headers of newHeaders) {
17377
+ const seenHeaders = new Set();
17378
+ for (const [name, value] of iterateHeaders(headers)) {
17379
+ const lowerName = name.toLowerCase();
17380
+ if (!seenHeaders.has(lowerName)) {
17381
+ targetHeaders.delete(name);
17382
+ seenHeaders.add(lowerName);
17383
+ }
17384
+ if (value === null) {
17385
+ targetHeaders.delete(name);
17386
+ nullHeaders.add(lowerName);
17387
+ }
17388
+ else {
17389
+ targetHeaders.append(name, value);
17390
+ nullHeaders.delete(lowerName);
17391
+ }
17392
+ }
17393
+ }
17394
+ return { [brand_privateNullableHeaders]: true, values: targetHeaders, nulls: nullHeaders };
17395
+ };
17396
+
17397
+ /**
17398
+ * @license
17399
+ * Copyright 2025 Google LLC
17400
+ * SPDX-License-Identifier: Apache-2.0
17401
+ */
17402
+ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
17403
+ /**
17404
+ * Read an environment variable.
17405
+ *
17406
+ * Trims beginning and trailing whitespace.
17407
+ *
17408
+ * Will return undefined if the environment variable doesn't exist or cannot be accessed.
17409
+ */
17410
+ const readEnv = (env) => {
17411
+ var _a, _b, _c, _d, _e, _f;
17412
+ if (typeof globalThis.process !== 'undefined') {
17413
+ 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;
17414
+ }
17415
+ if (typeof globalThis.Deno !== 'undefined') {
17416
+ 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();
17417
+ }
17418
+ return undefined;
17419
+ };
17420
+
17421
+ /**
17422
+ * @license
17423
+ * Copyright 2025 Google LLC
17424
+ * SPDX-License-Identifier: Apache-2.0
17425
+ */
17426
+ var _a;
17427
+ /**
17428
+ * Base class for Gemini Next Gen API API clients.
17429
+ */
17430
+ class BaseGeminiNextGenAPIClient {
17431
+ /**
17432
+ * API Client for interfacing with the Gemini Next Gen API API.
17433
+ *
17434
+ * @param {string | null | undefined} [opts.apiKey=process.env['GEMINI_API_KEY'] ?? null]
17435
+ * @param {string | undefined} [opts.apiVersion=v1beta]
17436
+ * @param {string} [opts.baseURL=process.env['GEMINI_NEXT_GEN_API_BASE_URL'] ?? https://generativelanguage.googleapis.com] - Override the default base URL for the API.
17437
+ * @param {number} [opts.timeout=1 minute] - The maximum amount of time (in milliseconds) the client will wait for a response before timing out.
17438
+ * @param {MergedRequestInit} [opts.fetchOptions] - Additional `RequestInit` options to be passed to `fetch` calls.
17439
+ * @param {Fetch} [opts.fetch] - Specify a custom `fetch` function implementation.
17440
+ * @param {number} [opts.maxRetries=2] - The maximum number of times the client will retry a request.
17441
+ * @param {HeadersLike} opts.defaultHeaders - Default headers to include with every request to the API.
17442
+ * @param {Record<string, string | undefined>} opts.defaultQuery - Default query parameters to include with every request to the API.
17443
+ */
17444
+ constructor(_b) {
17445
+ var _c, _d, _e, _f, _g, _h, _j;
17446
+ var _k = _b === void 0 ? {} : _b, { baseURL = readEnv('GEMINI_NEXT_GEN_API_BASE_URL'), apiKey = (_c = readEnv('GEMINI_API_KEY')) !== null && _c !== void 0 ? _c : null, apiVersion = 'v1beta' } = _k, opts = __rest(_k, ["baseURL", "apiKey", "apiVersion"]);
17447
+ const options = Object.assign(Object.assign({ apiKey,
17448
+ apiVersion }, opts), { baseURL: baseURL || `https://generativelanguage.googleapis.com` });
17449
+ this.baseURL = options.baseURL;
17450
+ this.timeout = (_d = options.timeout) !== null && _d !== void 0 ? _d : BaseGeminiNextGenAPIClient.DEFAULT_TIMEOUT /* 1 minute */;
17451
+ this.logger = (_e = options.logger) !== null && _e !== void 0 ? _e : console;
17452
+ const defaultLogLevel = 'warn';
17453
+ // Set default logLevel early so that we can log a warning in parseLogLevel.
17454
+ this.logLevel = defaultLogLevel;
17455
+ this.logLevel =
17456
+ (_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;
17457
+ this.fetchOptions = options.fetchOptions;
17458
+ this.maxRetries = (_h = options.maxRetries) !== null && _h !== void 0 ? _h : 2;
17459
+ this.fetch = (_j = options.fetch) !== null && _j !== void 0 ? _j : getDefaultFetch();
17460
+ this.encoder = FallbackEncoder;
17461
+ this._options = options;
17462
+ this.apiKey = apiKey;
17463
+ this.apiVersion = apiVersion;
17464
+ }
17465
+ /**
17466
+ * Create a new client instance re-using the same options given to the current client with optional overriding.
17467
+ */
17468
+ withOptions(options) {
17469
+ 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));
17470
+ return client;
17471
+ }
17472
+ /**
17473
+ * Check whether the base URL is set to its default.
17474
+ */
17475
+ baseURLOverridden() {
17476
+ return this.baseURL !== 'https://generativelanguage.googleapis.com';
17477
+ }
17478
+ defaultQuery() {
17479
+ return this._options.defaultQuery;
17480
+ }
17481
+ validateHeaders({ values, nulls }) {
17482
+ if (this.apiKey && values.get('x-goog-api-key')) {
17483
+ return;
17484
+ }
17485
+ if (nulls.has('x-goog-api-key')) {
17486
+ return;
17487
+ }
17488
+ 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');
17489
+ }
17490
+ async authHeaders(opts) {
17491
+ if (this.apiKey == null) {
17492
+ return undefined;
17493
+ }
17494
+ return buildHeaders([{ 'x-goog-api-key': this.apiKey }]);
17495
+ }
17496
+ /**
17497
+ * Basic re-implementation of `qs.stringify` for primitive types.
17498
+ */
17499
+ stringifyQuery(query) {
17500
+ return Object.entries(query)
17501
+ .filter(([_, value]) => typeof value !== 'undefined')
17502
+ .map(([key, value]) => {
17503
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
17504
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
17505
+ }
17506
+ if (value === null) {
17507
+ return `${encodeURIComponent(key)}=`;
17508
+ }
17509
+ 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.`);
17510
+ })
17511
+ .join('&');
17512
+ }
17513
+ getUserAgent() {
17514
+ return `${this.constructor.name}/JS ${VERSION}`;
17515
+ }
17516
+ defaultIdempotencyKey() {
17517
+ return `stainless-node-retry-${uuid4()}`;
17518
+ }
17519
+ makeStatusError(status, error, message, headers) {
17520
+ return APIError.generate(status, error, message, headers);
17521
+ }
17522
+ buildURL(path, query, defaultBaseURL) {
17523
+ const baseURL = (!this.baseURLOverridden() && defaultBaseURL) || this.baseURL;
17524
+ const url = isAbsoluteURL(path) ?
17525
+ new URL(path)
17526
+ : new URL(baseURL + (baseURL.endsWith('/') && path.startsWith('/') ? path.slice(1) : path));
17527
+ const defaultQuery = this.defaultQuery();
17528
+ if (!isEmptyObj(defaultQuery)) {
17529
+ query = Object.assign(Object.assign({}, defaultQuery), query);
17530
+ }
17531
+ if (typeof query === 'object' && query && !Array.isArray(query)) {
17532
+ url.search = this.stringifyQuery(query);
17533
+ }
17534
+ return url.toString();
17535
+ }
17536
+ /**
17537
+ * Used as a callback for mutating the given `FinalRequestOptions` object.
17538
+ */
17539
+ async prepareOptions(options) { }
17540
+ /**
17541
+ * Used as a callback for mutating the given `RequestInit` object.
17542
+ *
17543
+ * This is useful for cases where you want to add certain headers based off of
17544
+ * the request properties, e.g. `method` or `url`.
17545
+ */
17546
+ async prepareRequest(request, { url, options }) { }
17547
+ get(path, opts) {
17548
+ return this.methodRequest('get', path, opts);
17549
+ }
17550
+ post(path, opts) {
17551
+ return this.methodRequest('post', path, opts);
17552
+ }
17553
+ patch(path, opts) {
17554
+ return this.methodRequest('patch', path, opts);
17555
+ }
17556
+ put(path, opts) {
17557
+ return this.methodRequest('put', path, opts);
17558
+ }
17559
+ delete(path, opts) {
17560
+ return this.methodRequest('delete', path, opts);
17561
+ }
17562
+ methodRequest(method, path, opts) {
17563
+ return this.request(Promise.resolve(opts).then((opts) => {
17564
+ return Object.assign({ method, path }, opts);
17565
+ }));
17566
+ }
17567
+ request(options, remainingRetries = null) {
17568
+ return new APIPromise(this, this.makeRequest(options, remainingRetries, undefined));
17569
+ }
17570
+ async makeRequest(optionsInput, retriesRemaining, retryOfRequestLogID) {
17571
+ var _b, _c, _d;
17572
+ const options = await optionsInput;
17573
+ const maxRetries = (_b = options.maxRetries) !== null && _b !== void 0 ? _b : this.maxRetries;
17574
+ if (retriesRemaining == null) {
17575
+ retriesRemaining = maxRetries;
17576
+ }
17577
+ await this.prepareOptions(options);
17578
+ const { req, url, timeout } = await this.buildRequest(options, {
17579
+ retryCount: maxRetries - retriesRemaining,
17580
+ });
17581
+ await this.prepareRequest(req, { url, options });
17582
+ /** Not an API request ID, just for correlating local log entries. */
17583
+ const requestLogID = 'log_' + ((Math.random() * (1 << 24)) | 0).toString(16).padStart(6, '0');
17584
+ const retryLogStr = retryOfRequestLogID === undefined ? '' : `, retryOf: ${retryOfRequestLogID}`;
17585
+ const startTime = Date.now();
17586
+ loggerFor(this).debug(`[${requestLogID}] sending request`, formatRequestDetails({
17587
+ retryOfRequestLogID,
17588
+ method: options.method,
17589
+ url,
17590
+ options,
17591
+ headers: req.headers,
17592
+ }));
17593
+ if ((_c = options.signal) === null || _c === void 0 ? void 0 : _c.aborted) {
17594
+ throw new APIUserAbortError();
17595
+ }
17596
+ const controller = new AbortController();
17597
+ const response = await this.fetchWithTimeout(url, req, timeout, controller).catch(castToError);
17598
+ const headersTime = Date.now();
17599
+ if (response instanceof globalThis.Error) {
17600
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
17601
+ if ((_d = options.signal) === null || _d === void 0 ? void 0 : _d.aborted) {
17602
+ throw new APIUserAbortError();
17603
+ }
17604
+ // detect native connection timeout errors
17605
+ // 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)"
17606
+ // undici throws "TypeError: fetch failed" with cause "ConnectTimeoutError: Connect Timeout Error (attempted address: example:443, timeout: 1ms)"
17607
+ // others do not provide enough information to distinguish timeouts from other connection errors
17608
+ const isTimeout = isAbortError(response) ||
17609
+ /timed? ?out/i.test(String(response) + ('cause' in response ? String(response.cause) : ''));
17610
+ if (retriesRemaining) {
17611
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - ${retryMessage}`);
17612
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (${retryMessage})`, formatRequestDetails({
17613
+ retryOfRequestLogID,
17614
+ url,
17615
+ durationMs: headersTime - startTime,
17616
+ message: response.message,
17617
+ }));
17618
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID !== null && retryOfRequestLogID !== void 0 ? retryOfRequestLogID : requestLogID);
17619
+ }
17620
+ loggerFor(this).info(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} - error; no more retries left`);
17621
+ loggerFor(this).debug(`[${requestLogID}] connection ${isTimeout ? 'timed out' : 'failed'} (error; no more retries left)`, formatRequestDetails({
17622
+ retryOfRequestLogID,
17623
+ url,
17624
+ durationMs: headersTime - startTime,
17625
+ message: response.message,
17626
+ }));
17627
+ if (isTimeout) {
17628
+ throw new APIConnectionTimeoutError();
17629
+ }
17630
+ throw new APIConnectionError({ cause: response });
17631
+ }
17632
+ const responseInfo = `[${requestLogID}${retryLogStr}] ${req.method} ${url} ${response.ok ? 'succeeded' : 'failed'} with status ${response.status} in ${headersTime - startTime}ms`;
17633
+ if (!response.ok) {
17634
+ const shouldRetry = await this.shouldRetry(response);
17635
+ if (retriesRemaining && shouldRetry) {
17636
+ const retryMessage = `retrying, ${retriesRemaining} attempts remaining`;
17637
+ // We don't need the body of this response.
17638
+ await CancelReadableStream(response.body);
17639
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
17640
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
17641
+ retryOfRequestLogID,
17642
+ url: response.url,
17643
+ status: response.status,
17644
+ headers: response.headers,
17645
+ durationMs: headersTime - startTime,
17646
+ }));
17647
+ return this.retryRequest(options, retriesRemaining, retryOfRequestLogID !== null && retryOfRequestLogID !== void 0 ? retryOfRequestLogID : requestLogID, response.headers);
17648
+ }
17649
+ const retryMessage = shouldRetry ? `error; no more retries left` : `error; not retryable`;
17650
+ loggerFor(this).info(`${responseInfo} - ${retryMessage}`);
17651
+ const errText = await response.text().catch((err) => castToError(err).message);
17652
+ const errJSON = safeJSON(errText);
17653
+ const errMessage = errJSON ? undefined : errText;
17654
+ loggerFor(this).debug(`[${requestLogID}] response error (${retryMessage})`, formatRequestDetails({
17655
+ retryOfRequestLogID,
17656
+ url: response.url,
17657
+ status: response.status,
17658
+ headers: response.headers,
17659
+ message: errMessage,
17660
+ durationMs: Date.now() - startTime,
17661
+ }));
17662
+ // @ts-ignore
17663
+ const err = this.makeStatusError(response.status, errJSON, errMessage, response.headers);
17664
+ throw err;
17665
+ }
17666
+ loggerFor(this).info(responseInfo);
17667
+ loggerFor(this).debug(`[${requestLogID}] response start`, formatRequestDetails({
17668
+ retryOfRequestLogID,
17669
+ url: response.url,
17670
+ status: response.status,
17671
+ headers: response.headers,
17672
+ durationMs: headersTime - startTime,
17673
+ }));
17674
+ return { response, options, controller, requestLogID, retryOfRequestLogID, startTime };
17675
+ }
17676
+ async fetchWithTimeout(url, init, ms, controller) {
17677
+ const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
17678
+ if (signal)
17679
+ signal.addEventListener('abort', () => controller.abort());
17680
+ const timeout = setTimeout(() => controller.abort(), ms);
17681
+ const isReadableBody = (globalThis.ReadableStream && options.body instanceof globalThis.ReadableStream) ||
17682
+ (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
17683
+ const fetchOptions = Object.assign(Object.assign(Object.assign({ signal: controller.signal }, (isReadableBody ? { duplex: 'half' } : {})), { method: 'GET' }), options);
17684
+ if (method) {
17685
+ // Custom methods like 'patch' need to be uppercased
17686
+ // See https://github.com/nodejs/undici/issues/2294
17687
+ fetchOptions.method = method.toUpperCase();
17688
+ }
17689
+ try {
17690
+ // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
17691
+ return await this.fetch.call(undefined, url, fetchOptions);
17692
+ }
17693
+ finally {
17694
+ clearTimeout(timeout);
17695
+ }
17696
+ }
17697
+ async shouldRetry(response) {
17698
+ // Note this is not a standard header.
17699
+ const shouldRetryHeader = response.headers.get('x-should-retry');
17700
+ // If the server explicitly says whether or not to retry, obey.
17701
+ if (shouldRetryHeader === 'true')
17702
+ return true;
17703
+ if (shouldRetryHeader === 'false')
17704
+ return false;
17705
+ // Retry on request timeouts.
17706
+ if (response.status === 408)
17707
+ return true;
17708
+ // Retry on lock timeouts.
17709
+ if (response.status === 409)
17710
+ return true;
17711
+ // Retry on rate limits.
17712
+ if (response.status === 429)
17713
+ return true;
17714
+ // Retry internal errors.
17715
+ if (response.status >= 500)
17716
+ return true;
17717
+ return false;
17718
+ }
17719
+ async retryRequest(options, retriesRemaining, requestLogID, responseHeaders) {
17720
+ var _b;
17721
+ let timeoutMillis;
17722
+ // Note the `retry-after-ms` header may not be standard, but is a good idea and we'd like proactive support for it.
17723
+ const retryAfterMillisHeader = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders.get('retry-after-ms');
17724
+ if (retryAfterMillisHeader) {
17725
+ const timeoutMs = parseFloat(retryAfterMillisHeader);
17726
+ if (!Number.isNaN(timeoutMs)) {
17727
+ timeoutMillis = timeoutMs;
17728
+ }
17729
+ }
17730
+ // About the Retry-After header: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
17731
+ const retryAfterHeader = responseHeaders === null || responseHeaders === void 0 ? void 0 : responseHeaders.get('retry-after');
17732
+ if (retryAfterHeader && !timeoutMillis) {
17733
+ const timeoutSeconds = parseFloat(retryAfterHeader);
17734
+ if (!Number.isNaN(timeoutSeconds)) {
17735
+ timeoutMillis = timeoutSeconds * 1000;
17736
+ }
17737
+ else {
17738
+ timeoutMillis = Date.parse(retryAfterHeader) - Date.now();
17739
+ }
17740
+ }
17741
+ // If the API asks us to wait a certain amount of time (and it's a reasonable amount),
17742
+ // just do what it says, but otherwise calculate a default
17743
+ if (!(timeoutMillis && 0 <= timeoutMillis && timeoutMillis < 60 * 1000)) {
17744
+ const maxRetries = (_b = options.maxRetries) !== null && _b !== void 0 ? _b : this.maxRetries;
17745
+ timeoutMillis = this.calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries);
17746
+ }
17747
+ await sleep$1(timeoutMillis);
17748
+ return this.makeRequest(options, retriesRemaining - 1, requestLogID);
17749
+ }
17750
+ calculateDefaultRetryTimeoutMillis(retriesRemaining, maxRetries) {
17751
+ const initialRetryDelay = 0.5;
17752
+ const maxRetryDelay = 8.0;
17753
+ const numRetries = maxRetries - retriesRemaining;
17754
+ // Apply exponential backoff, but not more than the max.
17755
+ const sleepSeconds = Math.min(initialRetryDelay * Math.pow(2, numRetries), maxRetryDelay);
17756
+ // Apply some jitter, take up to at most 25 percent of the retry time.
17757
+ const jitter = 1 - Math.random() * 0.25;
17758
+ return sleepSeconds * jitter * 1000;
17759
+ }
17760
+ async buildRequest(inputOptions, { retryCount = 0 } = {}) {
17761
+ var _b, _c, _d;
17762
+ const options = Object.assign({}, inputOptions);
17763
+ const { method, path, query, defaultBaseURL } = options;
17764
+ const url = this.buildURL(path, query, defaultBaseURL);
17765
+ if ('timeout' in options)
17766
+ validatePositiveInteger('timeout', options.timeout);
17767
+ options.timeout = (_b = options.timeout) !== null && _b !== void 0 ? _b : this.timeout;
17768
+ const { bodyHeaders, body } = this.buildBody({ options });
17769
+ const reqHeaders = await this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
17770
+ const req = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ method, headers: reqHeaders }, (options.signal && { signal: options.signal })), (globalThis.ReadableStream &&
17771
+ body instanceof globalThis.ReadableStream && { duplex: 'half' })), (body && { body })), ((_c = this.fetchOptions) !== null && _c !== void 0 ? _c : {})), ((_d = options.fetchOptions) !== null && _d !== void 0 ? _d : {}));
17772
+ return { req, url, timeout: options.timeout };
17773
+ }
17774
+ async buildHeaders({ options, method, bodyHeaders, retryCount, }) {
17775
+ let idempotencyHeaders = {};
17776
+ if (this.idempotencyHeader && method !== 'get') {
17777
+ if (!options.idempotencyKey)
17778
+ options.idempotencyKey = this.defaultIdempotencyKey();
17779
+ idempotencyHeaders[this.idempotencyHeader] = options.idempotencyKey;
17780
+ }
17781
+ const headers = buildHeaders([
17782
+ idempotencyHeaders,
17783
+ 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()),
17784
+ await this.authHeaders(options),
17785
+ this._options.defaultHeaders,
17786
+ bodyHeaders,
17787
+ options.headers,
17788
+ ]);
17789
+ this.validateHeaders(headers);
17790
+ return headers.values;
17791
+ }
17792
+ buildBody({ options: { body, headers: rawHeaders } }) {
17793
+ if (!body) {
17794
+ return { bodyHeaders: undefined, body: undefined };
17795
+ }
17796
+ const headers = buildHeaders([rawHeaders]);
17797
+ if (
17798
+ // Pass raw type verbatim
17799
+ ArrayBuffer.isView(body) ||
17800
+ body instanceof ArrayBuffer ||
17801
+ body instanceof DataView ||
17802
+ (typeof body === 'string' &&
17803
+ // Preserve legacy string encoding behavior for now
17804
+ headers.values.has('content-type')) ||
17805
+ // `Blob` is superset of `File`
17806
+ (globalThis.Blob && body instanceof globalThis.Blob) ||
17807
+ // `FormData` -> `multipart/form-data`
17808
+ body instanceof FormData ||
17809
+ // `URLSearchParams` -> `application/x-www-form-urlencoded`
17810
+ body instanceof URLSearchParams ||
17811
+ // Send chunked stream (each chunk has own `length`)
17812
+ (globalThis.ReadableStream && body instanceof globalThis.ReadableStream)) {
17813
+ return { bodyHeaders: undefined, body: body };
17814
+ }
17815
+ else if (typeof body === 'object' &&
17816
+ (Symbol.asyncIterator in body ||
17817
+ (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
17818
+ return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
17819
+ }
17820
+ else {
17821
+ return this.encoder({ body, headers });
17822
+ }
17823
+ }
17824
+ }
17825
+ BaseGeminiNextGenAPIClient.DEFAULT_TIMEOUT = 60000; // 1 minute
17826
+ /**
17827
+ * API Client for interfacing with the Gemini Next Gen API API.
17828
+ */
17829
+ class GeminiNextGenAPIClient extends BaseGeminiNextGenAPIClient {
17830
+ constructor() {
17831
+ super(...arguments);
17832
+ this.interactions = new Interactions(this);
17833
+ }
17834
+ }
17835
+ _a = GeminiNextGenAPIClient;
17836
+ GeminiNextGenAPIClient.GeminiNextGenAPIClient = _a;
17837
+ GeminiNextGenAPIClient.GeminiNextGenAPIClientError = GeminiNextGenAPIClientError;
17838
+ GeminiNextGenAPIClient.APIError = APIError;
17839
+ GeminiNextGenAPIClient.APIConnectionError = APIConnectionError;
17840
+ GeminiNextGenAPIClient.APIConnectionTimeoutError = APIConnectionTimeoutError;
17841
+ GeminiNextGenAPIClient.APIUserAbortError = APIUserAbortError;
17842
+ GeminiNextGenAPIClient.NotFoundError = NotFoundError;
17843
+ GeminiNextGenAPIClient.ConflictError = ConflictError;
17844
+ GeminiNextGenAPIClient.RateLimitError = RateLimitError;
17845
+ GeminiNextGenAPIClient.BadRequestError = BadRequestError;
17846
+ GeminiNextGenAPIClient.AuthenticationError = AuthenticationError;
17847
+ GeminiNextGenAPIClient.InternalServerError = InternalServerError;
17848
+ GeminiNextGenAPIClient.PermissionDeniedError = PermissionDeniedError;
17849
+ GeminiNextGenAPIClient.UnprocessableEntityError = UnprocessableEntityError;
17850
+ GeminiNextGenAPIClient.toFile = toFile;
17851
+ GeminiNextGenAPIClient.Interactions = Interactions;
17852
+
17853
+ /**
17854
+ * @license
17855
+ * Copyright 2025 Google LLC
17856
+ * SPDX-License-Identifier: Apache-2.0
17857
+ */
17858
+ const GOOGLE_API_KEY_HEADER = 'x-goog-api-key';
17859
+ const REQUIRED_VERTEX_AI_SCOPE = 'https://www.googleapis.com/auth/cloud-platform';
17860
+ class NodeAuth {
17861
+ constructor(opts) {
17862
+ if (opts.apiKey !== undefined) {
17863
+ this.apiKey = opts.apiKey;
17864
+ return;
17865
+ }
17866
+ const vertexAuthOptions = buildGoogleAuthOptions(opts.googleAuthOptions);
17867
+ this.googleAuth = new GoogleAuth(vertexAuthOptions);
17868
+ }
17869
+ async addAuthHeaders(headers, url) {
17870
+ if (this.apiKey !== undefined) {
17871
+ if (this.apiKey.startsWith('auth_tokens/')) {
17872
+ throw new Error('Ephemeral tokens are only supported by the live API.');
17873
+ }
17874
+ this.addKeyHeader(headers);
17875
+ return;
17876
+ }
17877
+ return this.addGoogleAuthHeaders(headers, url);
17878
+ }
17879
+ addKeyHeader(headers) {
17880
+ if (headers.get(GOOGLE_API_KEY_HEADER) !== null) {
17881
+ return;
17882
+ }
17883
+ if (this.apiKey === undefined) {
17884
+ // This should never happen, this method is only called
17885
+ // when apiKey is set.
17886
+ throw new Error('Trying to set API key header but apiKey is not set');
17887
+ }
17888
+ headers.append(GOOGLE_API_KEY_HEADER, this.apiKey);
17889
+ }
17890
+ async addGoogleAuthHeaders(headers, url) {
17891
+ if (this.googleAuth === undefined) {
17892
+ // This should never happen, addGoogleAuthHeaders should only be
17893
+ // called when there is no apiKey set and in these cases googleAuth
17894
+ // is set.
17895
+ throw new Error('Trying to set google-auth headers but googleAuth is unset');
17896
+ }
17897
+ const authHeaders = await this.googleAuth.getRequestHeaders(url);
17898
+ for (const [key, value] of authHeaders) {
17899
+ if (headers.get(key) !== null) {
17900
+ continue;
17901
+ }
17902
+ headers.append(key, value);
17903
+ }
17904
+ }
17905
+ }
17906
+ function buildGoogleAuthOptions(googleAuthOptions) {
17907
+ let authOptions;
17908
+ if (!googleAuthOptions) {
17909
+ authOptions = {
17910
+ scopes: [REQUIRED_VERTEX_AI_SCOPE],
17911
+ };
17912
+ return authOptions;
17913
+ }
17914
+ else {
17915
+ authOptions = googleAuthOptions;
17916
+ if (!authOptions.scopes) {
17917
+ authOptions.scopes = [REQUIRED_VERTEX_AI_SCOPE];
17918
+ return authOptions;
17919
+ }
17920
+ else if ((typeof authOptions.scopes === 'string' &&
17921
+ authOptions.scopes !== REQUIRED_VERTEX_AI_SCOPE) ||
17922
+ (Array.isArray(authOptions.scopes) &&
17923
+ authOptions.scopes.indexOf(REQUIRED_VERTEX_AI_SCOPE) < 0)) {
17924
+ throw new Error(`Invalid auth scopes. Scopes must include: ${REQUIRED_VERTEX_AI_SCOPE}`);
17925
+ }
17926
+ return authOptions;
17927
+ }
17928
+ }
17929
+
17930
+ /**
17931
+ * @license
17932
+ * Copyright 2025 Google LLC
17933
+ * SPDX-License-Identifier: Apache-2.0
17934
+ */
17935
+ class NodeDownloader {
17936
+ async download(params, apiClient) {
17937
+ if (params.downloadPath) {
17938
+ const response = await downloadFile(params, apiClient);
17939
+ if (response instanceof HttpResponse) {
17940
+ const writer = createWriteStream(params.downloadPath);
17941
+ const body = Readable.fromWeb(response.responseInternal.body);
17942
+ body.pipe(writer);
17943
+ await finished(writer);
17944
+ }
17945
+ else {
17946
+ try {
17947
+ await writeFile(params.downloadPath, response, {
17948
+ encoding: 'base64',
17949
+ });
17950
+ }
17951
+ catch (error) {
17952
+ throw new Error(`Failed to write file to ${params.downloadPath}: ${error}`);
17953
+ }
17954
+ }
17955
+ }
17956
+ }
17957
+ }
17958
+ async function downloadFile(params, apiClient) {
17959
+ var _a, _b, _c;
17960
+ const name = tFileName(params.file);
17961
+ if (name !== undefined) {
17962
+ return await apiClient.request({
17963
+ path: `files/${name}:download`,
17964
+ httpMethod: 'GET',
17965
+ queryParams: {
17966
+ 'alt': 'media',
17967
+ },
17968
+ httpOptions: (_a = params.config) === null || _a === void 0 ? void 0 : _a.httpOptions,
17969
+ abortSignal: (_b = params.config) === null || _b === void 0 ? void 0 : _b.abortSignal,
17970
+ });
17971
+ }
17972
+ else if (isGeneratedVideo(params.file)) {
17973
+ const videoBytes = (_c = params.file.video) === null || _c === void 0 ? void 0 : _c.videoBytes;
17974
+ if (typeof videoBytes === 'string') {
17975
+ return videoBytes;
17976
+ }
17977
+ else {
17978
+ throw new Error('Failed to download generated video, Uri or videoBytes not found.');
17979
+ }
17980
+ }
17981
+ else if (isVideo(params.file)) {
17982
+ const videoBytes = params.file.videoBytes;
17983
+ if (typeof videoBytes === 'string') {
17984
+ return videoBytes;
17985
+ }
17986
+ else {
17987
+ throw new Error('Failed to download video, Uri or videoBytes not found.');
17988
+ }
17989
+ }
17990
+ else {
17991
+ throw new Error('Unsupported file type');
17992
+ }
17993
+ }
17994
+
17995
+ /**
17996
+ * @license
17997
+ * Copyright 2025 Google LLC
17998
+ * SPDX-License-Identifier: Apache-2.0
17999
+ */
18000
+ class NodeWebSocketFactory {
18001
+ create(url, headers, callbacks) {
18002
+ return new NodeWebSocket(url, headers, callbacks);
18003
+ }
18004
+ }
18005
+ class NodeWebSocket {
18006
+ constructor(url, headers, callbacks) {
18007
+ this.url = url;
18008
+ this.headers = headers;
18009
+ this.callbacks = callbacks;
18010
+ }
18011
+ connect() {
18012
+ this.ws = new NodeWs.WebSocket(this.url, { headers: this.headers });
18013
+ this.ws.onopen = this.callbacks.onopen;
18014
+ this.ws.onerror = this.callbacks.onerror;
18015
+ this.ws.onclose = this.callbacks.onclose;
18016
+ this.ws.onmessage = this.callbacks.onmessage;
18017
+ }
18018
+ send(message) {
18019
+ if (this.ws === undefined) {
18020
+ throw new Error('WebSocket is not connected');
18021
+ }
18022
+ this.ws.send(message);
18023
+ }
18024
+ close() {
18025
+ if (this.ws === undefined) {
18026
+ throw new Error('WebSocket is not connected');
18027
+ }
18028
+ this.ws.close();
18029
+ }
18030
+ }
18031
+
18032
+ /**
18033
+ * @license
18034
+ * Copyright 2025 Google LLC
18035
+ * SPDX-License-Identifier: Apache-2.0
18036
+ */
18037
+ // Code generated by the Google Gen AI SDK generator DO NOT EDIT.
18038
+ function cancelTuningJobParametersToMldev(fromObject, _rootObject) {
18039
+ const toObject = {};
18040
+ const fromName = getValueByPath(fromObject, ['name']);
18041
+ if (fromName != null) {
18042
+ setValueByPath(toObject, ['_url', 'name'], fromName);
18043
+ }
18044
+ return toObject;
18045
+ }
18046
+ function cancelTuningJobParametersToVertex(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 cancelTuningJobResponseFromMldev(fromObject, _rootObject) {
15994
18055
  const toObject = {};
15995
18056
  const fromSdkHttpResponse = getValueByPath(fromObject, [
15996
18057
  'sdkHttpResponse',
@@ -17273,7 +19334,7 @@ class NodeUploader {
17273
19334
  let response = new HttpResponse(new Response());
17274
19335
  let uploadCommand = 'upload';
17275
19336
  let fileHandle;
17276
- const fileName = path.basename(file);
19337
+ const fileName = path$1.basename(file);
17277
19338
  try {
17278
19339
  fileHandle = await fs.open(file, 'r');
17279
19340
  if (!fileHandle) {
@@ -17384,6 +19445,28 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
17384
19445
  *
17385
19446
  */
17386
19447
  class GoogleGenAI {
19448
+ get interactions() {
19449
+ if (this._interactions !== undefined) {
19450
+ return this._interactions;
19451
+ }
19452
+ console.warn('GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions.');
19453
+ if (this.vertexai) {
19454
+ throw new Error('This version of the GenAI SDK does not support Vertex AI API for interactions.');
19455
+ }
19456
+ const httpOpts = this.httpOptions;
19457
+ // Unsupported Options Warnings
19458
+ if (httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.extraBody) {
19459
+ console.warn('GoogleGenAI.interactions: Client level httpOptions.extraBody is not supported by the interactions client and will be ignored.');
19460
+ }
19461
+ const nextGenClient = new GeminiNextGenAPIClient({
19462
+ baseURL: this.apiClient.getBaseUrl(),
19463
+ apiKey: this.apiKey,
19464
+ defaultHeaders: this.apiClient.getDefaultHeaders(),
19465
+ timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19466
+ });
19467
+ this._interactions = nextGenClient.interactions;
19468
+ return this._interactions;
19469
+ }
17387
19470
  constructor(options) {
17388
19471
  var _a, _b, _c, _d, _e, _f;
17389
19472
  // Validate explicitly set initializer values.
@@ -17491,5 +19574,5 @@ function getApiKeyFromEnv() {
17491
19574
  return envGoogleApiKey || envGeminiApiKey || undefined;
17492
19575
  }
17493
19576
 
17494
- 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 };
19577
+ 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 };
17495
19578
  //# sourceMappingURL=index.mjs.map