@google/genai 1.8.0 → 1.9.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.
@@ -1,4 +1,3 @@
1
- import { z } from 'zod';
2
1
  import { GoogleAuth } from 'google-auth-library';
3
2
  import { createWriteStream, writeFile } from 'fs';
4
3
  import { Readable } from 'node:stream';
@@ -796,11 +795,38 @@ var PersonGeneration;
796
795
  /** Enum that specifies the language of the text in the prompt. */
797
796
  var ImagePromptLanguage;
798
797
  (function (ImagePromptLanguage) {
798
+ /**
799
+ * Auto-detect the language.
800
+ */
799
801
  ImagePromptLanguage["auto"] = "auto";
802
+ /**
803
+ * English
804
+ */
800
805
  ImagePromptLanguage["en"] = "en";
806
+ /**
807
+ * Japanese
808
+ */
801
809
  ImagePromptLanguage["ja"] = "ja";
810
+ /**
811
+ * Korean
812
+ */
802
813
  ImagePromptLanguage["ko"] = "ko";
814
+ /**
815
+ * Hindi
816
+ */
803
817
  ImagePromptLanguage["hi"] = "hi";
818
+ /**
819
+ * Chinese
820
+ */
821
+ ImagePromptLanguage["zh"] = "zh";
822
+ /**
823
+ * Portuguese
824
+ */
825
+ ImagePromptLanguage["pt"] = "pt";
826
+ /**
827
+ * Spanish
828
+ */
829
+ ImagePromptLanguage["es"] = "es";
804
830
  })(ImagePromptLanguage || (ImagePromptLanguage = {}));
805
831
  /** Enum representing the mask mode of a mask reference image. */
806
832
  var MaskReferenceMode;
@@ -1901,133 +1927,12 @@ function tContents(origin) {
1901
1927
  }
1902
1928
  return result;
1903
1929
  }
