/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ // Code generated by the Google Gen AI SDK generator DO NOT EDIT. import * as afc from './_afc.js'; import {ApiClient} from './_api_client.js'; import * as common from './_common.js'; import {BaseModule} from './_common.js'; import * as _internal_types from './_internal_types.js'; import {tContents, tIsVertexEmbedContentModel} from './_transformers.js'; import * as converters from './converters/_models_converters.js'; import * as mcp from './mcp/_mcp.js'; import {PagedItem, Pager} from './pagers.js'; import * as types from './types.js'; export class Models extends BaseModule { constructor(private readonly apiClient: ApiClient) { super(); } private static loggedGenerateImagesWarning = false; private static loggedEditImageWarning = false; private static loggedGenerateVideosWarning = false; /** * Calculates embeddings for the given contents. * * @param params - The parameters for embedding contents. * @return The response from the API. * * @example * ```ts * const response = await ai.models.embedContent({ * model: 'text-embedding-004', * contents: [ * 'What is your name?', * 'What is your favorite color?', * ], * config: { * outputDimensionality: 64, * }, * }); * console.log(response); * ``` */ embedContent = async ( params: types.EmbedContentParameters, ): Promise => { if (!this.apiClient.isVertexAI()) { const isGeminiEmbedding2Model = params.model.includes('gemini-embedding-2'); if (isGeminiEmbedding2Model) { params.contents = tContents(params.contents); } return await this.embedContentInternal(params); } const isVertexEmbedContentModel = (params.model.includes('gemini') && params.model !== 'gemini-embedding-001') || params.model.includes('maas'); if (isVertexEmbedContentModel) { const contents = tContents(params.contents); if (contents.length > 1) { throw new Error( 'The embedContent API for this model only supports one content at a time.', ); } const paramsPrivate: types.EmbedContentParametersPrivate = { ...params, content: contents[0], embeddingApiType: types.EmbeddingApiType.EMBED_CONTENT, }; return await this.embedContentInternal(paramsPrivate); } else { const paramsPrivate: types.EmbedContentParametersPrivate = { ...params, embeddingApiType: types.EmbeddingApiType.PREDICT, }; return await this.embedContentInternal(paramsPrivate); } }; /** * Makes an API request to generate content with a given model. * * For the `model` parameter, supported formats for Gemini Enterprise Agent Platform API include: * - The Gemini model ID, for example: 'gemini-2.0-flash' * - The full resource name starts with 'projects/', for example: * 'projects/my-project-id/locations/us-central1/publishers/google/models/gemini-2.0-flash' * - The partial resource name with 'publishers/', for example: * 'publishers/google/models/gemini-2.0-flash' or * 'publishers/meta/models/llama-3.1-405b-instruct-maas' * - `/` separated publisher and model name, for example: * 'google/gemini-2.0-flash' or 'meta/llama-3.1-405b-instruct-maas' * * For the `model` parameter, supported formats for Gemini API include: * - The Gemini model ID, for example: 'gemini-2.0-flash' * - The model name starts with 'models/', for example: * 'models/gemini-2.0-flash' * - For tuned models, the model name starts with 'tunedModels/', * for example: * 'tunedModels/1234567890123456789' * * Some models support multimodal input and output. * * @param params - The parameters for generating content. * @return The response from generating content. * * @example * ```ts * const response = await ai.models.generateContent({ * model: 'gemini-2.0-flash', * contents: 'why is the sky blue?', * config: { * candidateCount: 2, * } * }); * console.log(response); * ``` */ generateContent = async ( params: types.GenerateContentParameters, ): Promise => { const transformedParams = await this.processParamsMaybeAddMcpUsage(params); this.maybeMoveToResponseJsonSchema(params); if (!afc.hasCallableTools(params) || afc.shouldDisableAfc(params.config)) { return await this.generateContentInternal(transformedParams); } const incompatibleToolIndexes = afc.findAfcIncompatibleToolIndexes(params); if (incompatibleToolIndexes.length > 0) { const formattedIndexes = incompatibleToolIndexes .map((index: number) => `tools[${index}]`) .join(', '); throw new Error( `Automatic function calling with CallableTools (or MCP objects) and basic FunctionDeclarations is not yet supported. Incompatible tools found at ${ formattedIndexes }.`, ); } let response: types.GenerateContentResponse; let functionResponseContent: types.Content; const automaticFunctionCallingHistory: types.Content[] = tContents( transformedParams.contents, ); const maxRemoteCalls = transformedParams.config?.automaticFunctionCalling?.maximumRemoteCalls ?? afc.DEFAULT_MAX_REMOTE_CALLS; let remoteCalls = 0; while (remoteCalls < maxRemoteCalls) { response = await this.generateContentInternal(transformedParams); if (!response.functionCalls || response.functionCalls!.length === 0) { break; } const responseContent: types.Content = response.candidates![0].content!; const functionResponseParts: types.Part[] = []; for (const tool of params.config?.tools ?? []) { if (afc.isCallableTool(tool)) { const callableTool = tool as types.CallableTool; const parts = await callableTool.callTool(response.functionCalls!); functionResponseParts.push(...parts); } } remoteCalls++; functionResponseContent = { role: 'user', parts: functionResponseParts, }; transformedParams.contents = tContents(transformedParams.contents); (transformedParams.contents as types.Content[]).push(responseContent); (transformedParams.contents as types.Content[]).push( functionResponseContent, ); if (afc.shouldAppendAfcHistory(transformedParams.config)) { automaticFunctionCallingHistory.push(responseContent); automaticFunctionCallingHistory.push(functionResponseContent); } } if (afc.shouldAppendAfcHistory(transformedParams.config)) { response!.automaticFunctionCallingHistory = automaticFunctionCallingHistory; } return response!; }; /** * This logic is needed for GenerateContentConfig only. * Previously we made GenerateContentConfig.responseSchema field to accept * unknown. Since v1.9.0, we switch to use backend JSON schema support. * To maintain backward compatibility, we move the data that was treated as * JSON schema from the responseSchema field to the responseJsonSchema field. */ private maybeMoveToResponseJsonSchema( params: types.GenerateContentParameters, ): void { if (params.config && params.config.responseSchema) { if (!params.config.responseJsonSchema) { if (Object.keys(params.config.responseSchema).includes('$schema')) { params.config.responseJsonSchema = params.config.responseSchema; delete params.config.responseSchema; } } } return; } /** * Makes an API request to generate content with a given model and yields the * response in chunks. * * For the `model` parameter, supported formats for Gemini Enterprise Agent Platform API include: * - The Gemini model ID, for example: 'gemini-2.0-flash' * - The full resource name starts with 'projects/', for example: * 'projects/my-project-id/locations/us-central1/publishers/google/models/gemini-2.0-flash' * - The partial resource name with 'publishers/', for example: * 'publishers/google/models/gemini-2.0-flash' or * 'publishers/meta/models/llama-3.1-405b-instruct-maas' * - `/` separated publisher and model name, for example: * 'google/gemini-2.0-flash' or 'meta/llama-3.1-405b-instruct-maas' * * For the `model` parameter, supported formats for Gemini API include: * - The Gemini model ID, for example: 'gemini-2.0-flash' * - The model name starts with 'models/', for example: * 'models/gemini-2.0-flash' * - For tuned models, the model name starts with 'tunedModels/', * for example: * 'tunedModels/1234567890123456789' * * Some models support multimodal input and output. * * @param params - The parameters for generating content with streaming response. * @return The response from generating content. * * @example * ```ts * const response = await ai.models.generateContentStream({ * model: 'gemini-2.0-flash', * contents: 'why is the sky blue?', * config: { * maxOutputTokens: 200, * } * }); * for await (const chunk of response) { * console.log(chunk); * } * ``` */ generateContentStream = async ( params: types.GenerateContentParameters, ): Promise> => { this.maybeMoveToResponseJsonSchema(params); if (afc.shouldDisableAfc(params.config)) { const transformedParams = await this.processParamsMaybeAddMcpUsage(params); return await this.generateContentStreamInternal(transformedParams); } const incompatibleToolIndexes = afc.findAfcIncompatibleToolIndexes(params); if (incompatibleToolIndexes.length > 0) { const formattedIndexes = incompatibleToolIndexes .map((index: number) => `tools[${index}]`) .join(', '); throw new Error( `Incompatible tools found at ${ formattedIndexes }. Automatic function calling with CallableTools (or MCP objects) and basic FunctionDeclarations" is not yet supported.`, ); } // With tool compatibility confirmed, validate that the configuration are // compatible with each other and raise an error if invalid. const streamFunctionCall = params?.config?.toolConfig?.functionCallingConfig ?.streamFunctionCallArguments; const disableAfc = params?.config?.automaticFunctionCalling?.disable; if (streamFunctionCall && !disableAfc) { throw new Error( "Running in streaming mode with 'streamFunctionCallArguments' enabled, " + 'this feature is not compatible with automatic function calling (AFC). ' + "Please set 'config.automaticFunctionCalling.disable' to true to disable AFC " + "or leave 'config.toolConfig.functionCallingConfig.streamFunctionCallArguments' " + 'to be undefined or set to false to disable streaming function call arguments feature.', ); } return await this.processAfcStream(params); }; /** * Transforms the CallableTools in the parameters to be simply Tools, it * copies the params into a new object and replaces the tools, it does not * modify the original params. Also sets the MCP usage header if there are * MCP tools in the parameters. */ private async processParamsMaybeAddMcpUsage( params: types.GenerateContentParameters, ): Promise { const tools = params.config?.tools; if (!tools) { return params; } const transformedTools = await Promise.all( tools.map(async (tool) => { if (afc.isCallableTool(tool)) { const callableTool = tool as types.CallableTool; return await callableTool.tool(); } return tool; }), ); const newParams: types.GenerateContentParameters = { model: params.model, contents: params.contents, config: { ...params.config, tools: transformedTools, }, }; newParams.config!.tools = transformedTools; if ( params.config && params.config.tools && mcp.hasMcpToolUsage(params.config.tools) ) { const headers = params.config.httpOptions?.headers ?? {}; let newHeaders = {...headers}; if (Object.keys(newHeaders).length === 0) { newHeaders = this.apiClient.getDefaultHeaders(); } mcp.setMcpUsageHeader(newHeaders); newParams.config!.httpOptions = { ...params.config.httpOptions, headers: newHeaders, }; } return newParams; } private async initAfcToolsMap( params: types.GenerateContentParameters, ): Promise> { const afcTools: Map = new Map(); for (const tool of params.config?.tools ?? []) { if (afc.isCallableTool(tool)) { const callableTool = tool as types.CallableTool; const toolDeclaration = await callableTool.tool(); for (const declaration of toolDeclaration.functionDeclarations ?? []) { if (!declaration.name) { throw new Error('Function declaration name is required.'); } if (afcTools.has(declaration.name)) { throw new Error( `Duplicate tool declaration name: ${declaration.name}`, ); } afcTools.set(declaration.name, callableTool); } } } return afcTools; } private async processAfcStream( params: types.GenerateContentParameters, ): Promise> { const maxRemoteCalls = params.config?.automaticFunctionCalling?.maximumRemoteCalls ?? afc.DEFAULT_MAX_REMOTE_CALLS; let wereFunctionsCalled = false; let remoteCallCount = 0; const afcToolsMap = await this.initAfcToolsMap(params); return (async function* ( models: Models, afcTools: Map, params: types.GenerateContentParameters, ) { while (remoteCallCount < maxRemoteCalls) { if (wereFunctionsCalled) { remoteCallCount++; wereFunctionsCalled = false; } const transformedParams = await models.processParamsMaybeAddMcpUsage(params); const response = await models.generateContentStreamInternal(transformedParams); const functionResponses: types.Part[] = []; const responseContents: types.Content[] = []; for await (const chunk of response) { yield chunk; if (chunk.candidates && chunk.candidates[0]?.content) { responseContents.push(chunk.candidates[0].content); for (const part of chunk.candidates[0].content.parts ?? []) { if (remoteCallCount < maxRemoteCalls && part.functionCall) { if (!part.functionCall.name) { throw new Error( 'Function call name was not returned by the model.', ); } if (!afcTools.has(part.functionCall.name)) { throw new Error( `Automatic function calling was requested, but not all the tools the model used implement the CallableTool interface. Available tools: ${afcTools.keys()}, missing tool: ${ part.functionCall.name }`, ); } else { const responseParts = await afcTools .get(part.functionCall.name)! .callTool([part.functionCall]); functionResponses.push(...responseParts); } } } } } if (functionResponses.length > 0) { wereFunctionsCalled = true; const typedResponseChunk = new types.GenerateContentResponse(); typedResponseChunk.candidates = [ { content: { role: 'user', parts: functionResponses, }, }, ]; yield typedResponseChunk; const newContents: types.Content[] = []; newContents.push(...responseContents); newContents.push({ role: 'user', parts: functionResponses, }); const updatedContents = tContents(params.contents).concat( newContents, ); params.contents = updatedContents; } else { break; } } })(this, afcToolsMap, params); } /** * Generates an image based on a text description and configuration. * * @param params - The parameters for generating images. * @return The response from the API. * * @example * ```ts * const response = await client.models.generateImages({ * model: 'imagen-4.0-generate-001', * prompt: 'Robot holding a red skateboard', * config: { * numberOfImages: 1, * includeRaiReason: true, * }, * }); * console.log(response?.generatedImages?.[0]?.image?.imageBytes); * ``` */ generateImages = async ( params: types.GenerateImagesParameters, ): Promise => { if (!Models.loggedGenerateImagesWarning) { Models.loggedGenerateImagesWarning = true; console.warn( 'The generateImages method is deprecated and will be removed in the next major release (not before Jan. 1 2027). Please use the generateContent method with image models instead. See https://ai.google.dev/gemini-api/docs/deprecations#imagen-models and https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/capabilities/image-generation#generate-images', ); } return await this.generateImagesInternal(params).then((apiResponse) => { let positivePromptSafetyAttributes; const generatedImages = []; if (apiResponse?.generatedImages) { for (const generatedImage of apiResponse.generatedImages) { if ( generatedImage && generatedImage?.safetyAttributes && generatedImage?.safetyAttributes?.contentType === 'Positive Prompt' ) { positivePromptSafetyAttributes = generatedImage?.safetyAttributes; } else { generatedImages.push(generatedImage); } } } let response: types.GenerateImagesResponse; if (positivePromptSafetyAttributes) { response = { generatedImages: generatedImages, positivePromptSafetyAttributes: positivePromptSafetyAttributes, sdkHttpResponse: apiResponse.sdkHttpResponse, }; } else { response = { generatedImages: generatedImages, sdkHttpResponse: apiResponse.sdkHttpResponse, }; } return response; }); }; list = async ( params?: types.ListModelsParameters, ): Promise> => { const defaultConfig: types.ListModelsConfig = { queryBase: true, }; const actualConfig: types.ListModelsConfig = { ...defaultConfig, ...params?.config, }; const actualParams: types.ListModelsParameters = { config: actualConfig, }; if (this.apiClient.isVertexAI()) { if (!actualParams.config!.queryBase) { if (actualParams.config?.filter) { throw new Error( 'Filtering tuned models list is only supported in Gemini Developer API mode, not in Gemini Enterprise Agent Platform mode.', ); } else { actualParams.config!.filter = 'labels.tune-type:*'; } } } return new Pager( PagedItem.PAGED_ITEM_MODELS, (x: types.ListModelsParameters) => this.listInternal(x), await this.listInternal(actualParams), actualParams, ); }; /** * Edits an image based on a prompt, list of reference images, and configuration. * * @param params - The parameters for editing an image. * @return The response from the API. * * @example * ```ts * const response = await client.models.editImage({ * model: 'imagen-3.0-capability-001', * prompt: 'Generate an image containing a mug with the product logo [1] visible on the side of the mug.', * referenceImages: [subjectReferenceImage] * config: { * numberOfImages: 1, * includeRaiReason: true, * }, * }); * console.log(response?.generatedImages?.[0]?.image?.imageBytes); * ``` */ editImage = async ( params: types.EditImageParameters, ): Promise => { if (!Models.loggedEditImageWarning) { Models.loggedEditImageWarning = true; console.warn( 'The editImage method is deprecated and will be removed in the next major release (not before Jan. 1 2027). Please use the generateContent method with image models instead. See https://ai.google.dev/gemini-api/docs/deprecations#imagen-models and https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/capabilities/gemini-edit-images#edit-an-image', ); } const paramsInternal: _internal_types.EditImageParametersInternal = { model: params.model, prompt: params.prompt, referenceImages: [], config: params.config, }; if (params.referenceImages) { if (params.referenceImages) { paramsInternal.referenceImages = params.referenceImages.map((img) => img.toReferenceImageAPI(), ); } } return await this.editImageInternal(paramsInternal); }; /** * Upscales an image based on an image, upscale factor, and configuration. * Only supported in Gemini Enterprise Agent Platform currently. * * @param params - The parameters for upscaling an image. * @return The response from the API. * * @example * ```ts * const response = await client.models.upscaleImage({ * model: 'imagen-4.0-upscale-preview', * image: image, * upscaleFactor: 'x2', * config: { * includeRaiReason: true, * }, * }); * console.log(response?.generatedImages?.[0]?.image?.imageBytes); * ``` */ upscaleImage = async ( params: types.UpscaleImageParameters, ): Promise => { let apiConfig: _internal_types.UpscaleImageAPIConfigInternal = { numberOfImages: 1, mode: 'upscale', }; if (params.config) { apiConfig = {...apiConfig, ...params.config}; } const apiParams: _internal_types.UpscaleImageAPIParametersInternal = { model: params.model, image: params.image, upscaleFactor: params.upscaleFactor, config: apiConfig, }; return await this.upscaleImageInternal(apiParams); }; /** * Generates videos based on a text description and configuration. * * @param params - The parameters for generating videos. * @return A Promise which allows you to track the progress and eventually retrieve the generated videos using the operations.get method. * * @example * ```ts * const operation = await ai.models.generateVideos({ * model: 'veo-2.0-generate-001', * source: { * prompt: 'A neon hologram of a cat driving at top speed', * }, * config: { * numberOfVideos: 1 * }); * * while (!operation.done) { * await new Promise(resolve => setTimeout(resolve, 10000)); * operation = await ai.operations.getVideosOperation({operation: operation}); * } * * console.log(operation.response?.generatedVideos?.[0]?.video?.uri); * ``` */ generateVideos = async ( params: types.GenerateVideosParameters, ): Promise => { if ((params.prompt || params.image || params.video) && params.source) { throw new Error( 'Source and prompt/image/video are mutually exclusive. Please only use source.', ); } if (params.prompt || params.image || params.video) { if (!Models.loggedGenerateVideosWarning) { Models.loggedGenerateVideosWarning = true; console.warn( 'The generateVideos method with prompt/image/video arguments is deprecated and will be removed in a future major release (not before 2026-07-31). Please use the source argument instead.', ); } } // Gemini API does not support video bytes. if (!this.apiClient.isVertexAI()) { if (params.video?.uri && params.video?.videoBytes) { params.video = { uri: params.video.uri, mimeType: params.video.mimeType, }; } else if ( params.source?.video?.uri && params.source?.video?.videoBytes ) { params.source.video = { uri: params.source.video.uri, mimeType: params.source.video.mimeType, }; } } return await this.generateVideosInternal(params); }; private async generateContentInternal( params: types.GenerateContentParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.generateContentParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:generateContent', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.GenerateContentResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateContentResponseFromVertex( apiResponse, params, ); const typedResp = new types.GenerateContentResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.generateContentParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:generateContent', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.GenerateContentResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateContentResponseFromMldev( apiResponse, params, ); const typedResp = new types.GenerateContentResponse(); Object.assign(typedResp, resp); return typedResp; }); } } private async generateContentStreamInternal( params: types.GenerateContentParameters, ): Promise> { let response: Promise>; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.generateContentParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:streamGenerateContent?alt=sse', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; const apiClient = this.apiClient; response = apiClient.requestStream({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) as Promise>; return response.then(async function* ( apiResponse: AsyncGenerator, ) { for await (const chunk of apiResponse) { const resp = converters.generateContentResponseFromVertex( (await chunk.json()) as types.GenerateContentResponse, params, ); resp['sdkHttpResponse'] = { headers: chunk.headers, } as types.HttpResponse; const typedResp = new types.GenerateContentResponse(); Object.assign(typedResp, resp); yield typedResp; } }); } else { const body = converters.generateContentParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:streamGenerateContent?alt=sse', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; const apiClient = this.apiClient; response = apiClient.requestStream({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) as Promise>; return response.then(async function* ( apiResponse: AsyncGenerator, ) { for await (const chunk of apiResponse) { const resp = converters.generateContentResponseFromMldev( (await chunk.json()) as types.GenerateContentResponse, params, ); resp['sdkHttpResponse'] = { headers: chunk.headers, } as types.HttpResponse; const typedResp = new types.GenerateContentResponse(); Object.assign(typedResp, resp); yield typedResp; } }); } } /** * Calculates embeddings for the given contents. Only text is supported. * * @param params - The parameters for embedding contents. * @return The response from the API. * * @example * ```ts * const response = await ai.models.embedContent({ * model: 'text-embedding-004', * contents: [ * 'What is your name?', * 'What is your favorite color?', * ], * config: { * outputDimensionality: 64, * }, * }); * console.log(response); * ``` */ private async embedContentInternal( params: types.EmbedContentParametersPrivate, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.embedContentParametersPrivateToVertex( this.apiClient, params, params, ); const endpointUrl = tIsVertexEmbedContentModel(params.model) ? '{model}:embedContent' : '{model}:predict'; path = common.formatMap( endpointUrl, body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.EmbedContentResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.embedContentResponseFromVertex( apiResponse, params, ); const typedResp = new types.EmbedContentResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.embedContentParametersPrivateToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:batchEmbedContents', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.EmbedContentResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.embedContentResponseFromMldev( apiResponse, params, ); const typedResp = new types.EmbedContentResponse(); Object.assign(typedResp, resp); return typedResp; }); } } /** * Private method for generating images. */ private async generateImagesInternal( params: types.GenerateImagesParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.generateImagesParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.GenerateImagesResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateImagesResponseFromVertex( apiResponse, params, ); const typedResp = new types.GenerateImagesResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.generateImagesParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.GenerateImagesResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateImagesResponseFromMldev( apiResponse, params, ); const typedResp = new types.GenerateImagesResponse(); Object.assign(typedResp, resp); return typedResp; }); } } /** * Private method for editing an image. */ private async editImageInternal( params: _internal_types.EditImageParametersInternal, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.editImageParametersInternalToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.EditImageResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.editImageResponseFromVertex( apiResponse, params, ); const typedResp = new types.EditImageResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { throw new Error( 'This method is only supported by the Gemini Enterprise Agent Platform (previously known as Vertex AI).', ); } } /** * Private method for upscaling an image. */ private async upscaleImageInternal( params: _internal_types.UpscaleImageAPIParametersInternal, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.upscaleImageAPIParametersInternalToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.UpscaleImageResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.upscaleImageResponseFromVertex( apiResponse, params, ); const typedResp = new types.UpscaleImageResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { throw new Error( 'This method is only supported by the Gemini Enterprise Agent Platform (previously known as Vertex AI).', ); } } /** * Recontextualizes an image. * * There is one type of recontextualization currently supported: * 1) Virtual Try-On: Generate images of persons modeling fashion products. * * @param params - The parameters for recontextualizing an image. * @return The response from the API. * * @example * ```ts * const response = await ai.models.recontextImage({ * model: 'virtual-try-on-001', * source: { * personImage: personImage, * productImages: [productImage], * }, * config: { * numberOfImages: 1, * }, * }); * console.log(response?.generatedImages?.[0]?.image?.imageBytes); * ``` */ async recontextImage( params: types.RecontextImageParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.recontextImageParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.recontextImageResponseFromVertex( apiResponse, params, ); const typedResp = new types.RecontextImageResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { throw new Error( 'This method is only supported by the Gemini Enterprise Agent Platform (previously known as Vertex AI).', ); } } /** * Segments an image, creating a mask of a specified area. * * @param params - The parameters for segmenting an image. * @return The response from the API. * * @example * ```ts * const response = await ai.models.segmentImage({ * model: 'image-segmentation-001', * source: { * image: image, * }, * config: { * mode: 'foreground', * }, * }); * console.log(response?.generatedMasks?.[0]?.mask?.imageBytes); * ``` */ async segmentImage( params: types.SegmentImageParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.segmentImageParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predict', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.segmentImageResponseFromVertex( apiResponse, params, ); const typedResp = new types.SegmentImageResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { throw new Error( 'This method is only supported by the Gemini Enterprise Agent Platform (previously known as Vertex AI).', ); } } /** * Fetches information about a model by name. * * @example * ```ts * const modelInfo = await ai.models.get({model: 'gemini-2.0-flash'}); * ``` */ async get(params: types.GetModelParameters): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.getModelParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{name}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'GET', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.modelFromVertex(apiResponse, params); return resp as types.Model; }); } else { const body = converters.getModelParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{name}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'GET', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.modelFromMldev(apiResponse, params); return resp as types.Model; }); } } private async listInternal( params: types.ListModelsParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.listModelsParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{models_url}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'GET', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.ListModelsResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.listModelsResponseFromVertex( apiResponse, params, ); const typedResp = new types.ListModelsResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.listModelsParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{models_url}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'GET', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.ListModelsResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.listModelsResponseFromMldev( apiResponse, params, ); const typedResp = new types.ListModelsResponse(); Object.assign(typedResp, resp); return typedResp; }); } } /** * Updates a tuned model by its name. * * @param params - The parameters for updating the model. * @return The response from the API. * * @example * ```ts * const response = await ai.models.update({ * model: 'tuned-model-name', * config: { * displayName: 'New display name', * description: 'New description', * }, * }); * ``` */ async update(params: types.UpdateModelParameters): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.updateModelParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'PATCH', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.modelFromVertex(apiResponse, params); return resp as types.Model; }); } else { const body = converters.updateModelParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{name}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'PATCH', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.modelFromMldev(apiResponse, params); return resp as types.Model; }); } } /** * Deletes a tuned model by its name. * * @param params - The parameters for deleting the model. * @return The response from the API. * * @example * ```ts * const response = await ai.models.delete({model: 'tuned-model-name'}); * ``` */ async delete( params: types.DeleteModelParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.deleteModelParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{name}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'DELETE', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.DeleteModelResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.deleteModelResponseFromVertex( apiResponse, params, ); const typedResp = new types.DeleteModelResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.deleteModelParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{name}', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'DELETE', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.DeleteModelResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.deleteModelResponseFromMldev( apiResponse, params, ); const typedResp = new types.DeleteModelResponse(); Object.assign(typedResp, resp); return typedResp; }); } } /** * Counts the number of tokens in the given contents. Multimodal input is * supported for Gemini models. * * @param params - The parameters for counting tokens. * @return The response from the API. * * @example * ```ts * const response = await ai.models.countTokens({ * model: 'gemini-2.0-flash', * contents: 'The quick brown fox jumps over the lazy dog.' * }); * console.log(response); * ``` */ async countTokens( params: types.CountTokensParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.countTokensParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:countTokens', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.CountTokensResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.countTokensResponseFromVertex( apiResponse, params, ); const typedResp = new types.CountTokensResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.countTokensParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:countTokens', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.CountTokensResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.countTokensResponseFromMldev( apiResponse, params, ); const typedResp = new types.CountTokensResponse(); Object.assign(typedResp, resp); return typedResp; }); } } /** * Given a list of contents, returns a corresponding TokensInfo containing * the list of tokens and list of token ids. * * This method is not supported by the Gemini Developer API. * * @param params - The parameters for computing tokens. * @return The response from the API. * * @example * ```ts * const response = await ai.models.computeTokens({ * model: 'gemini-2.0-flash', * contents: 'What is your name?' * }); * console.log(response); * ``` */ async computeTokens( params: types.ComputeTokensParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.computeTokensParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:computeTokens', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json().then((jsonResponse) => { const response = jsonResponse as types.ComputeTokensResponse; response.sdkHttpResponse = { headers: httpResponse.headers, } as types.HttpResponse; return response; }); }) as Promise; return response.then((apiResponse) => { const resp = converters.computeTokensResponseFromVertex( apiResponse, params, ); const typedResp = new types.ComputeTokensResponse(); Object.assign(typedResp, resp); return typedResp; }); } else { throw new Error( 'This method is only supported by the Gemini Enterprise Agent Platform (previously known as Vertex AI).', ); } } /** * Private method for generating videos. */ private async generateVideosInternal( params: types.GenerateVideosParameters, ): Promise { let response: Promise; let path: string = ''; let queryParams: Record = {}; if (this.apiClient.isVertexAI()) { const body = converters.generateVideosParametersToVertex( this.apiClient, params, params, ); path = common.formatMap( '{model}:predictLongRunning', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateVideosOperationFromVertex( apiResponse, params, ); const typedResp = new types.GenerateVideosOperation(); Object.assign(typedResp, resp); return typedResp; }); } else { const body = converters.generateVideosParametersToMldev( this.apiClient, params, params, ); path = common.formatMap( '{model}:predictLongRunning', body['_url'] as Record, ); queryParams = body['_query'] as Record; delete body['_url']; delete body['_query']; response = this.apiClient .request({ path: path, queryParams: queryParams, body: JSON.stringify(body), httpMethod: 'POST', httpOptions: params.config?.httpOptions, abortSignal: params.config?.abortSignal, }) .then((httpResponse) => { return httpResponse.json(); }) as Promise; return response.then((apiResponse) => { const resp = converters.generateVideosOperationFromMldev( apiResponse, params, ); const typedResp = new types.GenerateVideosOperation(); Object.assign(typedResp, resp); return typedResp; }); } } }