@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
JavaScript
"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