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.

1,035 lines (1,021 loc) 35.5 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/edge/index.ts var index_exports = {}; __export(index_exports, { createVertex: () => createVertex2, vertex: () => vertex }); module.exports = __toCommonJS(index_exports); // src/edge/google-vertex-provider-edge.ts var import_provider_utils7 = require("@ai-sdk/provider-utils"); // src/google-vertex-provider.ts var import_internal3 = require("@ai-sdk/google/internal"); var import_provider_utils5 = require("@ai-sdk/provider-utils"); // src/version.ts var VERSION = true ? "4.0.137" : "0.0.0-test"; // src/google-vertex-embedding-model.ts var import_provider = require("@ai-sdk/provider"); var import_provider_utils2 = require("@ai-sdk/provider-utils"); var import_v43 = require("zod/v4"); // src/google-vertex-error.ts var import_provider_utils = require("@ai-sdk/provider-utils"); var import_v4 = require("zod/v4"); var googleVertexErrorDataSchema = import_v4.z.object({ error: import_v4.z.object({ code: import_v4.z.number().nullable(), message: import_v4.z.string(), status: import_v4.z.string() }) }); var googleVertexFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)( { errorSchema: googleVertexErrorDataSchema, errorToMessage: (data) => data.error.message } ); // src/google-vertex-embedding-options.ts var import_v42 = require("zod/v4"); var googleVertexEmbeddingModelOptions = import_v42.z.object({ /** * Optional. Optional reduced dimension for the output embedding. * If set, excessive values in the output embedding are truncated from the end. */ outputDimensionality: import_v42.z.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: import_v42.z.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: import_v42.z.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: import_v42.z.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 (0, import_provider_utils2.parseProviderOptions)({ provider: "vertex", providerOptions, schema: googleVertexEmbeddingModelOptions }); if (googleOptions == null) { googleOptions = await (0, import_provider_utils2.parseProviderOptions)({ provider: "google", providerOptions, schema: googleVertexEmbeddingModelOptions }); } googleOptions = googleOptions != null ? googleOptions : {}; if (values.length > this.maxEmbeddingsPerCall) { throw new import_provider.TooManyEmbeddingValuesForCallError({ provider: this.provider, modelId: this.modelId, maxEmbeddingsPerCall: this.maxEmbeddingsPerCall, values }); } const mergedHeaders = (0, import_provider_utils2.combineHeaders)( await (0, import_provider_utils2.resolve)(this.config.headers), headers ); const url = `${this.config.baseURL}/models/${this.modelId}:predict`; const { responseHeaders, value: response, rawValue } = await (0, import_provider_utils2.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: (0, import_provider_utils2.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 = import_v43.z.object({ predictions: import_v43.z.array( import_v43.z.object({ embeddings: import_v43.z.object({ values: import_v43.z.array(import_v43.z.number()), statistics: import_v43.z.object({ token_count: import_v43.z.number() }) }) }) ) }); // src/google-vertex-image-model.ts var import_internal = require("@ai-sdk/google/internal"); var import_provider_utils3 = require("@ai-sdk/provider-utils"); var import_v44 = require("zod/v4"); var GoogleVertexImageModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v3"; } get maxImagesPerCall() { if (isGeminiModel(this.modelId)) { return 10; } return 4; } get provider() { return this.config.provider; } async doGenerate(options) { if (isGeminiModel(this.modelId)) { return this.doGenerateGemini(options); } return this.doGenerateImagen(options); } async doGenerateImagen({ 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 (0, import_provider_utils3.parseProviderOptions)({ provider: "vertex", providerOptions, schema: googleVertexImageModelOptionsSchema }); 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 (0, import_provider_utils3.postJsonToApi)({ url: `${this.config.baseURL}/models/${this.modelId}:predict`, headers: (0, import_provider_utils3.combineHeaders)(await (0, import_provider_utils3.resolve)(this.config.headers), headers), body, failedResponseHandler: googleVertexFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)( 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 : [] } } }; } async doGenerateGemini({ prompt, n, size, aspectRatio, seed, providerOptions, headers, abortSignal, files, mask }) { var _a, _b, _c, _d, _e, _f, _g, _h, _i; const warnings = []; if (mask != null) { throw new Error( "Gemini image models do not support mask-based image editing." ); } if (n != null && n > 1) { throw new Error( "Gemini image models do not support generating a set number of images per call. Use n=1 or omit the n parameter." ); } if (size != null) { warnings.push({ type: "unsupported", feature: "size", details: "This model does not support the `size` option. Use `aspectRatio` instead." }); } const userContent = []; if (prompt != null) { userContent.push({ type: "text", text: prompt }); } if (files != null && files.length > 0) { for (const file of files) { if (file.type === "url") { userContent.push({ type: "file", data: new URL(file.url), mediaType: "image/*" }); } else { userContent.push({ type: "file", data: typeof file.data === "string" ? file.data : new Uint8Array(file.data), mediaType: file.mediaType }); } } } const languageModelPrompt = [ { role: "user", content: userContent } ]; const languageModel = new import_internal.GoogleGenerativeAILanguageModel(this.modelId, { provider: this.config.provider, baseURL: this.config.baseURL, headers: (_a = this.config.headers) != null ? _a : {}, fetch: this.config.fetch, generateId: (_b = this.config.generateId) != null ? _b : import_provider_utils3.generateId, supportedUrls: () => ({ "*": [/^https?:\/\/.*$/, /^gs:\/\/.*$/] }) }); const result = await languageModel.doGenerate({ prompt: languageModelPrompt, seed, providerOptions: { vertex: { responseModalities: ["IMAGE"], imageConfig: aspectRatio ? { aspectRatio } : void 0, ...(_c = providerOptions == null ? void 0 : providerOptions.vertex) != null ? _c : {} } }, headers, abortSignal }); const currentDate = (_f = (_e = (_d = this.config._internal) == null ? void 0 : _d.currentDate) == null ? void 0 : _e.call(_d)) != null ? _f : /* @__PURE__ */ new Date(); const images = []; for (const part of result.content) { if (part.type === "file" && part.mediaType.startsWith("image/")) { images.push((0, import_provider_utils3.convertToBase64)(part.data)); } } return { images, warnings, providerMetadata: { vertex: { images: images.map(() => ({})) } }, response: { timestamp: currentDate, modelId: this.modelId, headers: (_g = result.response) == null ? void 0 : _g.headers }, usage: result.usage ? { inputTokens: result.usage.inputTokens.total, outputTokens: result.usage.outputTokens.total, totalTokens: ((_h = result.usage.inputTokens.total) != null ? _h : 0) + ((_i = result.usage.outputTokens.total) != null ? _i : 0) } : void 0 }; } }; function isGeminiModel(modelId) { return modelId.startsWith("gemini-"); } var vertexImageResponseSchema = import_v44.z.object({ predictions: import_v44.z.array( import_v44.z.object({ bytesBase64Encoded: import_v44.z.string(), mimeType: import_v44.z.string(), prompt: import_v44.z.string().nullish() }) ).nullish() }); var googleVertexImageModelOptionsSchema = import_v44.z.object({ negativePrompt: import_v44.z.string().nullish(), personGeneration: import_v44.z.enum(["dont_allow", "allow_adult", "allow_all"]).nullish(), safetySetting: import_v44.z.enum([ "block_low_and_above", "block_medium_and_above", "block_only_high", "block_none" ]).nullish(), addWatermark: import_v44.z.boolean().nullish(), storageUri: import_v44.z.string().nullish(), sampleImageSize: import_v44.z.enum(["1K", "2K"]).nullish(), /** * Configuration for image editing operations */ edit: import_v44.z.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: import_v44.z.number().nullish(), // Edit mode options // https://cloud.google.com/vertex-ai/generative-ai/docs/image/edit-insert-objects mode: import_v44.z.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: import_v44.z.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: import_v44.z.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 (0, import_provider_utils3.convertUint8ArrayToBase64)(file.data); } // src/google-vertex-tools.ts var import_internal2 = require("@ai-sdk/google/internal"); var googleVertexTools = { googleSearch: import_internal2.googleTools.googleSearch, enterpriseWebSearch: import_internal2.googleTools.enterpriseWebSearch, googleMaps: import_internal2.googleTools.googleMaps, urlContext: import_internal2.googleTools.urlContext, fileSearch: import_internal2.googleTools.fileSearch, codeExecution: import_internal2.googleTools.codeExecution, vertexRagStore: import_internal2.googleTools.vertexRagStore }; // src/google-vertex-video-model.ts var import_provider2 = require("@ai-sdk/provider"); var import_provider_utils4 = require("@ai-sdk/provider-utils"); var import_v45 = require("zod/v4"); var GoogleVertexVideoModel = class { constructor(modelId, config) { this.modelId = modelId; this.config = config; this.specificationVersion = "v3"; } get provider() { return this.config.provider; } get maxVideosPerCall() { return 4; } async doGenerate(options) { var _a, _b, _c, _d, _e, _f; 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 warnings = []; const vertexOptions = await (0, import_provider_utils4.parseProviderOptions)({ provider: "vertex", providerOptions: options.providerOptions, schema: googleVertexVideoModelOptionsSchema }); const instances = [{}]; const instance = instances[0]; if (options.prompt != null) { instance.prompt = options.prompt; } if (options.image != null) { if (options.image.type === "url") { warnings.push({ type: "unsupported", feature: "URL-based image input", details: "Vertex AI video models require base64-encoded images or GCS URIs. URL will be ignored." }); } else { const base64Data = typeof options.image.data === "string" ? options.image.data : (0, import_provider_utils4.convertUint8ArrayToBase64)(options.image.data); instance.image = { bytesBase64Encoded: base64Data, mimeType: options.image.mediaType }; } } if ((vertexOptions == null ? void 0 : vertexOptions.referenceImages) != null) { instance.referenceImages = vertexOptions.referenceImages; } const parameters = { sampleCount: options.n }; if (options.aspectRatio) { parameters.aspectRatio = options.aspectRatio; } if (options.resolution) { const resolutionMap = { "1280x720": "720p", "1920x1080": "1080p", "3840x2160": "4k" }; parameters.resolution = resolutionMap[options.resolution] || options.resolution; } if (options.duration) { parameters.durationSeconds = options.duration; } if (options.seed) { parameters.seed = options.seed; } if (vertexOptions != null) { const opts = vertexOptions; if (opts.personGeneration !== void 0 && opts.personGeneration !== null) { parameters.personGeneration = opts.personGeneration; } if (opts.negativePrompt !== void 0 && opts.negativePrompt !== null) { parameters.negativePrompt = opts.negativePrompt; } if (opts.generateAudio !== void 0 && opts.generateAudio !== null) { parameters.generateAudio = opts.generateAudio; } if (opts.gcsOutputDirectory !== void 0 && opts.gcsOutputDirectory !== null) { parameters.gcsOutputDirectory = opts.gcsOutputDirectory; } for (const [key, value] of Object.entries(opts)) { if (![ "pollIntervalMs", "pollTimeoutMs", "personGeneration", "negativePrompt", "generateAudio", "gcsOutputDirectory", "referenceImages" ].includes(key)) { parameters[key] = value; } } } const { value: operation } = await (0, import_provider_utils4.postJsonToApi)({ url: `${this.config.baseURL}/models/${this.modelId}:predictLongRunning`, headers: (0, import_provider_utils4.combineHeaders)( await (0, import_provider_utils4.resolve)(this.config.headers), options.headers ), body: { instances, parameters }, successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)( vertexOperationSchema ), failedResponseHandler: googleVertexFailedResponseHandler, abortSignal: options.abortSignal, fetch: this.config.fetch }); const operationName = operation.name; if (!operationName) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_ERROR", message: "No operation name returned from API" }); } const pollIntervalMs = (_d = vertexOptions == null ? void 0 : vertexOptions.pollIntervalMs) != null ? _d : 1e4; const pollTimeoutMs = (_e = vertexOptions == null ? void 0 : vertexOptions.pollTimeoutMs) != null ? _e : 6e5; const startTime = Date.now(); let finalOperation = operation; let responseHeaders; while (!finalOperation.done) { if (Date.now() - startTime > pollTimeoutMs) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_TIMEOUT", message: `Video generation timed out after ${pollTimeoutMs}ms` }); } await (0, import_provider_utils4.delay)(pollIntervalMs); if ((_f = options.abortSignal) == null ? void 0 : _f.aborted) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_ABORTED", message: "Video generation request was aborted" }); } const { value: statusOperation, responseHeaders: pollHeaders } = await (0, import_provider_utils4.postJsonToApi)({ url: `${this.config.baseURL}/models/${this.modelId}:fetchPredictOperation`, headers: (0, import_provider_utils4.combineHeaders)( await (0, import_provider_utils4.resolve)(this.config.headers), options.headers ), body: { operationName }, successfulResponseHandler: (0, import_provider_utils4.createJsonResponseHandler)( vertexOperationSchema ), failedResponseHandler: googleVertexFailedResponseHandler, abortSignal: options.abortSignal, fetch: this.config.fetch }); finalOperation = statusOperation; responseHeaders = pollHeaders; } if (finalOperation.error) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_FAILED", message: `Video generation failed: ${finalOperation.error.message}` }); } const response = finalOperation.response; if (!(response == null ? void 0 : response.videos) || response.videos.length === 0) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_ERROR", message: `No videos in response. Response: ${JSON.stringify(finalOperation)}` }); } const videos = []; const videoMetadata = []; for (const video of response.videos) { if (video.bytesBase64Encoded) { videos.push({ type: "base64", data: video.bytesBase64Encoded, mediaType: video.mimeType || "video/mp4" }); videoMetadata.push({ mimeType: video.mimeType }); } else if (video.gcsUri) { videos.push({ type: "url", url: video.gcsUri, mediaType: video.mimeType || "video/mp4" }); videoMetadata.push({ gcsUri: video.gcsUri, mimeType: video.mimeType }); } } if (videos.length === 0) { throw new import_provider2.AISDKError({ name: "VERTEX_VIDEO_GENERATION_ERROR", message: "No valid videos in response" }); } return { videos, warnings, response: { timestamp: currentDate, modelId: this.modelId, headers: responseHeaders }, providerMetadata: { "google-vertex": { videos: videoMetadata } } }; } }; var vertexOperationSchema = import_v45.z.object({ name: import_v45.z.string().nullish(), done: import_v45.z.boolean().nullish(), error: import_v45.z.object({ code: import_v45.z.number().nullish(), message: import_v45.z.string(), status: import_v45.z.string().nullish() }).nullish(), response: import_v45.z.object({ videos: import_v45.z.array( import_v45.z.object({ bytesBase64Encoded: import_v45.z.string().nullish(), gcsUri: import_v45.z.string().nullish(), mimeType: import_v45.z.string().nullish() }) ).nullish(), raiMediaFilteredCount: import_v45.z.number().nullish() }).nullish() }); var googleVertexVideoModelOptionsSchema = (0, import_provider_utils4.lazySchema)( () => (0, import_provider_utils4.zodSchema)( import_v45.z.object({ pollIntervalMs: import_v45.z.number().positive().nullish(), pollTimeoutMs: import_v45.z.number().positive().nullish(), personGeneration: import_v45.z.enum(["dont_allow", "allow_adult", "allow_all"]).nullish(), negativePrompt: import_v45.z.string().nullish(), generateAudio: import_v45.z.boolean().nullish(), gcsOutputDirectory: import_v45.z.string().nullish(), referenceImages: import_v45.z.array( import_v45.z.object({ bytesBase64Encoded: import_v45.z.string().nullish(), gcsUri: import_v45.z.string().nullish() }) ).nullish() }).passthrough() ) ); // 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) ? (0, import_provider_utils5.normalizeHeaders)(init.headers) : {}, "x-goog-api-key": apiKey } }; return (customFetch != null ? customFetch : fetch)(url.toString(), modifiedInit); }; } function createVertex(options = {}) { const apiKey = (0, import_provider_utils5.loadOptionalSetting)({ settingValue: options.apiKey, environmentVariableName: "GOOGLE_VERTEX_API_KEY" }); const loadVertexProject = () => (0, import_provider_utils5.loadSetting)({ settingValue: options.project, settingName: "project", environmentVariableName: "GOOGLE_VERTEX_PROJECT", description: "Google Vertex project" }); const loadVertexLocation = () => (0, import_provider_utils5.loadSetting)({ settingValue: options.location, settingName: "location", environmentVariableName: "GOOGLE_VERTEX_LOCATION", description: "Google Vertex location" }); const loadBaseURL = () => { var _a, _b; if (apiKey) { return (_a = (0, import_provider_utils5.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 = (0, import_provider_utils5.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 (0, import_provider_utils5.resolve)((_a = options.headers) != null ? _a : {}); return (0, import_provider_utils5.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 import_internal3.GoogleGenerativeAILanguageModel(modelId, { ...createConfig("chat"), generateId: (_a = options.generateId) != null ? _a : import_provider_utils5.generateId, supportedUrls: () => ({ "*": [ // HTTP URLs: /^https?:\/\/.*$/, // Google Cloud Storage URLs: /^gs:\/\/.*$/ ] }) }); }; const createEmbeddingModel = (modelId) => new GoogleVertexEmbeddingModel(modelId, createConfig("embedding")); const createImageModel = (modelId) => { var _a; return new GoogleVertexImageModel(modelId, { ...createConfig("image"), generateId: (_a = options.generateId) != null ? _a : import_provider_utils5.generateId }); }; const createVideoModel = (modelId) => { var _a; return new GoogleVertexVideoModel(modelId, { ...createConfig("video"), generateId: (_a = options.generateId) != null ? _a : import_provider_utils5.generateId }); }; 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.video = createVideoModel; provider.videoModel = createVideoModel; provider.tools = googleVertexTools; return provider; } // src/edge/google-vertex-auth-edge.ts var import_provider_utils6 = require("@ai-sdk/provider-utils"); var loadCredentials = async () => { try { return { clientEmail: (0, import_provider_utils6.loadSetting)({ settingValue: void 0, settingName: "clientEmail", environmentVariableName: "GOOGLE_CLIENT_EMAIL", description: "Google client email" }), privateKey: (0, import_provider_utils6.loadSetting)({ settingValue: void 0, settingName: "privateKey", environmentVariableName: "GOOGLE_PRIVATE_KEY", description: "Google private key" }), privateKeyId: (0, import_provider_utils6.loadOptionalSetting)({ settingValue: void 0, environmentVariableName: "GOOGLE_PRIVATE_KEY_ID" }) }; } catch (error) { throw new Error(`Failed to load Google credentials: ${error.message}`); } }; var base64url = (str) => { return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); }; var importPrivateKey = async (pemKey) => { const pemHeader = "-----BEGIN PRIVATE KEY-----"; const pemFooter = "-----END PRIVATE KEY-----"; const pemContents = pemKey.replace(pemHeader, "").replace(pemFooter, "").replace(/\s/g, ""); const binaryString = atob(pemContents); const binaryData = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { binaryData[i] = binaryString.charCodeAt(i); } return await crypto.subtle.importKey( "pkcs8", binaryData, { name: "RSASSA-PKCS1-v1_5", hash: "SHA-256" }, true, ["sign"] ); }; var buildJwt = async (credentials) => { const now = Math.floor(Date.now() / 1e3); const header = { alg: "RS256", typ: "JWT" }; if (credentials.privateKeyId) { header.kid = credentials.privateKeyId; } const payload = { iss: credentials.clientEmail, scope: "https://www.googleapis.com/auth/cloud-platform", aud: "https://oauth2.googleapis.com/token", exp: now + 3600, iat: now }; const privateKey = await importPrivateKey(credentials.privateKey); const signingInput = `${base64url(JSON.stringify(header))}.${base64url( JSON.stringify(payload) )}`; const encoder = new TextEncoder(); const data = encoder.encode(signingInput); const signature = await crypto.subtle.sign( "RSASSA-PKCS1-v1_5", privateKey, data ); const signatureBase64 = base64url( String.fromCharCode(...new Uint8Array(signature)) ); return `${base64url(JSON.stringify(header))}.${base64url( JSON.stringify(payload) )}.${signatureBase64}`; }; async function generateAuthToken(credentials) { try { const creds = credentials || await loadCredentials(); const jwt = await buildJwt(creds); const response = await fetch("https://oauth2.googleapis.com/token", { method: "POST", headers: (0, import_provider_utils6.withUserAgentSuffix)( { "Content-Type": "application/x-www-form-urlencoded" }, `ai-sdk/google-vertex/${VERSION}`, (0, import_provider_utils6.getRuntimeEnvironmentUserAgent)() ), body: new URLSearchParams({ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer", assertion: jwt }) }); if (!response.ok) { throw new Error(`Token request failed: ${response.statusText}`); } const data = await response.json(); return data.access_token; } catch (error) { throw error; } } // src/edge/google-vertex-provider-edge.ts function createVertex2(options = {}) { const apiKey = (0, import_provider_utils7.loadOptionalSetting)({ settingValue: options.apiKey, environmentVariableName: "GOOGLE_VERTEX_API_KEY" }); if (apiKey) { return createVertex(options); } return createVertex({ ...options, headers: async () => ({ Authorization: `Bearer ${await generateAuthToken( options.googleCredentials )}`, ...await (0, import_provider_utils7.resolve)(options.headers) }) }); } var vertex = createVertex2(); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { createVertex, vertex }); //# sourceMappingURL=index.js.map