1904
- // The fields that are supported by JSONSchema. Must be kept in sync with the
1905
- // JSONSchema interface above.
1906
- const supportedJsonSchemaFields = new Set([
1907
- 'type',
1908
- 'format',
1909
- 'title',
1910
- 'description',
1911
- 'default',
1912
- 'items',
1913
- 'minItems',
1914
- 'maxItems',
1915
- 'enum',
1916
- 'properties',
1917
- 'required',
1918
- 'minProperties',
1919
- 'maxProperties',
1920
- 'minimum',
1921
- 'maximum',
1922
- 'minLength',
1923
- 'maxLength',
1924
- 'pattern',
1925
- 'anyOf',
1926
- 'propertyOrdering',
1927
- ]);
1928
- const jsonSchemaTypeValidator = z.enum([
1929
- 'string',
1930
- 'number',
1931
- 'integer',
1932
- 'object',
1933
- 'array',
1934
- 'boolean',
1935
- 'null',
1936
- ]);
1937
- // Handles all types and arrays of all types.
1938
- const schemaTypeUnion = z.union([
1939
- jsonSchemaTypeValidator,
1940
- z.array(jsonSchemaTypeValidator),
1941
- ]);
1942
- /**
1943
- * Creates a zod validator for JSONSchema.
1944
- *
1945
- * @param strictMode Whether to enable strict mode, default to true. When
1946
- * strict mode is enabled, the zod validator will throw error if there
1947
- * are unrecognized fields in the input data. If strict mode is
1948
- * disabled, the zod validator will ignore the unrecognized fields, only
1949
- * populate the fields that are listed in the JSONSchema. Regardless of
1950
- * the mode the type mismatch will always result in an error, for example
1951
- * items field should be a single JSONSchema, but for tuple type it would
1952
- * be an array of JSONSchema, this will always result in an error.
1953
- * @return The zod validator for JSONSchema.
1954
- */
1955
- function createJsonSchemaValidator(strictMode = true) {
1956
- const jsonSchemaValidator = z.lazy(() => {
1957
- // Define the base object shape *inside* the z.lazy callback
1958
- const baseShape = z.object({
1959
- // --- Type ---
1960
- type: schemaTypeUnion.optional(),
1961
- // --- Annotations ---
1962
- format: z.string().optional(),
1963
- title: z.string().optional(),
1964
- description: z.string().optional(),
1965
- default: z.unknown().optional(),
1966
- // --- Array Validations ---
1967
- items: jsonSchemaValidator.optional(),
1968
- minItems: z.coerce.string().optional(),
1969
- maxItems: z.coerce.string().optional(),
1970
- // --- Generic Validations ---
1971
- enum: z.array(z.unknown()).optional(),
1972
- // --- Object Validations ---
1973
- properties: z.record(z.string(), jsonSchemaValidator).optional(),
1974
- required: z.array(z.string()).optional(),
1975
- minProperties: z.coerce.string().optional(),
1976
- maxProperties: z.coerce.string().optional(),
1977
- propertyOrdering: z.array(z.string()).optional(),
1978
- // --- Numeric Validations ---
1979
- minimum: z.number().optional(),
1980
- maximum: z.number().optional(),
1981
- // --- String Validations ---
1982
- minLength: z.coerce.string().optional(),
1983
- maxLength: z.coerce.string().optional(),
1984
- pattern: z.string().optional(),
1985
- // --- Schema Composition ---
1986
- anyOf: z.array(jsonSchemaValidator).optional(),
1987
- // --- Additional Properties --- This field is not included in the
1988
- // JSONSchema, will not be communicated to the model, it is here purely
1989
- // for enabling the zod validation strict mode.
1990
- additionalProperties: z.boolean().optional(),
1991
- });
1992
- // Conditionally apply .strict() based on the flag
1993
- return strictMode ? baseShape.strict() : baseShape;
1994
- });
1995
- return jsonSchemaValidator;
1996
- }
1997
1930
  /*
1998
- Handle type field:
1999
- The resulted type field in JSONSchema form zod_to_json_schema can be either
2000
- an array consist of primitive types or a single primitive type.
2001
- This is due to the optimization of zod_to_json_schema, when the types in the
2002
- union are primitive types without any additional specifications,
2003
- zod_to_json_schema will squash the types into an array instead of put them
2004
- in anyOf fields. Otherwise, it will put the types in anyOf fields.
2005
- See the following link for more details:
2006
- https://github.com/zodjs/zod-to-json-schema/blob/main/src/index.ts#L101
2007
- The logic here is trying to undo that optimization, flattening the array of
2008
- types to anyOf fields.
2009
- type field
2010
- |
2011
- ___________________________
2012
- / \
2013
- / \
2014
- / \
2015
- Array Type.*
2016
- / \ |
2017
- Include null. Not included null type = Type.*.
2018
- [null, Type.*, Type.*] multiple types.
2019
- [null, Type.*] [Type.*, Type.*]
2020
- / \
2021
- remove null \
2022
- add nullable = true \
2023
- / \ \
2024
- [Type.*] [Type.*, Type.*] \
2025
- only one type left multiple types left \
2026
- add type = Type.*. \ /
2027
- \ /
2028
- not populate the type field in final result
2029
- and make the types into anyOf fields
2030
- anyOf:[{type: 'Type.*'}, {type: 'Type.*'}];
1931
+ Transform the type field from an array of types to an array of anyOf fields.
1932
+ Example:
1933
+ {type: ['STRING', 'NUMBER']}
1934
+ will be transformed to
1935
+ {anyOf: [{type: 'STRING'}, {type: 'NUMBER'}]}
2031
1936
  */
