@google/genai 2.2.0 → 2.4.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.mjs CHANGED
@@ -7594,7 +7594,7 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
7594
7594
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
7595
7595
  const USER_AGENT_HEADER = 'User-Agent';
7596
7596
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
7597
- const SDK_VERSION = '2.2.0'; // x-release-please-version
7597
+ const SDK_VERSION = '2.4.0'; // x-release-please-version
7598
7598
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
7599
7599
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
7600
7600
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
@@ -9561,7 +9561,9 @@ class APIConnectionError extends APIError {
9561
9561
  }
9562
9562
  class APIConnectionTimeoutError extends APIConnectionError {
9563
9563
  constructor({ message } = {}) {
9564
- super({ message: message !== null && message !== void 0 ? message : 'Request timed out.' });
9564
+ super({
9565
+ message: message !== null && message !== void 0 ? message : 'Request timed out. This is a client-side timeout. You can increase the timeout by setting the `timeout` argument in your request or client http options.',
9566
+ });
9565
9567
  }
9566
9568
  }
9567
9569
  class BadRequestError extends APIError {
@@ -9928,6 +9930,126 @@ class APIResource {
9928
9930
  */
9929
9931
  APIResource._key = [];
9930
9932
 
9933
+ /**
9934
+ * @license
9935
+ * Copyright 2025 Google LLC
9936
+ * SPDX-License-Identifier: Apache-2.0
9937
+ */
9938
+ /**
9939
+ * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
9940
+ *
9941
+ * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3:
9942
+ * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
9943
+ * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
9944
+ * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
9945
+ */
9946
+ function encodeURIPath(str) {
9947
+ return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
9948
+ }
9949
+ const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
9950
+ const createPathTagFunction = (pathEncoder = encodeURIPath) => (function path(statics, ...params) {
9951
+ // If there are no params, no processing is needed.
9952
+ if (statics.length === 1)
9953
+ return statics[0];
9954
+ let postPath = false;
9955
+ const invalidSegments = [];
9956
+ const path = statics.reduce((previousValue, currentValue, index) => {
9957
+ var _a, _b, _c;
9958
+ if (/[?#]/.test(currentValue)) {
9959
+ postPath = true;
9960
+ }
9961
+ const value = params[index];
9962
+ let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
9963
+ if (index !== params.length &&
9964
+ (value == null ||
9965
+ (typeof value === 'object' &&
9966
+ // handle values from other realms
9967
+ value.toString ===
9968
+ ((_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)))) {
9969
+ encoded = value + '';
9970
+ invalidSegments.push({
9971
+ start: previousValue.length + currentValue.length,
9972
+ length: encoded.length,
9973
+ error: `Value of type ${Object.prototype.toString
9974
+ .call(value)
9975
+ .slice(8, -1)} is not a valid path parameter`,
9976
+ });
9977
+ }
9978
+ return previousValue + currentValue + (index === params.length ? '' : encoded);
9979
+ }, '');
9980
+ const pathOnly = path.split(/[?#]/, 1)[0];
9981
+ const invalidSegmentPattern = /(^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
9982
+ let match;
9983
+ // Find all invalid segments
9984
+ while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
9985
+ const hasLeadingSlash = match[0].startsWith('/');
9986
+ const offset = hasLeadingSlash ? 1 : 0;
9987
+ const cleanMatch = hasLeadingSlash ? match[0].slice(1) : match[0];
9988
+ invalidSegments.push({
9989
+ start: match.index + offset,
9990
+ length: cleanMatch.length,
9991
+ error: `Value "${cleanMatch}" can\'t be safely passed as a path parameter`,
9992
+ });
9993
+ }
9994
+ invalidSegments.sort((a, b) => a.start - b.start);
9995
+ if (invalidSegments.length > 0) {
9996
+ let lastEnd = 0;
9997
+ const underline = invalidSegments.reduce((acc, segment) => {
9998
+ const spaces = ' '.repeat(segment.start - lastEnd);
9999
+ const arrows = '^'.repeat(segment.length);
10000
+ lastEnd = segment.start + segment.length;
10001
+ return acc + spaces + arrows;
10002
+ }, '');
10003
+ throw new GeminiNextGenAPIClientError(`Path parameters result in path with invalid segments:\n${invalidSegments
10004
+ .map((e) => e.error)
10005
+ .join('\n')}\n${path}\n${underline}`);
10006
+ }
10007
+ return path;
10008
+ });
10009
+ /**
10010
+ * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
10011
+ */
10012
+ const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
10013
+
10014
+ /**
10015
+ * @license
10016
+ * Copyright 2025 Google LLC
10017
+ * SPDX-License-Identifier: Apache-2.0
10018
+ */
10019
+ class BaseAgents extends APIResource {
10020
+ /**
10021
+ * Creates a new Agent (Typed version for SDK).
10022
+ */
10023
+ create(params = {}, options) {
10024
+ const _a = params !== null && params !== void 0 ? params : {}, { api_version = this._client.apiVersion } = _a, body = __rest(_a, ["api_version"]);
10025
+ return this._client.post(path `/${api_version}/agents`, Object.assign({ body }, options));
10026
+ }
10027
+ /**
10028
+ * Lists all Agents.
10029
+ */
10030
+ list(params = {}, options) {
10031
+ const _a = params !== null && params !== void 0 ? params : {}, { api_version = this._client.apiVersion } = _a, query = __rest(_a, ["api_version"]);
10032
+ return this._client.get(path `/${api_version}/agents`, Object.assign({ query }, options));
10033
+ }
10034
+ /**
10035
+ * Deletes an Agent.
10036
+ */
10037
+ delete(id, params = {}, options) {
10038
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
10039
+ return this._client.delete(path `/${api_version}/agents/${id}`, options);
10040
+ }
10041
+ /**
10042
+ * Gets a specific Agent.
10043
+ */
10044
+ get(id, params = {}, options) {
10045
+ const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
10046
+ return this._client.get(path `/${api_version}/agents/${id}`, options);
10047
+ }
10048
+ }
10049
+ BaseAgents._key = Object.freeze(['agents']);
10050
+ class Agents extends BaseAgents {
10051
+ }
10052
+
9931
10053
  /**
9932
10054
  * @license
9933
10055
  * Copyright 2025 Google LLC
@@ -10589,87 +10711,6 @@ class LegacyLyriaStream extends Stream {
10589
10711
  }
10590
10712
  }
10591
10713
 
10592
- /**
10593
- * @license
10594
- * Copyright 2025 Google LLC
10595
- * SPDX-License-Identifier: Apache-2.0
10596
- */
10597
- /**
10598
- * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
10599
- *
10600
- * Taken from https://datatracker.ietf.org/doc/html/rfc3986#section-3.3:
10601
- * > unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
10602
- * > sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
10603
- * > pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
10604
- */
10605
- function encodeURIPath(str) {
10606
- return str.replace(/[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/g, encodeURIComponent);
10607
- }
10608
- const EMPTY = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.create(null));
10609
- const createPathTagFunction = (pathEncoder = encodeURIPath) => (function path(statics, ...params) {
10610
- // If there are no params, no processing is needed.
10611
- if (statics.length === 1)
10612
- return statics[0];
10613
- let postPath = false;
10614
- const invalidSegments = [];
10615
- const path = statics.reduce((previousValue, currentValue, index) => {
10616
- var _a, _b, _c;
10617
- if (/[?#]/.test(currentValue)) {
10618
- postPath = true;
10619
- }
10620
- const value = params[index];
10621
- let encoded = (postPath ? encodeURIComponent : pathEncoder)('' + value);
10622
- if (index !== params.length &&
10623
- (value == null ||
10624
- (typeof value === 'object' &&
10625
- // handle values from other realms
10626
- value.toString ===
10627
- ((_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)))) {
10628
- encoded = value + '';
10629
- invalidSegments.push({
10630
- start: previousValue.length + currentValue.length,
10631
- length: encoded.length,
10632
- error: `Value of type ${Object.prototype.toString
10633
- .call(value)
10634
- .slice(8, -1)} is not a valid path parameter`,
10635
- });
10636
- }
10637
- return previousValue + currentValue + (index === params.length ? '' : encoded);
10638
- }, '');
10639
- const pathOnly = path.split(/[?#]/, 1)[0];
10640
- const invalidSegmentPattern = /(^|\/)(?:\.|%2e){1,2}(?=\/|$)/gi;
10641
- let match;
10642
- // Find all invalid segments
10643
- while ((match = invalidSegmentPattern.exec(pathOnly)) !== null) {
10644
- const hasLeadingSlash = match[0].startsWith('/');
10645
- const offset = hasLeadingSlash ? 1 : 0;
10646
- const cleanMatch = hasLeadingSlash ? match[0].slice(1) : match[0];
10647
- invalidSegments.push({
10648
- start: match.index + offset,
10649
- length: cleanMatch.length,
10650
- error: `Value "${cleanMatch}" can\'t be safely passed as a path parameter`,
10651
- });
10652
- }
10653
- invalidSegments.sort((a, b) => a.start - b.start);
10654
- if (invalidSegments.length > 0) {
10655
- let lastEnd = 0;
10656
- const underline = invalidSegments.reduce((acc, segment) => {
10657
- const spaces = ' '.repeat(segment.start - lastEnd);
10658
- const arrows = '^'.repeat(segment.length);
10659
- lastEnd = segment.start + segment.length;
10660
- return acc + spaces + arrows;
10661
- }, '');
10662
- throw new GeminiNextGenAPIClientError(`Path parameters result in path with invalid segments:\n${invalidSegments
10663
- .map((e) => e.error)
10664
- .join('\n')}\n${path}\n${underline}`);
10665
- }
10666
- return path;
10667
- });
10668
- /**
10669
- * URI-encodes path params and ensures no unsafe /./ or /../ path segments are introduced.
10670
- */
10671
- const path = /* @__PURE__ */ createPathTagFunction(encodeURIPath);
10672
-
10673
10714
  /**
10674
10715
  * @license
10675
10716
  * Copyright 2025 Google LLC
@@ -10691,10 +10732,14 @@ class BaseInteractions extends APIResource {
10691
10732
  });
10692
10733
  const isStreaming = (_a = params.stream) !== null && _a !== void 0 ? _a : false;
10693
10734
  const promise = this._client.post(path `/${api_version}/interactions`, Object.assign(Object.assign(Object.assign({ body }, options), { stream: isStreaming }), (needsLegacyLyriaShim && isStreaming ? { __streamClass: LegacyLyriaStream } : {})));
10694
- if (needsLegacyLyriaShim && !isStreaming) {
10695
- return promise._thenUnwrap((data) => coerceLegacyInteractionResponse(data));
10735
+ if (isStreaming) {
10736
+ return promise;
10696
10737
  }
10697
- return promise;
10738
+ let nonStreaming = promise;
10739
+ if (needsLegacyLyriaShim) {
10740
+ nonStreaming = nonStreaming._thenUnwrap((data) => coerceLegacyInteractionResponse(data));
10741
+ }
10742
+ return nonStreaming._thenUnwrap(addOutputProperties);
10698
10743
  }
10699
10744
  /**
10700
10745
  * Deletes the interaction by id.
@@ -10723,17 +10768,78 @@ class BaseInteractions extends APIResource {
10723
10768
  */
10724
10769
  cancel(id, params = {}, options) {
10725
10770
  const { api_version = this._client.apiVersion } = params !== null && params !== void 0 ? params : {};
10726
- return this._client.post(path `/${api_version}/interactions/${id}/cancel`, options);
10771
+ return this._client.post(path `/${api_version}/interactions/${id}/cancel`, options)._thenUnwrap(addOutputProperties);
10727
10772
  }
10728
10773
  get(id, params = {}, options) {
10729
10774
  var _a;
10730
10775
  const _b = params !== null && params !== void 0 ? params : {}, { api_version = this._client.apiVersion } = _b, query = __rest(_b, ["api_version"]);
10731
- 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 }));
10776
+ const response = 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 }));
10777
+ if (params === null || params === void 0 ? void 0 : params.stream) {
10778
+ return response;
10779
+ }
10780
+ return response._thenUnwrap(addOutputProperties);
10732
10781
  }
10733
10782
  }
10734
10783
  BaseInteractions._key = Object.freeze(['interactions']);
10735
10784
  class Interactions extends BaseInteractions {
10736
10785
  }
10786
+ function addOutputProperties(interaction) {
10787
+ var _a, _b;
10788
+ const steps = (_a = interaction.steps) !== null && _a !== void 0 ? _a : [];
10789
+ // output_text: scan backwards across all steps (stopping at user_input),
10790
+ // skip non-text content until the first text item is found, then collect
10791
+ // text until a non-text barrier is hit.
10792
+ const textParts = [];
10793
+ let collecting = false;
10794
+ outer: for (let i = steps.length - 1; i >= 0; i--) {
10795
+ const step = steps[i];
10796
+ if (step.type === 'user_input')
10797
+ break;
10798
+ if (step.type !== 'model_output' || !step.content) {
10799
+ if (collecting)
10800
+ break outer;
10801
+ continue;
10802
+ }
10803
+ const content = step.content;
10804
+ for (let j = content.length - 1; j >= 0; j--) {
10805
+ const item = content[j];
10806
+ if (item.type === 'text') {
10807
+ collecting = true;
10808
+ textParts.push((_b = item.text) !== null && _b !== void 0 ? _b : '');
10809
+ }
10810
+ else if (collecting) {
10811
+ // Hit a non-text barrier after we started collecting.
10812
+ break outer;
10813
+ }
10814
+ }
10815
+ }
10816
+ const output_text = textParts.reverse().join('');
10817
+ let output_image;
10818
+ let output_audio;
10819
+ let output_video;
10820
+ for (let i = steps.length - 1; i >= 0; i--) {
10821
+ const step = steps[i];
10822
+ const anyStep = step;
10823
+ if (anyStep.type === 'user_input') {
10824
+ break;
10825
+ }
10826
+ if (anyStep.type === 'model_output' && anyStep.content) {
10827
+ for (let j = anyStep.content.length - 1; j >= 0; j--) {
10828
+ const content = anyStep.content[j];
10829
+ if (content.type === 'image' && !output_image) {
10830
+ output_image = content;
10831
+ }
10832
+ if (content.type === 'audio' && !output_audio) {
10833
+ output_audio = content;
10834
+ }
10835
+ if (content.type === 'video' && !output_video) {
10836
+ output_video = content;
10837
+ }
10838
+ }
10839
+ }
10840
+ }
10841
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, interaction), (output_text && { output_text })), (output_image && { output_image })), (output_audio && { output_audio })), (output_video && { output_video }));
10842
+ }
10737
10843
 
