UNPKG

@ai-sdk/google-vertex

Version:

The **[Google Vertex provider](https://ai-sdk.dev/providers/ai-sdk-providers/google-vertex)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for the [Google Vertex AI](https://cloud.google.com/vertex-ai) APIs.

555 lines (544 loc) 17.8 kB
// src/google-vertex-provider-node.ts import { loadOptionalSetting as loadOptionalSetting2, resolve as resolve4 } from "@ai-sdk/provider-utils"; // src/google-vertex-auth-google-auth-library.ts import { GoogleAuth } from "google-auth-library"; var authInstance = null; var authOptions = null; function getAuth(options) { if (!authInstance || options !== authOptions) { authInstance = new GoogleAuth({ scopes: ["https://www.googleapis.com/auth/cloud-platform"], ...options }); authOptions = options; } return authInstance; } async function generateAuthToken(options) { const auth = getAuth(options || {}); const client = await auth.getClient(); const token = await client.getAccessToken(); return (token == null ? void 0 : token.token) || null; } // src/google-vertex-provider.ts import { GoogleGenerativeAILanguageModel } from "@ai-sdk/google/internal"; import { generateId, loadOptionalSetting, loadSetting, normalizeHeaders, resolve as resolve3, withoutTrailingSlash, withUserAgentSuffix } from "@ai-sdk/provider-utils"; // src/version.ts var VERSION = true ? "4.0.28" : "0.0.0-test"; // src/google-vertex-embedding-model.ts import { TooManyEmbeddingValuesForCallError } from "@ai-sdk/provider"; import { combineHeaders, createJsonResponseHandler, postJsonToApi, resolve, parseProviderOptions } from "@ai-sdk/provider-utils"; import { z as z3 } from "zod/v4"; // src/google-vertex-error.ts import { createJsonErrorResponseHandler } from "@ai-sdk/provider-utils"; import { z } from "zod/v4"; var googleVertexErrorDataSchema = z.object({ error: z.object({ code: z.number().nullable(), message: z.string(), status: z.string() }) }); var googleVertexFailedResponseHandler = createJsonErrorResponseHandler( { errorSchema: googleVertexErrorDataSchema, errorToMessage: (data) => data.error.message } ); // src/google-vertex-embedding-options.ts import { z as z2 } from "zod/v4"; var googleVertexEmbeddingProviderOptions = z2.object({ /** * Optional. Optional reduced dimension for the output embedding. * If set, excessive values in the output embedding are truncated from the end. */ outputDimensionality: z2.number().optional(), /** * Optional. Specifies the task type for generating embeddings. * Supported task types: * - SEMANTIC_SIMILARITY: Optimized for text similarity. * - CLASSIFICATION: Optimized for text classification. * - CLUSTERING: Optimized for clustering texts based on similarity. * - RETRIEVAL_DOCUMENT: Optimized for document retrieval. * - RETRIEVAL_QUERY: Optimized for query-based retrieval. * - QUESTION_ANSWERING: Optimized for answering questions. * - FACT_VERIFICATION: Optimized for verifying factual information. * - CODE_RETRIEVAL_QUERY: Optimized for retrieving code blocks based on natural language queries. */ taskType: z2.enum([ "SEMANTIC_SIMILARITY", "CLASSIFICATION", "CLUSTERING", "RETRIEVAL_DOCUMENT", "RETRIEVAL_QUERY", "QUESTION_ANSWERING", "FACT_VERIFICATION", "CODE_RETRIEVAL_QUERY" ]).optional(), /** * Optional. The title of the document being embedded. * Only valid when task_type is set to 'RETRIEVAL_DOCUMENT'. * Helps the model produce better embeddings by providing additional context. */ title: z2.string().optional(), /** * Optional. When set to true, input text will be truncated. When set to false, * an error is returned if the input text is longer than the maximum length supported by the model. Defaults to true. */ autoTruncate: z2.boolean().optional() }); // src/google-vertex-embedding-model.ts var GoogleVertexEmbeddingModel = class { constructor(modelId, config) { this.specificationVersion = "v3"; this.maxEmbeddingsPerCall = 2048; this.supportsParallelCalls = true; this.modelId = modelId; this.config = config; } get provider() { return this.config.provider; } async doEmbed({ values, headers, abortSignal, providerOptions }) { let googleOptions = await parseProviderOptions({ provider: "vertex", providerOptions, schema: googleVertexEmbeddingProviderOptions }); if (googleOptions == null) { googleOptions = await parseProviderOptions({ provider: "google", providerOptions, schema: googleVertexEmbeddingProviderOptions }); } googleOptions = googleOptions != null ? googleOptions : {}; if (values.length > this.maxEmbeddingsPerCall) { throw new TooManyEmbeddingValuesForCallError({ provider: this.provider, modelId: this.modelId, maxEmbeddingsPerCall: this.maxEmbeddingsPerCall, values }); } const mergedHeaders = combineHeaders( await resolve(this.config.headers), headers ); const url = `${this.config.baseURL}/models/${this.modelId}:predict`; const { responseHeaders, value: response, rawValue } = await postJsonToApi({ url, headers: mergedHeaders, body: { instances: values.map((value) => ({ content: value, task_type: googleOptions.taskType, title: googleOptions.title })), parameters: { outputDimensionality: googleOptions.outputDimensionality, autoTruncate: googleOptions.autoTruncate } }, failedResponseHandler: googleVertexFailedResponseHandler, successfulResponseHandler: createJsonResponseHandler( googleVertexTextEmbeddingResponseSchema ), abortSignal, fetch: this.config.fetch }); return { warnings: [], embeddings: response.predictions.map( (prediction) => prediction.embeddings.values ), usage: { tokens: response.predictions.reduce( (tokenCount, prediction) => tokenCount + prediction.embeddings.statistics.token_count, 0 ) }, response: { headers: responseHeaders, body: rawValue } }; } }; var googleVertexTextEmbeddingResponseSchema = z3.object({ predictions: z3.array( z3.object({ embeddings: z3.object({ values: z3.array(z3.number()), statistics: z3.object({ token_count: z3.number() }) }) }) ) }); // src/google-vertex-image-model.ts import { combineHeaders as combineHeaders2, convertUint8ArrayToBase64, createJsonResponseHandler as createJsonResponseHandler2, parseProviderOptions as parseProviderOptions2, postJsonToApi as postJsonToApi2, resolve as resolve2 } from "@ai-sdk/provider-utils"; import { z as z4 } from "zod/v4"; var GoogleVertexImageModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v3"; // https://cloud.google.com/vertex-ai/generative-ai/docs/model-reference/imagen-api#parameter_list this.maxImagesPerCall = 4; } get provider() { return this.config.provider; } async doGenerate({ prompt, n, size, aspectRatio, seed, providerOptions, headers, abortSignal, files, mask }) { var _a, _b, _c, _d, _e, _f, _g; const warnings = []; if (size != null) { warnings.push({ type: "unsupported", feature: "size", details: "This model does not support the `size` option. Use `aspectRatio` instead." }); } const vertexImageOptions = await parseProviderOptions2({ provider: "vertex", providerOptions, schema: vertexImageProviderOptionsSchema }); const { edit, ...otherOptions } = vertexImageOptions != null ? vertexImageOptions : {}; const { mode: editMode, baseSteps, maskMode, maskDilation } = edit != null ? edit : {}; const isEditMode = files != null && files.length > 0; let body; if (isEditMode) { const referenceImages = []; for (let i = 0; i < files.length; i++) { const file = files[i]; referenceImages.push({ referenceType: "REFERENCE_TYPE_RAW", referenceId: i + 1, referenceImage: { bytesBase64Encoded: getBase64Data(file) } }); } if (mask != null) { referenceImages.push({ referenceType: "REFERENCE_TYPE_MASK", referenceId: files.length + 1, referenceImage: { bytesBase64Encoded: getBase64Data(mask) }, maskImageConfig: { maskMode: maskMode != null ? maskMode : "MASK_MODE_USER_PROVIDED", ...maskDilation != null ? { dilation: maskDilation } : {} } }); } body = { instances: [ { prompt, referenceImages } ], parameters: { sampleCount: n, ...aspectRatio != null ? { aspectRatio } : {}, ...seed != null ? { seed } : {}, editMode: editMode != null ? editMode : "EDIT_MODE_INPAINT_INSERTION", ...baseSteps != null ? { editConfig: { baseSteps } } : {}, ...otherOptions } }; } else { body = { instances: [{ prompt }], parameters: { sampleCount: n, ...aspectRatio != null ? { aspectRatio } : {}, ...seed != null ? { seed } : {}, ...otherOptions } }; } const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date(); const { value: response, responseHeaders } = await postJsonToApi2({ url: `${this.config.baseURL}/models/${this.modelId}:predict`, headers: combineHeaders2(await resolve2(this.config.headers), headers), body, failedResponseHandler: googleVertexFailedResponseHandler, successfulResponseHandler: createJsonResponseHandler2( vertexImageResponseSchema ), abortSignal, fetch: this.config.fetch }); return { images: (_e = (_d = response.predictions) == null ? void 0 : _d.map( ({ bytesBase64Encoded }) => bytesBase64Encoded )) != null ? _e : [], warnings, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders }, providerMetadata: { vertex: { images: (_g = (_f = response.predictions) == null ? void 0 : _f.map((prediction) => { const { // normalize revised prompt property prompt: revisedPrompt } = prediction; return { ...revisedPrompt != null && { revisedPrompt } }; })) != null ? _g : [] } } }; } }; var vertexImageResponseSchema = z4.object({ predictions: z4.array( z4.object({ bytesBase64Encoded: z4.string(), mimeType: z4.string(), prompt: z4.string().nullish() }) ).nullish() }); var vertexImageProviderOptionsSchema = z4.object({ negativePrompt: z4.string().nullish(), personGeneration: z4.enum(["dont_allow", "allow_adult", "allow_all"]).nullish(), safetySetting: z4.enum([ "block_low_and_above", "block_medium_and_above", "block_only_high", "block_none" ]).nullish(), addWatermark: z4.boolean().nullish(), storageUri: z4.string().nullish(), sampleImageSize: z4.enum(["1K", "2K"]).nullish(), /** * Configuration for image editing operations */ edit: z4.object({ /** * An integer that represents the number of sampling steps. * A higher value offers better image quality, a lower value offers better latency. * Try 35 steps to start. If the quality doesn't meet your requirements, * increase the value towards an upper limit of 75. */ baseSteps: z4.number().nullish(), // Edit mode options // https://cloud.google.com/vertex-ai/generative-ai/docs/image/edit-insert-objects mode: z4.enum([ "EDIT_MODE_INPAINT_INSERTION", "EDIT_MODE_INPAINT_REMOVAL", "EDIT_MODE_OUTPAINT", "EDIT_MODE_CONTROLLED_EDITING", "EDIT_MODE_PRODUCT_IMAGE", "EDIT_MODE_BGSWAP" ]).nullish(), /** * The mask mode to use. * - `MASK_MODE_DEFAULT` - Default value for mask mode. * - `MASK_MODE_USER_PROVIDED` - User provided mask. No segmentation needed. * - `MASK_MODE_DETECTION_BOX` - Mask from detected bounding boxes. * - `MASK_MODE_CLOTHING_AREA` - Masks from segmenting the clothing area with open-vocab segmentation. * - `MASK_MODE_PARSED_PERSON` - Masks from segmenting the person body and clothing using the person-parsing model. */ maskMode: z4.enum([ "MASK_MODE_DEFAULT", "MASK_MODE_USER_PROVIDED", "MASK_MODE_DETECTION_BOX", "MASK_MODE_CLOTHING_AREA", "MASK_MODE_PARSED_PERSON" ]).nullish(), /** * Optional. A float value between 0 and 1, inclusive, that represents the * percentage of the image width to grow the mask by. Using dilation helps * compensate for imprecise masks. We recommend a value of 0.01. */ maskDilation: z4.number().nullish() }).nullish() }); function getBase64Data(file) { if (file.type === "url") { throw new Error( "URL-based images are not supported for Google Vertex image editing. Please provide the image data directly." ); } if (typeof file.data === "string") { return file.data; } return convertUint8ArrayToBase64(file.data); } // src/google-vertex-tools.ts import { googleTools } from "@ai-sdk/google/internal"; var googleVertexTools = { googleSearch: googleTools.googleSearch, enterpriseWebSearch: googleTools.enterpriseWebSearch, googleMaps: googleTools.googleMaps, urlContext: googleTools.urlContext, fileSearch: googleTools.fileSearch, codeExecution: googleTools.codeExecution, vertexRagStore: googleTools.vertexRagStore }; // src/google-vertex-provider.ts var EXPRESS_MODE_BASE_URL = "https://aiplatform.googleapis.com/v1/publishers/google"; function createExpressModeFetch(apiKey, customFetch) { return async (url, init) => { const modifiedInit = { ...init, headers: { ...(init == null ? void 0 : init.headers) ? normalizeHeaders(init.headers) : {}, "x-goog-api-key": apiKey } }; return (customFetch != null ? customFetch : fetch)(url.toString(), modifiedInit); }; } function createVertex(options = {}) { const apiKey = loadOptionalSetting({ settingValue: options.apiKey, environmentVariableName: "GOOGLE_VERTEX_API_KEY" }); const loadVertexProject = () => loadSetting({ settingValue: options.project, settingName: "project", environmentVariableName: "GOOGLE_VERTEX_PROJECT", description: "Google Vertex project" }); const loadVertexLocation = () => loadSetting({ settingValue: options.location, settingName: "location", environmentVariableName: "GOOGLE_VERTEX_LOCATION", description: "Google Vertex location" }); const loadBaseURL = () => { var _a, _b; if (apiKey) { return (_a = withoutTrailingSlash(options.baseURL)) != null ? _a : EXPRESS_MODE_BASE_URL; } const region = loadVertexLocation(); const project = loadVertexProject(); const baseHost = `${region === "global" ? "" : region + "-"}aiplatform.googleapis.com`; return (_b = withoutTrailingSlash(options.baseURL)) != null ? _b : `https://${baseHost}/v1beta1/projects/${project}/locations/${region}/publishers/google`; }; const createConfig = (name) => { const getHeaders = async () => { var _a; const originalHeaders = await resolve3((_a = options.headers) != null ? _a : {}); return withUserAgentSuffix( originalHeaders, `ai-sdk/google-vertex/${VERSION}` ); }; return { provider: `google.vertex.${name}`, headers: getHeaders, fetch: apiKey ? createExpressModeFetch(apiKey, options.fetch) : options.fetch, baseURL: loadBaseURL() }; }; const createChatModel = (modelId) => { var _a; return new GoogleGenerativeAILanguageModel(modelId, { ...createConfig("chat"), generateId: (_a = options.generateId) != null ? _a : generateId, supportedUrls: () => ({ "*": [ // HTTP URLs: /^https?:\/\/.*$/, // Google Cloud Storage URLs: /^gs:\/\/.*$/ ] }) }); }; const createEmbeddingModel = (modelId) => new GoogleVertexEmbeddingModel(modelId, createConfig("embedding")); const createImageModel = (modelId) => new GoogleVertexImageModel(modelId, createConfig("image")); const provider = function(modelId) { if (new.target) { throw new Error( "The Google Vertex AI model function cannot be called with the new keyword." ); } return createChatModel(modelId); }; provider.specificationVersion = "v3"; provider.languageModel = createChatModel; provider.embeddingModel = createEmbeddingModel; provider.textEmbeddingModel = createEmbeddingModel; provider.image = createImageModel; provider.imageModel = createImageModel; provider.tools = googleVertexTools; return provider; } // src/google-vertex-provider-node.ts function createVertex2(options = {}) { const apiKey = loadOptionalSetting2({ settingValue: options.apiKey, environmentVariableName: "GOOGLE_VERTEX_API_KEY" }); if (apiKey) { return createVertex(options); } return createVertex({ ...options, headers: async () => ({ Authorization: `Bearer ${await generateAuthToken( options.googleAuthOptions )}`, ...await resolve4(options.headers) }) }); } var vertex = createVertex2(); export { VERSION, createVertex2 as createVertex, vertex }; //# sourceMappingURL=index.mjs.map