@mastra/core
Version:
Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.
1,531 lines (1,523 loc) • 130 kB
JavaScript
import { lazyValidator, zodSchema, lazySchema, createProviderDefinedToolFactoryWithOutputSchema, createIdGenerator, withoutTrailingSlash, resolve, postJsonToApi, createJsonErrorResponseHandler, createJsonResponseHandler, combineHeaders, createEventSourceResponseHandler, withUserAgentSuffix, loadOptionalSetting, APICallError, safeValidateTypes, safeParseJSON, asSchema, AISDKError, convertBase64ToUint8Array, getErrorMessage, getFromApi, convertUint8ArrayToBase64, isAbortError, getErrorMessage2, delay, validateDownloadUrl, getRuntimeEnvironmentUserAgent, readResponseWithSizeLimit, DEFAULT_MAX_DOWNLOAD_SIZE } from './chunk-7PQ4WG3V.js';
import { z } from 'zod/v4';
import { z as z$1 } from 'zod';
function getContext() {
return {
headers: {}
};
}
async function getVercelOidcToken() {
if (process.env.VERCEL_OIDC_TOKEN) {
return process.env.VERCEL_OIDC_TOKEN ?? "";
}
throw new Error("@vercel/oidc is not available in the vendored @internal AI packages. Provide an API key instead.");
}
var marker = "vercel.ai.gateway.error";
var symbol = Symbol.for(marker);
var _a;
var _b;
var GatewayError = class _GatewayError extends (_b = Error, _a = symbol, _b) {
constructor({
message,
statusCode = 500,
cause
}) {
super(message);
this[_a] = true;
this.statusCode = statusCode;
this.cause = cause;
}
/**
* Checks if the given error is a Gateway Error.
* @param {unknown} error - The error to check.
* @returns {boolean} True if the error is a Gateway Error, false otherwise.
*/
static isInstance(error) {
return _GatewayError.hasMarker(error);
}
static hasMarker(error) {
return typeof error === "object" && error !== null && symbol in error && error[symbol] === true;
}
};
var name = "GatewayAuthenticationError";
var marker2 = `vercel.ai.gateway.error.${name}`;
var symbol2 = Symbol.for(marker2);
var _a2;
var _b2;
var GatewayAuthenticationError = class _GatewayAuthenticationError extends (_b2 = GatewayError, _a2 = symbol2, _b2) {
constructor({
message = "Authentication failed",
statusCode = 401,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a2] = true;
this.name = name;
this.type = "authentication_error";
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol2 in error;
}
/**
* Creates a contextual error message when authentication fails
*/
static createContextualError({
apiKeyProvided,
oidcTokenProvided,
message = "Authentication failed",
statusCode = 401,
cause
}) {
let contextualMessage;
if (apiKeyProvided) {
contextualMessage = `AI Gateway authentication failed: Invalid API key.
Create a new API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.`;
} else if (oidcTokenProvided) {
contextualMessage = `AI Gateway authentication failed: Invalid OIDC token.
Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.
Alternatively, use an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys`;
} else {
contextualMessage = `AI Gateway authentication failed: No authentication provided.
Option 1 - API key:
Create an API key: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys
Provide via 'apiKey' option or 'AI_GATEWAY_API_KEY' environment variable.
Option 2 - OIDC token:
Run 'npx vercel link' to link your project, then 'vc env pull' to fetch the token.`;
}
return new _GatewayAuthenticationError({
message: contextualMessage,
statusCode,
cause
});
}
};
var name2 = "GatewayInvalidRequestError";
var marker3 = `vercel.ai.gateway.error.${name2}`;
var symbol3 = Symbol.for(marker3);
var _a3;
var _b3;
var GatewayInvalidRequestError = class extends (_b3 = GatewayError, _a3 = symbol3, _b3) {
constructor({
message = "Invalid request",
statusCode = 400,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a3] = true;
this.name = name2;
this.type = "invalid_request_error";
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol3 in error;
}
};
var name3 = "GatewayRateLimitError";
var marker4 = `vercel.ai.gateway.error.${name3}`;
var symbol4 = Symbol.for(marker4);
var _a4;
var _b4;
var GatewayRateLimitError = class extends (_b4 = GatewayError, _a4 = symbol4, _b4) {
constructor({
message = "Rate limit exceeded",
statusCode = 429,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a4] = true;
this.name = name3;
this.type = "rate_limit_exceeded";
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol4 in error;
}
};
var name4 = "GatewayModelNotFoundError";
var marker5 = `vercel.ai.gateway.error.${name4}`;
var symbol5 = Symbol.for(marker5);
var modelNotFoundParamSchema = lazyValidator(
() => zodSchema(
z.object({
modelId: z.string()
})
)
);
var _a5;
var _b5;
var GatewayModelNotFoundError = class extends (_b5 = GatewayError, _a5 = symbol5, _b5) {
constructor({
message = "Model not found",
statusCode = 404,
modelId,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a5] = true;
this.name = name4;
this.type = "model_not_found";
this.modelId = modelId;
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol5 in error;
}
};
var name5 = "GatewayInternalServerError";
var marker6 = `vercel.ai.gateway.error.${name5}`;
var symbol6 = Symbol.for(marker6);
var _a6;
var _b6;
var GatewayInternalServerError = class extends (_b6 = GatewayError, _a6 = symbol6, _b6) {
constructor({
message = "Internal server error",
statusCode = 500,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a6] = true;
this.name = name5;
this.type = "internal_server_error";
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol6 in error;
}
};
var name6 = "GatewayResponseError";
var marker7 = `vercel.ai.gateway.error.${name6}`;
var symbol7 = Symbol.for(marker7);
var _a7;
var _b7;
var GatewayResponseError = class extends (_b7 = GatewayError, _a7 = symbol7, _b7) {
constructor({
message = "Invalid response from Gateway",
statusCode = 502,
response,
validationError,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a7] = true;
this.name = name6;
this.type = "response_error";
this.response = response;
this.validationError = validationError;
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol7 in error;
}
};
async function createGatewayErrorFromResponse({
response,
statusCode,
defaultMessage = "Gateway request failed",
cause,
authMethod
}) {
const parseResult = await safeValidateTypes({
value: response,
schema: gatewayErrorResponseSchema
});
if (!parseResult.success) {
return new GatewayResponseError({
message: `Invalid error response format: ${defaultMessage}`,
statusCode,
response,
validationError: parseResult.error,
cause
});
}
const validatedResponse = parseResult.value;
const errorType = validatedResponse.error.type;
const message = validatedResponse.error.message;
switch (errorType) {
case "authentication_error":
return GatewayAuthenticationError.createContextualError({
apiKeyProvided: authMethod === "api-key",
oidcTokenProvided: authMethod === "oidc",
statusCode,
cause
});
case "invalid_request_error":
return new GatewayInvalidRequestError({ message, statusCode, cause });
case "rate_limit_exceeded":
return new GatewayRateLimitError({ message, statusCode, cause });
case "model_not_found": {
const modelResult = await safeValidateTypes({
value: validatedResponse.error.param,
schema: modelNotFoundParamSchema
});
return new GatewayModelNotFoundError({
message,
statusCode,
modelId: modelResult.success ? modelResult.value.modelId : void 0,
cause
});
}
case "internal_server_error":
return new GatewayInternalServerError({ message, statusCode, cause });
default:
return new GatewayInternalServerError({ message, statusCode, cause });
}
}
var gatewayErrorResponseSchema = lazyValidator(
() => zodSchema(
z.object({
error: z.object({
message: z.string(),
type: z.string().nullish(),
param: z.unknown().nullish(),
code: z.union([z.string(), z.number()]).nullish()
})
})
)
);
function extractApiCallResponse(error) {
if (error.data !== void 0) {
return error.data;
}
if (error.responseBody != null) {
try {
return JSON.parse(error.responseBody);
} catch (e) {
return error.responseBody;
}
}
return {};
}
var name7 = "GatewayTimeoutError";
var marker8 = `vercel.ai.gateway.error.${name7}`;
var symbol8 = Symbol.for(marker8);
var _a8;
var _b8;
var GatewayTimeoutError = class _GatewayTimeoutError extends (_b8 = GatewayError, _a8 = symbol8, _b8) {
constructor({
message = "Request timed out",
statusCode = 408,
cause
} = {}) {
super({ message, statusCode, cause });
this[_a8] = true;
this.name = name7;
this.type = "timeout_error";
}
static isInstance(error) {
return GatewayError.hasMarker(error) && symbol8 in error;
}
/**
* Creates a helpful timeout error message with troubleshooting guidance
*/
static createTimeoutError({
originalMessage,
statusCode = 408,
cause
}) {
const message = `Gateway request timed out: ${originalMessage}
This is a client-side timeout. To resolve this, increase your timeout configuration: https://vercel.com/docs/ai-gateway/capabilities/video-generation#extending-timeouts-for-node.js`;
return new _GatewayTimeoutError({
message,
statusCode,
cause
});
}
};
function isTimeoutError(error) {
if (!(error instanceof Error)) {
return false;
}
const errorCode = error.code;
if (typeof errorCode === "string") {
const undiciTimeoutCodes = [
"UND_ERR_HEADERS_TIMEOUT",
"UND_ERR_BODY_TIMEOUT",
"UND_ERR_CONNECT_TIMEOUT"
];
return undiciTimeoutCodes.includes(errorCode);
}
return false;
}
async function asGatewayError(error, authMethod) {
var _a93;
if (GatewayError.isInstance(error)) {
return error;
}
if (isTimeoutError(error)) {
return GatewayTimeoutError.createTimeoutError({
originalMessage: error instanceof Error ? error.message : "Unknown error",
cause: error
});
}
if (APICallError.isInstance(error)) {
if (error.cause && isTimeoutError(error.cause)) {
return GatewayTimeoutError.createTimeoutError({
originalMessage: error.message,
cause: error
});
}
return await createGatewayErrorFromResponse({
response: extractApiCallResponse(error),
statusCode: (_a93 = error.statusCode) != null ? _a93 : 500,
defaultMessage: "Gateway request failed",
cause: error,
authMethod
});
}
return await createGatewayErrorFromResponse({
response: {},
statusCode: 500,
defaultMessage: error instanceof Error ? `Gateway request failed: ${error.message}` : "Unknown Gateway error",
cause: error,
authMethod
});
}
var GATEWAY_AUTH_METHOD_HEADER = "ai-gateway-auth-method";
async function parseAuthMethod(headers) {
const result = await safeValidateTypes({
value: headers[GATEWAY_AUTH_METHOD_HEADER],
schema: gatewayAuthMethodSchema
});
return result.success ? result.value : void 0;
}
var gatewayAuthMethodSchema = lazyValidator(
() => zodSchema(z.union([z.literal("api-key"), z.literal("oidc")]))
);
var KNOWN_MODEL_TYPES = ["embedding", "image", "language"];
var GatewayFetchMetadata = class {
constructor(config) {
this.config = config;
}
async getAvailableModels() {
try {
const { value } = await getFromApi({
url: `${this.config.baseURL}/config`,
headers: await resolve(this.config.headers()),
successfulResponseHandler: createJsonResponseHandler(
gatewayAvailableModelsResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
fetch: this.config.fetch
});
return value;
} catch (error) {
throw await asGatewayError(error);
}
}
async getCredits() {
try {
const baseUrl = new URL(this.config.baseURL);
const { value } = await getFromApi({
url: `${baseUrl.origin}/v1/credits`,
headers: await resolve(this.config.headers()),
successfulResponseHandler: createJsonResponseHandler(
gatewayCreditsResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
fetch: this.config.fetch
});
return value;
} catch (error) {
throw await asGatewayError(error);
}
}
};
var gatewayAvailableModelsResponseSchema = lazyValidator(
() => zodSchema(
z.object({
models: z.array(
z.object({
id: z.string(),
name: z.string(),
description: z.string().nullish(),
pricing: z.object({
input: z.string(),
output: z.string(),
input_cache_read: z.string().nullish(),
input_cache_write: z.string().nullish()
}).transform(
({ input, output, input_cache_read, input_cache_write }) => ({
input,
output,
...input_cache_read ? { cachedInputTokens: input_cache_read } : {},
...input_cache_write ? { cacheCreationInputTokens: input_cache_write } : {}
})
).nullish(),
specification: z.object({
specificationVersion: z.literal("v2"),
provider: z.string(),
modelId: z.string()
}),
modelType: z.string().nullish()
})
).transform(
(models) => models.filter(
(m) => m.modelType == null || KNOWN_MODEL_TYPES.includes(m.modelType)
)
)
})
)
);
var gatewayCreditsResponseSchema = lazyValidator(
() => zodSchema(
z.object({
balance: z.string(),
total_used: z.string()
}).transform(({ balance, total_used }) => ({
balance,
totalUsed: total_used
}))
)
);
var GatewaySpendReport = class {
constructor(config) {
this.config = config;
}
async getSpendReport(params) {
try {
const baseUrl = new URL(this.config.baseURL);
const searchParams = new URLSearchParams();
searchParams.set("start_date", params.startDate);
searchParams.set("end_date", params.endDate);
if (params.groupBy) {
searchParams.set("group_by", params.groupBy);
}
if (params.datePart) {
searchParams.set("date_part", params.datePart);
}
if (params.userId) {
searchParams.set("user_id", params.userId);
}
if (params.model) {
searchParams.set("model", params.model);
}
if (params.provider) {
searchParams.set("provider", params.provider);
}
if (params.credentialType) {
searchParams.set("credential_type", params.credentialType);
}
if (params.tags && params.tags.length > 0) {
searchParams.set("tags", params.tags.join(","));
}
const { value } = await getFromApi({
url: `${baseUrl.origin}/v1/report?${searchParams.toString()}`,
headers: await resolve(this.config.headers()),
successfulResponseHandler: createJsonResponseHandler(
gatewaySpendReportResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
fetch: this.config.fetch
});
return value;
} catch (error) {
throw await asGatewayError(error);
}
}
};
var gatewaySpendReportResponseSchema = lazySchema(
() => zodSchema(
z.object({
results: z.array(
z.object({
day: z.string().optional(),
hour: z.string().optional(),
user: z.string().optional(),
model: z.string().optional(),
tag: z.string().optional(),
provider: z.string().optional(),
credential_type: z.enum(["byok", "system"]).optional(),
total_cost: z.number(),
market_cost: z.number().optional(),
input_tokens: z.number().optional(),
output_tokens: z.number().optional(),
cached_input_tokens: z.number().optional(),
cache_creation_input_tokens: z.number().optional(),
reasoning_tokens: z.number().optional(),
request_count: z.number().optional()
}).transform(
({
credential_type,
total_cost,
market_cost,
input_tokens,
output_tokens,
cached_input_tokens,
cache_creation_input_tokens,
reasoning_tokens,
request_count,
...rest
}) => ({
...rest,
...credential_type !== void 0 ? { credentialType: credential_type } : {},
totalCost: total_cost,
...market_cost !== void 0 ? { marketCost: market_cost } : {},
...input_tokens !== void 0 ? { inputTokens: input_tokens } : {},
...output_tokens !== void 0 ? { outputTokens: output_tokens } : {},
...cached_input_tokens !== void 0 ? { cachedInputTokens: cached_input_tokens } : {},
...cache_creation_input_tokens !== void 0 ? { cacheCreationInputTokens: cache_creation_input_tokens } : {},
...reasoning_tokens !== void 0 ? { reasoningTokens: reasoning_tokens } : {},
...request_count !== void 0 ? { requestCount: request_count } : {}
})
)
)
})
)
);
var GatewayGenerationInfoFetcher = class {
constructor(config) {
this.config = config;
}
async getGenerationInfo(params) {
try {
const baseUrl = new URL(this.config.baseURL);
const { value } = await getFromApi({
url: `${baseUrl.origin}/v1/generation?id=${encodeURIComponent(params.id)}`,
headers: await resolve(this.config.headers()),
successfulResponseHandler: createJsonResponseHandler(
gatewayGenerationInfoResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
fetch: this.config.fetch
});
return value;
} catch (error) {
throw await asGatewayError(error);
}
}
};
var gatewayGenerationInfoResponseSchema = lazySchema(
() => zodSchema(
z.object({
data: z.object({
id: z.string(),
total_cost: z.number(),
upstream_inference_cost: z.number(),
usage: z.number(),
created_at: z.string(),
model: z.string(),
is_byok: z.boolean(),
provider_name: z.string(),
streamed: z.boolean(),
finish_reason: z.string(),
latency: z.number(),
generation_time: z.number(),
native_tokens_prompt: z.number(),
native_tokens_completion: z.number(),
native_tokens_reasoning: z.number(),
native_tokens_cached: z.number(),
native_tokens_cache_creation: z.number(),
billable_web_search_calls: z.number()
}).transform(
({
total_cost,
upstream_inference_cost,
created_at,
is_byok,
provider_name,
finish_reason,
generation_time,
native_tokens_prompt,
native_tokens_completion,
native_tokens_reasoning,
native_tokens_cached,
native_tokens_cache_creation,
billable_web_search_calls,
...rest
}) => ({
...rest,
totalCost: total_cost,
upstreamInferenceCost: upstream_inference_cost,
createdAt: created_at,
isByok: is_byok,
providerName: provider_name,
finishReason: finish_reason,
generationTime: generation_time,
promptTokens: native_tokens_prompt,
completionTokens: native_tokens_completion,
reasoningTokens: native_tokens_reasoning,
cachedTokens: native_tokens_cached,
cacheCreationTokens: native_tokens_cache_creation,
billableWebSearchCalls: billable_web_search_calls
})
)
}).transform(({ data }) => data)
)
);
var GatewayLanguageModel = class {
constructor(modelId, config) {
this.modelId = modelId;
this.config = config;
this.specificationVersion = "v2";
this.supportedUrls = { "*/*": [/.*/] };
}
get provider() {
return this.config.provider;
}
async getArgs(options) {
const { abortSignal: _abortSignal, ...optionsWithoutSignal } = options;
return {
args: this.maybeEncodeFileParts(optionsWithoutSignal),
warnings: []
};
}
async doGenerate(options) {
const { args, warnings } = await this.getArgs(options);
const { abortSignal } = options;
const resolvedHeaders = await resolve(this.config.headers());
try {
const {
responseHeaders,
value: responseBody,
rawValue: rawResponse
} = await postJsonToApi({
url: this.getUrl(),
headers: combineHeaders(
resolvedHeaders,
options.headers,
this.getModelConfigHeaders(this.modelId, false),
await resolve(this.config.o11yHeaders)
),
body: args,
successfulResponseHandler: createJsonResponseHandler(z.any()),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
...abortSignal && { abortSignal },
fetch: this.config.fetch
});
return {
...responseBody,
request: { body: args },
response: { headers: responseHeaders, body: rawResponse },
warnings
};
} catch (error) {
throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
}
}
async doStream(options) {
const { args, warnings } = await this.getArgs(options);
const { abortSignal } = options;
const resolvedHeaders = await resolve(this.config.headers());
try {
const { value: response, responseHeaders } = await postJsonToApi({
url: this.getUrl(),
headers: combineHeaders(
resolvedHeaders,
options.headers,
this.getModelConfigHeaders(this.modelId, true),
await resolve(this.config.o11yHeaders)
),
body: args,
successfulResponseHandler: createEventSourceResponseHandler(z.any()),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
...abortSignal && { abortSignal },
fetch: this.config.fetch
});
return {
stream: response.pipeThrough(
new TransformStream({
start(controller) {
if (warnings.length > 0) {
controller.enqueue({ type: "stream-start", warnings });
}
},
transform(chunk, controller) {
if (chunk.success) {
const streamPart = chunk.value;
if (streamPart.type === "raw" && !options.includeRawChunks) {
return;
}
if (streamPart.type === "response-metadata" && streamPart.timestamp && typeof streamPart.timestamp === "string") {
streamPart.timestamp = new Date(streamPart.timestamp);
}
controller.enqueue(streamPart);
} else {
controller.error(
chunk.error
);
}
}
})
),
request: { body: args },
response: { headers: responseHeaders }
};
} catch (error) {
throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
}
}
isFilePart(part) {
return part && typeof part === "object" && "type" in part && part.type === "file";
}
/**
* Encodes file parts in the prompt to base64. Mutates the passed options
* instance directly to avoid copying the file data.
* @param options - The options to encode.
* @returns The options with the file parts encoded.
*/
maybeEncodeFileParts(options) {
for (const message of options.prompt) {
for (const part of message.content) {
if (this.isFilePart(part)) {
const filePart = part;
if (filePart.data instanceof Uint8Array) {
const buffer = Uint8Array.from(filePart.data);
const base64Data = Buffer.from(buffer).toString("base64");
filePart.data = new URL(
`data:${filePart.mediaType || "application/octet-stream"};base64,${base64Data}`
);
}
}
}
}
return options;
}
getUrl() {
return `${this.config.baseURL}/language-model`;
}
getModelConfigHeaders(modelId, streaming) {
return {
"ai-language-model-specification-version": "2",
"ai-language-model-id": modelId,
"ai-language-model-streaming": String(streaming)
};
}
};
var GatewayEmbeddingModel = class {
constructor(modelId, config) {
this.modelId = modelId;
this.config = config;
this.specificationVersion = "v2";
this.maxEmbeddingsPerCall = 2048;
this.supportsParallelCalls = true;
}
get provider() {
return this.config.provider;
}
async doEmbed({
values,
headers,
abortSignal,
providerOptions
}) {
var _a93;
const resolvedHeaders = await resolve(this.config.headers());
try {
const {
responseHeaders,
value: responseBody,
rawValue
} = await postJsonToApi({
url: this.getUrl(),
headers: combineHeaders(
resolvedHeaders,
headers != null ? headers : {},
this.getModelConfigHeaders(),
await resolve(this.config.o11yHeaders)
),
body: {
input: values.length === 1 ? values[0] : values,
...providerOptions ? { providerOptions } : {}
},
successfulResponseHandler: createJsonResponseHandler(
gatewayEmbeddingResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
...abortSignal && { abortSignal },
fetch: this.config.fetch
});
return {
embeddings: responseBody.embeddings,
usage: (_a93 = responseBody.usage) != null ? _a93 : void 0,
providerMetadata: responseBody.providerMetadata,
response: { headers: responseHeaders, body: rawValue }
};
} catch (error) {
throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
}
}
getUrl() {
return `${this.config.baseURL}/embedding-model`;
}
getModelConfigHeaders() {
return {
"ai-embedding-model-specification-version": "2",
"ai-model-id": this.modelId
};
}
};
var gatewayEmbeddingResponseSchema = lazyValidator(
() => zodSchema(
z.object({
embeddings: z.array(z.array(z.number())),
usage: z.object({ tokens: z.number() }).nullish(),
providerMetadata: z.record(z.string(), z.record(z.string(), z.unknown())).optional()
})
)
);
var GatewayImageModel = class {
constructor(modelId, config) {
this.modelId = modelId;
this.config = config;
this.specificationVersion = "v2";
this.maxImagesPerCall = Number.MAX_SAFE_INTEGER;
}
get provider() {
return this.config.provider;
}
async doGenerate({
prompt,
n,
size,
aspectRatio,
seed,
providerOptions,
headers,
abortSignal
}) {
var _a93, _b9, _c, _d;
const resolvedHeaders = await resolve(this.config.headers());
try {
const {
responseHeaders,
value: responseBody
} = await postJsonToApi({
url: this.getUrl(),
headers: combineHeaders(
resolvedHeaders,
headers != null ? headers : {},
this.getModelConfigHeaders(),
await resolve(this.config.o11yHeaders)
),
body: {
prompt,
n,
...size && { size },
...aspectRatio && { aspectRatio },
...seed && { seed },
...providerOptions && { providerOptions }
},
successfulResponseHandler: createJsonResponseHandler(
gatewayImageResponseSchema
),
failedResponseHandler: createJsonErrorResponseHandler({
errorSchema: z.any(),
errorToMessage: (data) => data
}),
...abortSignal && { abortSignal },
fetch: this.config.fetch
});
return {
images: responseBody.images,
// Always base64 strings from server
warnings: (_a93 = responseBody.warnings) != null ? _a93 : [],
providerMetadata: responseBody.providerMetadata,
response: {
timestamp: /* @__PURE__ */ new Date(),
modelId: this.modelId,
headers: responseHeaders
},
...responseBody.usage != null && {
usage: {
inputTokens: (_b9 = responseBody.usage.inputTokens) != null ? _b9 : void 0,
outputTokens: (_c = responseBody.usage.outputTokens) != null ? _c : void 0,
totalTokens: (_d = responseBody.usage.totalTokens) != null ? _d : void 0
}
}
};
} catch (error) {
throw await asGatewayError(error, await parseAuthMethod(resolvedHeaders));
}
}
getUrl() {
return `${this.config.baseURL}/image-model`;
}
getModelConfigHeaders() {
return {
"ai-image-model-specification-version": "2",
"ai-model-id": this.modelId
};
}
};
var providerMetadataEntrySchema = z.object({
images: z.array(z.unknown()).optional()
}).catchall(z.unknown());
var gatewayImageUsageSchema = z.object({
inputTokens: z.number().nullish(),
outputTokens: z.number().nullish(),
totalTokens: z.number().nullish()
});
var gatewayImageResponseSchema = z.object({
images: z.array(z.string()),
// Always base64 strings over the wire
warnings: z.array(
z.object({
type: z.literal("other"),
message: z.string()
})
).optional(),
providerMetadata: z.record(z.string(), providerMetadataEntrySchema).optional(),
usage: gatewayImageUsageSchema.optional()
});
var parallelSearchInputSchema = lazySchema(
() => zodSchema(
z$1.object({
objective: z$1.string().describe(
"Natural-language description of the web research goal, including source or freshness guidance and broader context from the task. Maximum 5000 characters."
),
search_queries: z$1.array(z$1.string()).optional().describe(
"Optional search queries to supplement the objective. Maximum 200 characters per query."
),
mode: z$1.enum(["one-shot", "agentic"]).optional().describe(
'Mode preset: "one-shot" for comprehensive results with longer excerpts (default), "agentic" for concise, token-efficient results for multi-step workflows.'
),
max_results: z$1.number().optional().describe(
"Maximum number of results to return (1-20). Defaults to 10 if not specified."
),
source_policy: z$1.object({
include_domains: z$1.array(z$1.string()).optional().describe("List of domains to include in search results."),
exclude_domains: z$1.array(z$1.string()).optional().describe("List of domains to exclude from search results."),
after_date: z$1.string().optional().describe(
"Only include results published after this date (ISO 8601 format)."
)
}).optional().describe(
"Source policy for controlling which domains to include/exclude and freshness."
),
excerpts: z$1.object({
max_chars_per_result: z$1.number().optional().describe("Maximum characters per result."),
max_chars_total: z$1.number().optional().describe("Maximum total characters across all results.")
}).optional().describe("Excerpt configuration for controlling result length."),
fetch_policy: z$1.object({
max_age_seconds: z$1.number().optional().describe(
"Maximum age in seconds for cached content. Set to 0 to always fetch fresh content."
)
}).optional().describe("Fetch policy for controlling content freshness.")
})
)
);
var parallelSearchOutputSchema = lazySchema(
() => zodSchema(
z$1.union([
// Success response
z$1.object({
searchId: z$1.string(),
results: z$1.array(
z$1.object({
url: z$1.string(),
title: z$1.string(),
excerpt: z$1.string(),
publishDate: z$1.string().nullable().optional(),
relevanceScore: z$1.number().optional()
})
)
}),
// Error response
z$1.object({
error: z$1.enum([
"api_error",
"rate_limit",
"timeout",
"invalid_input",
"configuration_error",
"unknown"
]),
statusCode: z$1.number().optional(),
message: z$1.string()
})
])
)
);
var parallelSearchToolFactory = createProviderDefinedToolFactoryWithOutputSchema({
id: "gateway.parallel_search",
name: "parallel_search",
inputSchema: parallelSearchInputSchema,
outputSchema: parallelSearchOutputSchema
});
var parallelSearch = (config = {}) => parallelSearchToolFactory(config);
var perplexitySearchInputSchema = lazySchema(
() => zodSchema(
z$1.object({
query: z$1.union([z$1.string(), z$1.array(z$1.string())]).describe(
"Search query (string) or multiple queries (array of up to 5 strings). Multi-query searches return combined results from all queries."
),
max_results: z$1.number().optional().describe(
"Maximum number of search results to return (1-20, default: 10)"
),
max_tokens_per_page: z$1.number().optional().describe(
"Maximum number of tokens to extract per search result page (256-2048, default: 2048)"
),
max_tokens: z$1.number().optional().describe(
"Maximum total tokens across all search results (default: 25000, max: 1000000)"
),
country: z$1.string().optional().describe(
"Two-letter ISO 3166-1 alpha-2 country code for regional search results (e.g., 'US', 'GB', 'FR')"
),
search_domain_filter: z$1.array(z$1.string()).optional().describe(
"List of domains to include or exclude from search results (max 20). To include: ['nature.com', 'science.org']. To exclude: ['-example.com', '-spam.net']"
),
search_language_filter: z$1.array(z$1.string()).optional().describe(
"List of ISO 639-1 language codes to filter results (max 10, lowercase). Examples: ['en', 'fr', 'de']"
),
search_after_date: z$1.string().optional().describe(
"Include only results published after this date. Format: 'MM/DD/YYYY' (e.g., '3/1/2025'). Cannot be used with search_recency_filter."
),
search_before_date: z$1.string().optional().describe(
"Include only results published before this date. Format: 'MM/DD/YYYY' (e.g., '3/15/2025'). Cannot be used with search_recency_filter."
),
last_updated_after_filter: z$1.string().optional().describe(
"Include only results last updated after this date. Format: 'MM/DD/YYYY' (e.g., '3/1/2025'). Cannot be used with search_recency_filter."
),
last_updated_before_filter: z$1.string().optional().describe(
"Include only results last updated before this date. Format: 'MM/DD/YYYY' (e.g., '3/15/2025'). Cannot be used with search_recency_filter."
),
search_recency_filter: z$1.enum(["day", "week", "month", "year"]).optional().describe(
"Filter results by relative time period. Cannot be used with search_after_date or search_before_date."
)
})
)
);
var perplexitySearchOutputSchema = lazySchema(
() => zodSchema(
z$1.union([
// Success response
z$1.object({
results: z$1.array(
z$1.object({
title: z$1.string(),
url: z$1.string(),
snippet: z$1.string(),
date: z$1.string().optional(),
lastUpdated: z$1.string().optional()
})
),
id: z$1.string()
}),
// Error response
z$1.object({
error: z$1.enum([
"api_error",
"rate_limit",
"timeout",
"invalid_input",
"unknown"
]),
statusCode: z$1.number().optional(),
message: z$1.string()
})
])
)
);
var perplexitySearchToolFactory = createProviderDefinedToolFactoryWithOutputSchema({
id: "gateway.perplexity_search",
name: "perplexity_search",
inputSchema: perplexitySearchInputSchema,
outputSchema: perplexitySearchOutputSchema
});
var perplexitySearch = (config = {}) => perplexitySearchToolFactory(config);
var gatewayTools = {
/**
* Search the web using Parallel AI's Search API for LLM-optimized excerpts.
*
* Takes a natural language objective and returns relevant excerpts,
* replacing multiple keyword searches with a single call for broad
* or complex queries. Supports different search types for depth vs
* breadth tradeoffs.
*/
parallelSearch,
/**
* Search the web using Perplexity's Search API for real-time information,
* news, research papers, and articles.
*
* Provides ranked search results with advanced filtering options including
* domain, language, date range, and recency filters.
*/
perplexitySearch
};
async function getVercelRequestId() {
var _a93;
return (_a93 = getContext().headers) == null ? void 0 : _a93["x-vercel-id"];
}
var VERSION = "2.0.88";
var AI_GATEWAY_PROTOCOL_VERSION = "0.0.1";
function createGatewayProvider(options = {}) {
var _a93, _b9;
let pendingMetadata = null;
let metadataCache = null;
const cacheRefreshMillis = (_a93 = options.metadataCacheRefreshMillis) != null ? _a93 : 1e3 * 60 * 5;
let lastFetchTime = 0;
const baseURL = (_b9 = withoutTrailingSlash(options.baseURL)) != null ? _b9 : "https://ai-gateway.vercel.sh/v1/ai";
const getHeaders = async () => {
const auth = await getGatewayAuthToken(options);
if (auth) {
return withUserAgentSuffix(
{
Authorization: `Bearer ${auth.token}`,
"ai-gateway-protocol-version": AI_GATEWAY_PROTOCOL_VERSION,
[GATEWAY_AUTH_METHOD_HEADER]: auth.authMethod,
...options.headers
},
`ai-sdk/gateway/${VERSION}`
);
}
throw GatewayAuthenticationError.createContextualError({
apiKeyProvided: false,
oidcTokenProvided: false,
statusCode: 401
});
};
const createO11yHeaders = () => {
const deploymentId = loadOptionalSetting({
settingValue: void 0,
environmentVariableName: "VERCEL_DEPLOYMENT_ID"
});
const environment = loadOptionalSetting({
settingValue: void 0,
environmentVariableName: "VERCEL_ENV"
});
const region = loadOptionalSetting({
settingValue: void 0,
environmentVariableName: "VERCEL_REGION"
});
const projectId = loadOptionalSetting({
settingValue: void 0,
environmentVariableName: "VERCEL_PROJECT_ID"
});
return async () => {
const requestId = await getVercelRequestId();
return {
...deploymentId && { "ai-o11y-deployment-id": deploymentId },
...environment && { "ai-o11y-environment": environment },
...region && { "ai-o11y-region": region },
...requestId && { "ai-o11y-request-id": requestId },
...projectId && { "ai-o11y-project-id": projectId }
};
};
};
const createLanguageModel = (modelId) => {
return new GatewayLanguageModel(modelId, {
provider: "gateway",
baseURL,
headers: getHeaders,
fetch: options.fetch,
o11yHeaders: createO11yHeaders()
});
};
const getAvailableModels = async () => {
var _a102, _b10, _c;
const now2 = (_c = (_b10 = (_a102 = options._internal) == null ? void 0 : _a102.currentDate) == null ? void 0 : _b10.call(_a102).getTime()) != null ? _c : Date.now();
if (!pendingMetadata || now2 - lastFetchTime > cacheRefreshMillis) {
lastFetchTime = now2;
pendingMetadata = new GatewayFetchMetadata({
baseURL,
headers: getHeaders,
fetch: options.fetch
}).getAvailableModels().then((metadata) => {
metadataCache = metadata;
return metadata;
}).catch(async (error) => {
throw await asGatewayError(
error,
await parseAuthMethod(await getHeaders())
);
});
}
return metadataCache ? Promise.resolve(metadataCache) : pendingMetadata;
};
const getCredits = async () => {
return new GatewayFetchMetadata({
baseURL,
headers: getHeaders,
fetch: options.fetch
}).getCredits().catch(async (error) => {
throw await asGatewayError(
error,
await parseAuthMethod(await getHeaders())
);
});
};
const getSpendReport = async (params) => {
return new GatewaySpendReport({
baseURL,
headers: getHeaders,
fetch: options.fetch
}).getSpendReport(params).catch(async (error) => {
throw await asGatewayError(
error,
await parseAuthMethod(await getHeaders())
);
});
};
const getGenerationInfo = async (params) => {
return new GatewayGenerationInfoFetcher({
baseURL,
headers: getHeaders,
fetch: options.fetch
}).getGenerationInfo(params).catch(async (error) => {
throw await asGatewayError(
error,
await parseAuthMethod(await getHeaders())
);
});
};
const provider = function(modelId) {
if (new.target) {
throw new Error(
"The Gateway Provider model function cannot be called with the new keyword."
);
}
return createLanguageModel(modelId);
};
provider.getAvailableModels = getAvailableModels;
provider.getCredits = getCredits;
provider.getSpendReport = getSpendReport;
provider.getGenerationInfo = getGenerationInfo;
provider.imageModel = (modelId) => {
return new GatewayImageModel(modelId, {
provider: "gateway",
baseURL,
headers: getHeaders,
fetch: options.fetch,
o11yHeaders: createO11yHeaders()
});
};
provider.languageModel = createLanguageModel;
provider.textEmbeddingModel = (modelId) => {
return new GatewayEmbeddingModel(modelId, {
provider: "gateway",
baseURL,
headers: getHeaders,
fetch: options.fetch,
o11yHeaders: createO11yHeaders()
});
};
provider.tools = gatewayTools;
return provider;
}
var gateway = createGatewayProvider();
async function getGatewayAuthToken(options) {
const apiKey = loadOptionalSetting({
settingValue: options.apiKey,
environmentVariableName: "AI_GATEWAY_API_KEY"
});
if (apiKey) {
return {
token: apiKey,
authMethod: "api-key"
};
}
try {
const oidcToken = await getVercelOidcToken();
return {
token: oidcToken,
authMethod: "oidc"
};
} catch (e) {
return null;
}
}
var _globalThis = typeof globalThis === "object" ? globalThis : global;
var VERSION2 = "1.9.0";
var re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;
function _makeCompatibilityCheck(ownVersion) {
var acceptedVersions = /* @__PURE__ */ new Set([ownVersion]);
var rejectedVersions = /* @__PURE__ */ new Set();
var myVersionMatch = ownVersion.match(re);
if (!myVersionMatch) {
return function() {
return false;
};
}
var ownVersionParsed = {
major: +myVersionMatch[1],
minor: +myVersionMatch[2],
patch: +myVersionMatch[3],
prerelease: myVersionMatch[4]
};
if (ownVersionParsed.prerelease != null) {
return function isExactmatch(globalVersion) {
return globalVersion === ownVersion;
};
}
function _reject(v) {
rejectedVersions.add(v);
return false;
}
function _accept(v) {
acceptedVersions.add(v);
return true;
}
return function isCompatible2(globalVersion) {
if (acceptedVersions.has(globalVersion)) {
return true;
}
if (rejectedVersions.has(globalVersion)) {
return false;
}
var globalVersionMatch = globalVersion.match(re);
if (!globalVersionMatch) {
return _reject(globalVersion);
}
var globalVersionParsed = {
major: +globalVersionMatch[1],
minor: +globalVersionMatch[2],
patch: +globalVersionMatch[3],
prerelease: globalVersionMatch[4]
};
if (globalVersionParsed.prerelease != null) {
return _reject(globalVersion);
}
if (ownVersionParsed.major !== globalVersionParsed.major) {
return _reject(globalVersion);
}
if (ownVersionParsed.major === 0) {
if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) {
return _accept(globalVersion);
}
return _reject(globalVersion);
}
if (ownVersionParsed.minor <= globalVersionParsed.minor) {
return _accept(globalVersion);
}
return _reject(globalVersion);
};
}
var isCompatible = _makeCompatibilityCheck(VERSION2);
var major = VERSION2.split(".")[0];
var GLOBAL_OPENTELEMETRY_API_KEY = /* @__PURE__ */ Symbol.for("opentelemetry.js.api." + major);
var _global = _globalThis;
function registerGlobal(type, instance, diag, allowOverride) {
var _a16;
if (allowOverride === void 0) {
allowOverride = false;
}
var api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a16 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a16 !== void 0 ? _a16 : {
version: VERSION2
};
if (!allowOverride && api[type]) {
var err = new Error("@opentelemetry/api: Attempted duplicate registration of API: " + type);
diag.error(err.stack || err.message);
return false;
}
if (api.version !== VERSION2) {
var err = new Error("@opentelemetry/api: Registration of version v" + api.version + " for " + type + " does not match previously registered API v" + VERSION2);
diag.error(err.stack || err.message);
return false;
}
api[type] = instance;
diag.debug("@opentelemetry/api: Registered a global for " + type + " v" + VERSION2 + ".");
return true;
}
function getGlobal(type) {
var _a16, _b9;
var globalVersion = (_a16 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a16 === void 0 ? void 0 : _a16.version;
if (!globalVersion || !isCompatible(globalVersion)) {
return;
}
return (_b9 = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b9 === void 0 ? void 0 : _b9[type];
}
function unregisterGlobal(type, diag) {
diag.debug("@opentelemetry/api: Unregistering a global for " + type + " v" + VERSION2 + ".");
var api = _global[GLOBAL_OPENTELEMETRY_API_KEY];
if (api) {
delete api[type];
}
}
var __read = function(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while (!(r = i.next()).done) ar.push(r.value);
} catch (error) {
e = { error };
} finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
} finally {
if (e) throw e.error;
}
}
return ar;
};
var __spreadArray = function(to, from, pack) {
if (arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var DiagComponentLogger = (
/** @class */
(function() {
function DiagComponentLogger2(props) {
this._namespace = props.namespace || "DiagComponentLogger";
}
DiagComponentLogger2.prototype.debug = function() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy("debug", this._namespace, args);
};
DiagComponentLogger2.prototype.error = function() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy("error", this._namespace, args);
};
DiagComponentLogger2.prototype.info = function() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy("info", this._namespace, args);
};
DiagComponentLogger2.prototype.warn = function() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy("warn", this._namespace, args);
};
DiagComponentLogger2.prototype.verbose = function() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
return logProxy("verbose", this._namespace, args);
};
return DiagComponentLogger2;
})()
);
function logProxy(funcName, namespace, args) {
var logger = getGlobal("diag");
if (!logger) {
return;
}
args.unshift(namespace);
return logger[funcName].apply(logger, __spreadArray([], __read(args), false));
}
var DiagLogLevel;
(function(DiagLogLevel2) {
DiagLogLevel2[DiagLogLevel2["NONE"] = 0] = "NONE";
DiagLogLevel2[DiagLogLevel2["