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