10738
10844
  /**
10739
10845
  * @license
@@ -11448,6 +11554,7 @@ class GeminiNextGenAPIClient extends BaseGeminiNextGenAPIClient {
11448
11554
  super(...arguments);
11449
11555
  this.interactions = new Interactions(this);
11450
11556
  this.webhooks = new Webhooks(this);
11557
+ this.agents = new Agents(this);
11451
11558
  }
11452
11559
  }
11453
11560
  _a = GeminiNextGenAPIClient;
@@ -11468,6 +11575,7 @@ GeminiNextGenAPIClient.UnprocessableEntityError = UnprocessableEntityError;
11468
11575
  GeminiNextGenAPIClient.toFile = toFile;
11469
11576
  GeminiNextGenAPIClient.Interactions = Interactions;
11470
11577
  GeminiNextGenAPIClient.Webhooks = Webhooks;
11578
+ GeminiNextGenAPIClient.Agents = Agents;
11471
11579
 
11472
11580
  /**
11473
11581
  * @license
@@ -11883,6 +11991,12 @@ function liveConnectConfigToMldev$1(fromObject, parentObject) {
11883
11991
  }
11884
11992
  setValueByPath(parentObject, ['setup', 'safetySettings'], transformedList);
11885
11993
  }
11994
+ const fromStreamTranslationConfig = getValueByPath(fromObject, [
11995
+ 'streamTranslationConfig',
11996
+ ]);
11997
+ if (parentObject !== undefined && fromStreamTranslationConfig != null) {
11998
+ setValueByPath(parentObject, ['setup', 'generationConfig', 'streamTranslationConfig'], fromStreamTranslationConfig);
11999
+ }
11886
12000
  return toObject;
11887
12001
  }
11888
12002
  function liveConnectConfigToVertex(fromObject, parentObject) {
@@ -12015,6 +12129,9 @@ function liveConnectConfigToVertex(fromObject, parentObject) {
12015
12129
  }
12016
12130
  setValueByPath(parentObject, ['setup', 'safetySettings'], transformedList);
12017
12131
  }
12132
+ if (getValueByPath(fromObject, ['streamTranslationConfig']) !== undefined) {
12133
+ throw new Error('streamTranslationConfig parameter is only supported in Gemini Developer API mode, not in Gemini Enterprise Agent Platform mode.');
12134
+ }
12018
12135
  return toObject;
12019
12136
  }
12020
12137
  function liveConnectParametersToMldev(apiClient, fromObject) {
@@ -19143,6 +19260,12 @@ function liveConnectConfigToMldev(fromObject, parentObject) {
19143
19260
  }
19144
19261
  setValueByPath(parentObject, ['setup', 'safetySettings'], transformedList);
19145
19262
  }
19263
+ const fromStreamTranslationConfig = getValueByPath(fromObject, [
19264
+ 'streamTranslationConfig',
19265
+ ]);
19266
+ if (parentObject !== undefined && fromStreamTranslationConfig != null) {
19267
+ setValueByPath(parentObject, ['setup', 'generationConfig', 'streamTranslationConfig'], fromStreamTranslationConfig);
19268
+ }
19146
19269
  return toObject;
19147
19270
  }
19148
19271
  function liveConnectConstraintsToMldev(apiClient, fromObject) {
@@ -20874,6 +20997,7 @@ class GoogleGenAI {
20874
20997
  if (this._interactions !== undefined) {
20875
20998
  return this._interactions;
20876
20999
  }
21000
+ console.warn('GoogleGenAI.interactions: Interactions usage is experimental and may change in future versions.');
20877
21001
  this._interactions = this.getNextGenClient().interactions;
20878
21002
  return this._interactions;
20879
21003
  }
@@ -20884,6 +21008,14 @@ class GoogleGenAI {
20884
21008
  this._webhooks = this.getNextGenClient().webhooks;
20885
21009
  return this._webhooks;
20886
21010
  }
21011
+ get agents() {
21012
+ if (this._agents !== undefined) {
21013
+ return this._agents;
21014
+ }
21015
+ console.warn('GoogleGenAI.agents: Agents usage is experimental and may change in future versions.');
21016
+ this._agents = this.getNextGenClient().agents;
21017
+ return this._agents;
21018
+ }
20887
21019
  constructor(options) {
20888
21020
  var _a, _b;
20889
21021
  if (options.apiKey == null) {