2032
1937
  function flattenTypeArrayToAnyOf(typeList, resultingSchema) {
2033
1938
  if (typeList.includes('null')) {
@@ -2173,15 +2078,11 @@ function processJsonSchema(_jsonSchema) {
2173
2078
  // https://github.com/StefanTerdell/zod-to-json-schema/blob/70525efe555cd226691e093d171370a3b10921d1/src/zodToJsonSchema.ts#L7
2174
2079
  // typebox can return unknown, see details in
2175
2080
  // https://github.com/sinclairzx81/typebox/blob/5a5431439f7d5ca6b494d0d18fbfd7b1a356d67c/src/type/create/type.ts#L35
2081
+ // Note: proper json schemas with the $schema field set never arrive to this
2082
+ // transformer. Schemas with $schema are routed to the equivalent API json
2083
+ // schema field.
2176
2084
  function tSchema(schema) {
2177
- if (Object.keys(schema).includes('$schema')) {
2178
- delete schema['$schema'];
2179
- const validatedJsonSchema = createJsonSchemaValidator().parse(schema);
2180
- return processJsonSchema(validatedJsonSchema);
2181
- }
2182
- else {
2183
- return processJsonSchema(schema);
2184
- }
2085
+ return processJsonSchema(schema);
2185
2086
  }
2186
2087
  function tSpeechConfig(speechConfig) {
2187
2088
  if (typeof speechConfig === 'object') {
@@ -2210,10 +2111,28 @@ function tTool(tool) {
2210
2111
  if (tool.functionDeclarations) {
2211
2112
  for (const functionDeclaration of tool.functionDeclarations) {
2212
2113
  if (functionDeclaration.parameters) {
2213
- functionDeclaration.parameters = tSchema(functionDeclaration.parameters);
2114
+ if (!Object.keys(functionDeclaration.parameters).includes('$schema')) {
2115
+ functionDeclaration.parameters = processJsonSchema(functionDeclaration.parameters);
2116
+ }
2117
+ else {
2118
+ if (!functionDeclaration.parametersJsonSchema) {
2119
+ functionDeclaration.parametersJsonSchema =
2120
+ functionDeclaration.parameters;
2121
+ delete functionDeclaration.parameters;
2122
+ }
2123
+ }
2214
2124
  }
2215
2125
  if (functionDeclaration.response) {
2216
- functionDeclaration.response = tSchema(functionDeclaration.response);
2126
+ if (!Object.keys(functionDeclaration.response).includes('$schema')) {
2127
+ functionDeclaration.response = processJsonSchema(functionDeclaration.response);
2128
+ }
2129
+ else {
2130
+ if (!functionDeclaration.responseJsonSchema) {
2131
+ functionDeclaration.responseJsonSchema =
2132
+ functionDeclaration.response;
2133
+ delete functionDeclaration.response;
2134
+ }
2135
+ }
2217
2136
  }
2218
2137
  }
2219
2138
  }
@@ -2418,7 +2337,7 @@ function mcpToGeminiTool(mcpTool, config = {}) {
2418
2337
  const functionDeclaration = {
2419
2338
  name: mcpToolSchema['name'],
2420
2339
  description: mcpToolSchema['description'],
2421
- parameters: processJsonSchema(filterToJsonSchema(mcpToolSchema['inputSchema'])),
2340
+ parametersJsonSchema: mcpToolSchema['inputSchema'],
2422
2341
  };
2423
2342
  if (config.behavior) {
2424
2343
  functionDeclaration['behavior'] = config.behavior;
@@ -2450,53 +2369,6 @@ function mcpToolsToGeminiTool(mcpTools, config = {}) {
2450
2369
  }
2451
2370
  return { functionDeclarations: functionDeclarations };
2452
2371
  }
2453
- // Filters the list schema field to only include fields that are supported by
2454
- // JSONSchema.
2455
- function filterListSchemaField(fieldValue) {
2456
- const listSchemaFieldValue = [];
2457
- for (const listFieldValue of fieldValue) {
2458
- listSchemaFieldValue.push(filterToJsonSchema(listFieldValue));
2459
- }
2460
- return listSchemaFieldValue;
2461
- }
2462
- // Filters the dict schema field to only include fields that are supported by
2463
- // JSONSchema.
2464
- function filterDictSchemaField(fieldValue) {
2465
- const dictSchemaFieldValue = {};
2466
- for (const [key, value] of Object.entries(fieldValue)) {
2467
- const valueRecord = value;
2468
- dictSchemaFieldValue[key] = filterToJsonSchema(valueRecord);
2469
- }
2470
- return dictSchemaFieldValue;
2471
- }
2472
- // Filters the schema to only include fields that are supported by JSONSchema.
2473
- function filterToJsonSchema(schema) {
2474
- const schemaFieldNames = new Set(['items']); // 'additional_properties' to come
2475
- const listSchemaFieldNames = new Set(['anyOf']); // 'one_of', 'all_of', 'not' to come
2476
- const dictSchemaFieldNames = new Set(['properties']); // 'defs' to come
2477
- const filteredSchema = {};
2478
- for (const [fieldName, fieldValue] of Object.entries(schema)) {
2479
- if (schemaFieldNames.has(fieldName)) {
2480
- filteredSchema[fieldName] = filterToJsonSchema(fieldValue);
2481
- }
2482
- else if (listSchemaFieldNames.has(fieldName)) {
2483
- filteredSchema[fieldName] = filterListSchemaField(fieldValue);
2484
- }
2485
- else if (dictSchemaFieldNames.has(fieldName)) {
2486
- filteredSchema[fieldName] = filterDictSchemaField(fieldValue);
2487
- }
2488
- else if (fieldName === 'type') {
2489
- const typeValue = fieldValue.toUpperCase();
2490
- filteredSchema[fieldName] = Object.values(Type).includes(typeValue)
2491
- ? typeValue
2492
- : Type.TYPE_UNSPECIFIED;
2493
- }
2494
- else if (supportedJsonSchemaFields.has(fieldName)) {
2495
- filteredSchema[fieldName] = fieldValue;
2496
- }
2497
- }
2498
- return filteredSchema;
2499
- }
2500
2372
  // Transforms a source input into a BatchJobSource object with validation.
2501
2373
  function tBatchJobSource(apiClient, src) {
2502
2374
  if (typeof src !== 'string' && !Array.isArray(src)) {
@@ -12832,7 +12704,7 @@ const CONTENT_TYPE_HEADER = 'Content-Type';
12832
12704
  const SERVER_TIMEOUT_HEADER = 'X-Server-Timeout';
12833
12705
  const USER_AGENT_HEADER = 'User-Agent';
12834
12706
  const GOOGLE_API_CLIENT_HEADER = 'x-goog-api-client';
12835
- const SDK_VERSION = '1.8.0'; // x-release-please-version
12707
+ const SDK_VERSION = '1.9.0'; // x-release-please-version
12836
12708
  const LIBRARY_LABEL = `google-genai-sdk/${SDK_VERSION}`;
12837
12709
  const VERTEX_AI_API_DEFAULT_VERSION = 'v1beta1';
12838
12710
  const GOOGLE_AI_API_DEFAULT_VERSION = 'v1beta';
@@ -13063,7 +12935,14 @@ class ApiClient {
13063
12935
  const abortController = new AbortController();
13064
12936
  const signal = abortController.signal;
13065
12937
  if (httpOptions.timeout && (httpOptions === null || httpOptions === void 0 ? void 0 : httpOptions.timeout) > 0) {
13066
- setTimeout(() => abortController.abort(), httpOptions.timeout);
12938
+ const timeoutHandle = setTimeout(() => abortController.abort(), httpOptions.timeout);
12939
+ if (timeoutHandle &&
12940
+ typeof timeoutHandle.unref ===
12941
+ 'function') {
12942
+ // call unref to prevent nodejs process from hanging, see
12943
+ // https://nodejs.org/api/timers.html#timeoutunref
12944
+ timeoutHandle.unref();
12945
+ }
13067
12946
  }
13068
12947
  if (abortSignal) {
13069
12948
  abortSignal.addEventListener('abort', () => {
@@ -13126,7 +13005,7 @@ class ApiClient {
13126
13005
  }
13127
13006
  break;
13128
13007
  }
13129
- const chunkString = decoder.decode(value);
13008
+ const chunkString = decoder.decode(value, { stream: true });
13130
13009
  // Parse and throw an error if the chunk contains an error.
13131
13010
  try {
13132
13011
  const chunkJson = JSON.parse(chunkString);
@@ -13883,7 +13762,7 @@ class Live {
13883
13762
  if (GOOGLE_GENAI_USE_VERTEXAI) {
13884
13763
  model = 'gemini-2.0-flash-live-preview-04-09';
13885
13764
  } else {
13886
- model = 'gemini-2.0-flash-live-001';
13765
+ model = 'gemini-live-2.5-flash-preview';
13887
13766
  }
13888
13767
  const session = await ai.live.connect({
13889
13768
  model: model,
@@ -13929,6 +13808,9 @@ class Live {
13929
13808
  let keyName = 'key';
13930
13809
  if (apiKey === null || apiKey === void 0 ? void 0 : apiKey.startsWith('auth_tokens/')) {
13931
13810
  console.warn('Warning: Ephemeral token support is experimental and may change in future versions.');
13811
+ if (apiVersion !== 'v1alpha') {
13812
+ console.warn("Warning: The SDK's ephemeral token support is in v1alpha only. Please use const ai = new GoogleGenAI({apiKey: token.name, httpOptions: { apiVersion: 'v1alpha' }}); before session connection.");
13813
+ }
13932
13814
  method = 'BidiGenerateContentConstrained';
13933
13815
  keyName = 'access_token';
13934
13816
  }
@@ -14204,7 +14086,7 @@ class Session {
14204
14086
  if (GOOGLE_GENAI_USE_VERTEXAI) {
14205
14087
  model = 'gemini-2.0-flash-live-preview-04-09';
14206
14088
  } else {
14207
- model = 'gemini-2.0-flash-live-001';
14089
+ model = 'gemini-live-2.5-flash-preview';
14208
14090
  }
14209
14091
  const session = await ai.live.connect({
14210
14092
  model: model,
@@ -14333,6 +14215,7 @@ class Models extends BaseModule {
14333
14215
  this.generateContent = async (params) => {
14334
14216
  var _a, _b, _c, _d, _e;
14335
14217
  const transformedParams = await this.processParamsForMcpUsage(params);
14218
+ this.maybeMoveToResponseJsonSchem(params);
14336
14219
  if (!hasMcpClientTools(params) || shouldDisableAfc(params.config)) {
14337
14220
  return await this.generateContentInternal(transformedParams);
14338
14221
  }
@@ -14419,6 +14302,7 @@ class Models extends BaseModule {
14419
14302
  * ```
14420
14303
  */
14421
14304
  this.generateContentStream = async (params) => {
14305
+ this.maybeMoveToResponseJsonSchem(params);
14422
14306
  if (shouldDisableAfc(params.config)) {
14423
14307
  const transformedParams = await this.processParamsForMcpUsage(params);
14424
14308
  return await this.generateContentStreamInternal(transformedParams);
@@ -14570,6 +14454,24 @@ class Models extends BaseModule {
14570
14454
  return await this.upscaleImageInternal(apiParams);
14571
14455
  };
14572
14456
  }
14457
+ /**
14458
+ * This logic is needed for GenerateContentConfig only.
14459
+ * Previously we made GenerateContentConfig.responseSchema field to accept
14460
+ * unknown. Since v1.9.0, we switch to use backend JSON schema support.
14461
+ * To maintain backward compatibility, we move the data that was treated as
14462
+ * JSON schema from the responseSchema field to the responseJsonSchema field.
14463
+ */
14464
+ maybeMoveToResponseJsonSchem(params) {
14465
+ if (params.config && params.config.responseSchema) {
14466
+ if (!params.config.responseJsonSchema) {
14467
+ if (Object.keys(params.config.responseSchema).includes('$schema')) {
14468
+ params.config.responseJsonSchema = params.config.responseSchema;
14469
+ delete params.config.responseSchema;
14470
+ }
14471
+ }
14472
+ }
14473
+ return;
14474
+ }
14573
14475
  /**
14574
14476
  * Transforms the CallableTools in the parameters to be simply Tools, it
14575
14477
  * copies the params into a new object and replaces the tools, it does not
@@ -16630,14 +16532,20 @@ class Tokens extends BaseModule {
16630
16532
  * @experimental
16631
16533
  *
16632
16534
  * @remarks
16633
- * Ephermeral auth tokens is only supported in the Gemini Developer API.
16535
+ * Ephemeral auth tokens is only supported in the Gemini Developer API.
16634
16536
  * It can be used for the session connection to the Live constrained API.
16537
+ * Support in v1alpha only.
16635
16538
  *
16636
16539
  * @param params - The parameters for the create request.
16637
16540
  * @return The created auth token.
16638
16541
  *
16639
16542
  * @example
16640
16543
  * ```ts
16544
+ * const ai = new GoogleGenAI({
16545
+ * apiKey: token.name,
16546
+ * httpOptions: { apiVersion: 'v1alpha' } // Support in v1alpha only.
16547
+ * });
16548
+ *
16641
16549
  * // Case 1: If LiveEphemeralParameters is unset, unlock LiveConnectConfig
16642
16550
  * // when using the token in Live API sessions. Each session connection can
16643
16551
  * // use a different configuration.