@google/genai 1.40.0 → 1.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict';
2
2
 
3
+ var pRetry = require('p-retry');
4
+
3
5
  /**
4
6
  * @license
5
7
  * Copyright 2025 Google LLC
@@ -1328,6 +1330,18 @@ exports.Environment = void 0;
1328
1330
  */
1329
1331
  Environment["ENVIRONMENT_BROWSER"] = "ENVIRONMENT_BROWSER";
1330
1332
  })(exports.Environment || (exports.Environment = {}));
1333
+ /** Enum representing the Vertex embedding API to use. */
1334
+ exports.EmbeddingApiType = void 0;
1335
+ (function (EmbeddingApiType) {
1336
+ /**
1337
+ * predict API endpoint (default)
1338
+ */
1339
+ EmbeddingApiType["PREDICT"] = "PREDICT";
1340
+ /**
1341
+ * embedContent API Endpoint
1342
+ */
1343
+ EmbeddingApiType["EMBED_CONTENT"] = "EMBED_CONTENT";
1344
+ })(exports.EmbeddingApiType || (exports.EmbeddingApiType = {}));
1331
1345
  /** Enum that controls the safety filter level for objectionable content. */
1332
1346
  exports.SafetyFilterLevel = void 0;
1333
1347
  (function (SafetyFilterLevel) {
@@ -3359,6 +3373,10 @@ function tJobState(state) {
3359
3373
  return stateString;
3360
3374
  }
3361
3375
  }
3376
+ function tIsVertexEmbedContentModel(model) {
3377
+ return ((model.includes('gemini') && model !== 'gemini-embedding-001') ||
3378
+ model.includes('maas'));
3379
+ }
3362
3380
 
3363
3381
  /**
3364
3382
  * @license
@@ -6931,10 +6949,22 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
6931
6949
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
6932
6950
  const USER_AGENT_HEADER = 'User-Agent';
6933
6951
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
6934
- const SDK_VERSION = '1.40.0'; // x-release-please-version
6952
+ const SDK_VERSION = '1.42.0'; // x-release-please-version
6935
6953
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
6936
6954
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
6937
6955
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
6956
+ // Default retry options.
6957
+ // The config is based on https://cloud.google.com/storage/docs/retry-strategy.
6958
+ const DEFAULT_RETRY_ATTEMPTS = 5; // Including the initial call
6959
+ // LINT.IfChange
6960
+ const DEFAULT_RETRY_HTTP_STATUS_CODES = [
6961
+ 408, // Request timeout
6962
+ 429, // Too many requests
6963
+ 500, // Internal server error
6964
+ 502, // Bad gateway
6965
+ 503, // Service unavailable
6966
+ 504, // Gateway timeout
6967
+ ];
6938
6968
  /**
6939
6969
  * The ApiClient class is used to send requests to the Gemini API or Vertex AI
6940
6970
  * endpoints.
@@ -7319,8 +7349,25 @@ class ApiClient {
7319
7349
  });
7320
7350
  }
7321
7351
  async apiCall(url, requestInit) {
7322
- return fetch(url, requestInit).catch((e) => {
7323
- throw new Error(`exception ${e} sending request`);
7352
+ var _a;
7353
+ if (!this.clientOptions.httpOptions ||
7354
+ !this.clientOptions.httpOptions.retryOptions) {
7355
+ return fetch(url, requestInit);
7356
+ }
7357
+ const retryOptions = this.clientOptions.httpOptions.retryOptions;
7358
+ const runFetch = async () => {
7359
+ const response = await fetch(url, requestInit);
7360
+ if (response.ok) {
7361
+ return response;
7362
+ }
7363
+ if (DEFAULT_RETRY_HTTP_STATUS_CODES.includes(response.status)) {
7364
+ throw new Error(`Retryable HTTP Error: ${response.statusText}`);
7365
+ }
7366
+ throw new pRetry.AbortError(`Non-retryable exception ${response.statusText} sending request`);
7367
+ };
7368
+ return pRetry(runFetch, {
7369
+ // Retry attempts is one less than the number of total attempts.
7370
+ retries: ((_a = retryOptions.attempts) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_ATTEMPTS) - 1,
7324
7371
  });
7325
7372
  }
7326
7373
  getDefaultHeaders() {
@@ -10481,7 +10528,7 @@ class BaseGeminiNextGenAPIClient {
10481
10528
  }
10482
10529
  async fetchWithTimeout(url, init, ms, controller) {
10483
10530
  const _b = init || {}, { signal, method } = _b, options = __rest(_b, ["signal", "method"]);
10484
- const abort = controller.abort.bind(controller);
10531
+ const abort = this._makeAbort(controller);
10485
10532
  if (signal)
10486
10533
  signal.addEventListener('abort', abort, { once: true });
10487
10534
  const timeout = setTimeout(abort, ms);
@@ -10597,6 +10644,11 @@ class BaseGeminiNextGenAPIClient {
10597
10644
  this.validateHeaders(headers);
10598
10645
  return headers.values;
10599
10646
  }
10647
+ _makeAbort(controller) {
10648
+ // note: we can't just inline this method inside `fetchWithTimeout()` because then the closure
10649
+ // would capture all request options, and cause a memory leak.
10650
+ return () => controller.abort();
10651
+ }
10600
10652
  buildBody({ options: { body, headers: rawHeaders } }) {
10601
10653
  if (!body) {
10602
10654
  return { bodyHeaders: undefined, body: undefined };
@@ -10625,6 +10677,13 @@ class BaseGeminiNextGenAPIClient {
10625
10677
  (Symbol.iterator in body && 'next' in body && typeof body.next === 'function'))) {
10626
10678
  return { bodyHeaders: undefined, body: ReadableStreamFrom(body) };
10627
10679
  }
10680
+ else if (typeof body === 'object' &&
10681
+ headers.values.get('content-type') === 'application/x-www-form-urlencoded') {
10682
+ return {
10683
+ bodyHeaders: { 'content-type': 'application/x-www-form-urlencoded' },
10684
+ body: this.stringifyQuery(body),
10685
+ };
10686
+ }
10628
10687
  else {
10629
10688
  return this.encoder({ body, headers });
10630
10689
  }
@@ -12128,33 +12187,103 @@ function embedContentConfigToMldev(fromObject, parentObject, _rootObject) {
12128
12187
  }
12129
12188
  return toObject;
12130
12189
  }
12131
- function embedContentConfigToVertex(fromObject, parentObject, _rootObject) {
12190
+ function embedContentConfigToVertex(fromObject, parentObject, rootObject) {
12132
12191
  const toObject = {};
12133
- const fromTaskType = getValueByPath(fromObject, ['taskType']);
12134
- if (parentObject !== undefined && fromTaskType != null) {
12135
- setValueByPath(parentObject, ['instances[]', 'task_type'], fromTaskType);
12192
+ let discriminatorTaskType = getValueByPath(rootObject, [
12193
+ 'embeddingApiType',
12194
+ ]);
12195
+ if (discriminatorTaskType === undefined) {
12196
+ discriminatorTaskType = 'PREDICT';
12136
12197
  }
12137
- const fromTitle = getValueByPath(fromObject, ['title']);
12138
- if (parentObject !== undefined && fromTitle != null) {
12139
- setValueByPath(parentObject, ['instances[]', 'title'], fromTitle);
12198
+ if (discriminatorTaskType === 'PREDICT') {
12199
+ const fromTaskType = getValueByPath(fromObject, ['taskType']);
12200
+ if (parentObject !== undefined && fromTaskType != null) {
12201
+ setValueByPath(parentObject, ['instances[]', 'task_type'], fromTaskType);
12202
+ }
12140
12203
  }
12141
- const fromOutputDimensionality = getValueByPath(fromObject, [
12142
- 'outputDimensionality',
12204
+ else if (discriminatorTaskType === 'EMBED_CONTENT') {
12205
+ const fromTaskType = getValueByPath(fromObject, ['taskType']);
12206
+ if (parentObject !== undefined && fromTaskType != null) {
12207
+ setValueByPath(parentObject, ['taskType'], fromTaskType);
12208
+ }
12209
+ }
12210
+ let discriminatorTitle = getValueByPath(rootObject, [
12211
+ 'embeddingApiType',
12143
12212
  ]);
12144
- if (parentObject !== undefined && fromOutputDimensionality != null) {
12145
- setValueByPath(parentObject, ['parameters', 'outputDimensionality'], fromOutputDimensionality);
12213
+ if (discriminatorTitle === undefined) {
12214
+ discriminatorTitle = 'PREDICT';
12146
12215
  }
12147
- const fromMimeType = getValueByPath(fromObject, ['mimeType']);
12148
- if (parentObject !== undefined && fromMimeType != null) {
12149
- setValueByPath(parentObject, ['instances[]', 'mimeType'], fromMimeType);
12216
+ if (discriminatorTitle === 'PREDICT') {
12217
+ const fromTitle = getValueByPath(fromObject, ['title']);
12218
+ if (parentObject !== undefined && fromTitle != null) {
12219
+ setValueByPath(parentObject, ['instances[]', 'title'], fromTitle);
12220
+ }
12150
12221
  }
12151
- const fromAutoTruncate = getValueByPath(fromObject, ['autoTruncate']);
12152
- if (parentObject !== undefined && fromAutoTruncate != null) {
12153
- setValueByPath(parentObject, ['parameters', 'autoTruncate'], fromAutoTruncate);
12222
+ else if (discriminatorTitle === 'EMBED_CONTENT') {
12223
+ const fromTitle = getValueByPath(fromObject, ['title']);
12224
+ if (parentObject !== undefined && fromTitle != null) {
12225
+ setValueByPath(parentObject, ['title'], fromTitle);
12226
+ }
12227
+ }
12228
+ let discriminatorOutputDimensionality = getValueByPath(rootObject, [
12229
+ 'embeddingApiType',
12230
+ ]);
12231
+ if (discriminatorOutputDimensionality === undefined) {
12232
+ discriminatorOutputDimensionality = 'PREDICT';
12233
+ }
12234
+ if (discriminatorOutputDimensionality === 'PREDICT') {
12235
+ const fromOutputDimensionality = getValueByPath(fromObject, [
12236
+ 'outputDimensionality',
12237
+ ]);
12238
+ if (parentObject !== undefined && fromOutputDimensionality != null) {
12239
+ setValueByPath(parentObject, ['parameters', 'outputDimensionality'], fromOutputDimensionality);
12240
+ }
12241
+ }
12242
+ else if (discriminatorOutputDimensionality === 'EMBED_CONTENT') {
12243
+ const fromOutputDimensionality = getValueByPath(fromObject, [
12244
+ 'outputDimensionality',
12245
+ ]);
12246
+ if (parentObject !== undefined && fromOutputDimensionality != null) {
12247
+ setValueByPath(parentObject, ['outputDimensionality'], fromOutputDimensionality);
12248
+ }
12249
+ }
12250
+ let discriminatorMimeType = getValueByPath(rootObject, [
12251
+ 'embeddingApiType',
12252
+ ]);
12253
+ if (discriminatorMimeType === undefined) {
12254
+ discriminatorMimeType = 'PREDICT';
12255
+ }
12256
+ if (discriminatorMimeType === 'PREDICT') {
12257
+ const fromMimeType = getValueByPath(fromObject, ['mimeType']);
12258
+ if (parentObject !== undefined && fromMimeType != null) {
12259
+ setValueByPath(parentObject, ['instances[]', 'mimeType'], fromMimeType);
12260
+ }
12261
+ }
12262
+ let discriminatorAutoTruncate = getValueByPath(rootObject, [
12263
+ 'embeddingApiType',
12264
+ ]);
12265
+ if (discriminatorAutoTruncate === undefined) {
12266
+ discriminatorAutoTruncate = 'PREDICT';
12267
+ }
12268
+ if (discriminatorAutoTruncate === 'PREDICT') {
12269
+ const fromAutoTruncate = getValueByPath(fromObject, [
12270
+ 'autoTruncate',
12271
+ ]);
12272
+ if (parentObject !== undefined && fromAutoTruncate != null) {
12273
+ setValueByPath(parentObject, ['parameters', 'autoTruncate'], fromAutoTruncate);
12274
+ }
12275
+ }
12276
+ else if (discriminatorAutoTruncate === 'EMBED_CONTENT') {
12277
+ const fromAutoTruncate = getValueByPath(fromObject, [
12278
+ 'autoTruncate',
12279
+ ]);
12280
+ if (parentObject !== undefined && fromAutoTruncate != null) {
12281
+ setValueByPath(parentObject, ['autoTruncate'], fromAutoTruncate);
12282
+ }
12154
12283
  }
12155
12284
  return toObject;
12156
12285
  }
12157
- function embedContentParametersToMldev(apiClient, fromObject, rootObject) {
12286
+ function embedContentParametersPrivateToMldev(apiClient, fromObject, rootObject) {
12158
12287
  const toObject = {};
12159
12288
  const fromModel = getValueByPath(fromObject, ['model']);
12160
12289
  if (fromModel != null) {
@@ -12170,6 +12299,10 @@ function embedContentParametersToMldev(apiClient, fromObject, rootObject) {
12170
12299
  }
12171
12300
  setValueByPath(toObject, ['requests[]', 'content'], transformedList);
12172
12301
  }
12302
+ const fromContent = getValueByPath(fromObject, ['content']);
12303
+ if (fromContent != null) {
12304
+ contentToMldev$1(tContent(fromContent));
12305
+ }
12173
12306
  const fromConfig = getValueByPath(fromObject, ['config']);
12174
12307
  if (fromConfig != null) {
12175
12308
  embedContentConfigToMldev(fromConfig, toObject);
@@ -12180,25 +12313,45 @@ function embedContentParametersToMldev(apiClient, fromObject, rootObject) {
12180
12313
  }
12181
12314
  return toObject;
12182
12315
  }
12183
- function embedContentParametersToVertex(apiClient, fromObject, rootObject) {
12316
+ function embedContentParametersPrivateToVertex(apiClient, fromObject, rootObject) {
12184
12317
  const toObject = {};
12185
12318
  const fromModel = getValueByPath(fromObject, ['model']);
12186
12319
  if (fromModel != null) {
12187
12320
  setValueByPath(toObject, ['_url', 'model'], tModel(apiClient, fromModel));
12188
12321
  }
12189
- const fromContents = getValueByPath(fromObject, ['contents']);
12190
- if (fromContents != null) {
12191
- let transformedList = tContentsForEmbed(apiClient, fromContents);
12192
- if (Array.isArray(transformedList)) {
12193
- transformedList = transformedList.map((item) => {
12194
- return item;
12195
- });
12322
+ let discriminatorContents = getValueByPath(rootObject, [
12323
+ 'embeddingApiType',
12324
+ ]);
12325
+ if (discriminatorContents === undefined) {
12326
+ discriminatorContents = 'PREDICT';
12327
+ }
12328
+ if (discriminatorContents === 'PREDICT') {
12329
+ const fromContents = getValueByPath(fromObject, ['contents']);
12330
+ if (fromContents != null) {
12331
+ let transformedList = tContentsForEmbed(apiClient, fromContents);
12332
+ if (Array.isArray(transformedList)) {
12333
+ transformedList = transformedList.map((item) => {
12334
+ return item;
12335
+ });
12336
+ }
12337
+ setValueByPath(toObject, ['instances[]', 'content'], transformedList);
12338
+ }
12339
+ }
12340
+ let discriminatorContent = getValueByPath(rootObject, [
12341
+ 'embeddingApiType',
12342
+ ]);
12343
+ if (discriminatorContent === undefined) {
12344
+ discriminatorContent = 'PREDICT';
12345
+ }
12346
+ if (discriminatorContent === 'EMBED_CONTENT') {
12347
+ const fromContent = getValueByPath(fromObject, ['content']);
12348
+ if (fromContent != null) {
12349
+ setValueByPath(toObject, ['content'], tContent(fromContent));
12196
12350
  }
12197
- setValueByPath(toObject, ['instances[]', 'content'], transformedList);
12198
12351
  }
12199
12352
  const fromConfig = getValueByPath(fromObject, ['config']);
12200
12353
  if (fromConfig != null) {
12201
- embedContentConfigToVertex(fromConfig, toObject);
12354
+ embedContentConfigToVertex(fromConfig, toObject, rootObject);
12202
12355
  }
12203
12356
  return toObject;
12204
12357
  }
@@ -12251,6 +12404,24 @@ function embedContentResponseFromVertex(fromObject, rootObject) {
12251
12404
  if (fromMetadata != null) {
12252
12405
  setValueByPath(toObject, ['metadata'], fromMetadata);
12253
12406
  }
12407
+ if (rootObject &&
12408
+ getValueByPath(rootObject, ['embeddingApiType']) === 'EMBED_CONTENT') {
12409
+ const embedding = getValueByPath(fromObject, ['embedding']);
12410
+ const usageMetadata = getValueByPath(fromObject, ['usageMetadata']);
12411
+ const truncated = getValueByPath(fromObject, ['truncated']);
12412
+ if (embedding) {
12413
+ const stats = {};
12414
+ if (usageMetadata &&
12415
+ usageMetadata['promptTokenCount']) {
12416
+ stats.tokenCount = usageMetadata['promptTokenCount'];
12417
+ }
12418
+ if (truncated) {
12419
+ stats.truncated = truncated;
12420
+ }
12421
+ embedding.statistics = stats;
12422
+ setValueByPath(toObject, ['embeddings'], [embedding]);
12423
+ }
12424
+ }
12254
12425
  return toObject;
12255
12426
  }
12256
12427
  function endpointFromVertex(fromObject, _rootObject) {
@@ -15799,6 +15970,47 @@ class Models extends BaseModule {
15799
15970
  constructor(apiClient) {
15800
15971
  super();
15801
15972
  this.apiClient = apiClient;
15973
+ /**
15974
+ * Calculates embeddings for the given contents.
15975
+ *
15976
+ * @param params - The parameters for embedding contents.
15977
+ * @return The response from the API.
15978
+ *
15979
+ * @example
15980
+ * ```ts
15981
+ * const response = await ai.models.embedContent({
15982
+ * model: 'text-embedding-004',
15983
+ * contents: [
15984
+ * 'What is your name?',
15985
+ * 'What is your favorite color?',
15986
+ * ],
15987
+ * config: {
15988
+ * outputDimensionality: 64,
15989
+ * },
15990
+ * });
15991
+ * console.log(response);
15992
+ * ```
15993
+ */
15994
+ this.embedContent = async (params) => {
15995
+ if (!this.apiClient.isVertexAI()) {
15996
+ return await this.embedContentInternal(params);
15997
+ }
15998
+ const isVertexEmbedContentModel = (params.model.includes('gemini') &&
15999
+ params.model !== 'gemini-embedding-001') ||
16000
+ params.model.includes('maas');
16001
+ if (isVertexEmbedContentModel) {
16002
+ const contents = tContents(params.contents);
16003
+ if (contents.length > 1) {
16004
+ throw new Error('The embedContent API for this model only supports one content at a time.');
16005
+ }
16006
+ const paramsPrivate = Object.assign(Object.assign({}, params), { content: contents[0], embeddingApiType: exports.EmbeddingApiType.EMBED_CONTENT });
16007
+ return await this.embedContentInternal(paramsPrivate);
16008
+ }
16009
+ else {
16010
+ const paramsPrivate = Object.assign(Object.assign({}, params), { embeddingApiType: exports.EmbeddingApiType.PREDICT });
16011
+ return await this.embedContentInternal(paramsPrivate);
16012
+ }
16013
+ };
15802
16014
  /**
15803
16015
  * Makes an API request to generate content with a given model.
15804
16016
  *
@@ -16486,14 +16698,17 @@ class Models extends BaseModule {
16486
16698
  * console.log(response);
16487
16699
  * ```
16488
16700
  */
16489
- async embedContent(params) {
16701
+ async embedContentInternal(params) {
16490
16702
  var _a, _b, _c, _d;
16491
16703
  let response;
16492
16704
  let path = '';
16493
16705
  let queryParams = {};
16494
16706
  if (this.apiClient.isVertexAI()) {
16495
- const body = embedContentParametersToVertex(this.apiClient, params);
16496
- path = formatMap('{model}:predict', body['_url']);
16707
+ const body = embedContentParametersPrivateToVertex(this.apiClient, params, params);
16708
+ const endpointUrl = tIsVertexEmbedContentModel(params.model)
16709
+ ? '{model}:embedContent'
16710
+ : '{model}:predict';
16711
+ path = formatMap(endpointUrl, body['_url']);
16497
16712
  queryParams = body['_query'];
16498
16713
  delete body['_url'];
16499
16714
  delete body['_query'];
@@ -16516,14 +16731,14 @@ class Models extends BaseModule {
16516
16731
  });
16517
16732
  });
16518
16733
  return response.then((apiResponse) => {
16519
- const resp = embedContentResponseFromVertex(apiResponse);
16734
+ const resp = embedContentResponseFromVertex(apiResponse, params);
16520
16735
  const typedResp = new EmbedContentResponse();
16521
16736
  Object.assign(typedResp, resp);
16522
16737
  return typedResp;
16523
16738
  });
16524
16739
  }
16525
16740
  else {
16526
- const body = embedContentParametersToMldev(this.apiClient, params);
16741
+ const body = embedContentParametersPrivateToMldev(this.apiClient, params);
16527
16742
  path = formatMap('{model}:batchEmbedContents', body['_url']);
16528
16743
  queryParams = body['_query'];
16529
16744
  delete body['_url'];
@@ -18251,6 +18466,9 @@ function createTuningJobConfigToMldev(fromObject, parentObject, _rootObject) {
18251
18466
  if (getValueByPath(fromObject, ['outputUri']) !== undefined) {
18252
18467
  throw new Error('outputUri parameter is not supported in Gemini API.');
18253
18468
  }
18469
+ if (getValueByPath(fromObject, ['encryptionSpec']) !== undefined) {
18470
+ throw new Error('encryptionSpec parameter is not supported in Gemini API.');
18471
+ }
18254
18472
  return toObject;
18255
18473
  }
18256
18474
  function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
@@ -18486,6 +18704,12 @@ function createTuningJobConfigToVertex(fromObject, parentObject, rootObject) {
18486
18704
  if (parentObject !== undefined && fromOutputUri != null) {
18487
18705
  setValueByPath(parentObject, ['outputUri'], fromOutputUri);
18488
18706
  }
18707
+ const fromEncryptionSpec = getValueByPath(fromObject, [
18708
+ 'encryptionSpec',
18709
+ ]);
18710
+ if (parentObject !== undefined && fromEncryptionSpec != null) {
18711
+ setValueByPath(parentObject, ['encryptionSpec'], fromEncryptionSpec);
18712
+ }
18489
18713
  return toObject;
18490
18714
  }
18491
18715
  function createTuningJobParametersPrivateToMldev(fromObject, rootObject) {
@@ -19413,6 +19637,7 @@ const LANGUAGE_LABEL_PREFIX = 'gl-node/';
19413
19637
  */
19414
19638
  class GoogleGenAI {
19415
19639
  get interactions() {
19640
+ var _a;
19416
19641
  if (this._interactions !== undefined) {
19417
19642
  return this._interactions;
19418
19643
  }
@@ -19432,6 +19657,7 @@ class GoogleGenAI {
19432
19657
  clientAdapter: this.apiClient,
19433
19658
  defaultHeaders: this.apiClient.getDefaultHeaders(),
19434
19659
  timeout: httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.timeout,
19660
+ maxRetries: (_a = httpOpts === null || httpOpts === void 0 ? void 0 : httpOpts.retryOptions) === null || _a === void 0 ? void 0 : _a.attempts,
19435
19661
  });
19436
19662
  this._interactions = nextGenClient.interactions;
19437
19663
  return this._interactions;