@mastra/rag
Version:
The Retrieval-Augmented Generation (RAG) module contains document processing and embedding utilities.
1,652 lines (1,638 loc) • 274 kB
JavaScript
import { Agent } from '@mastra/core/agent';
import { randomUUID, createHash } from 'crypto';
import { z } from 'zod';
import { parse } from 'node-html-better-parser';
import { encodingForModel, getEncoding } from 'js-tiktoken';
import { Big } from 'big.js';
import { createSimilarityPrompt } from '@mastra/core/relevance';
import ZeroEntropy from 'zeroentropy';
import { createTool } from '@mastra/core/tools';
import { embedV2, embedV1 } from '@mastra/core/vector';
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __knownSymbol = (name14, symbol15) => (symbol15 = Symbol[name14]) ? symbol15 : Symbol.for("Symbol." + name14);
var __typeError = (msg) => {
throw TypeError(msg);
};
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
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 __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
__defProp(target, "default", { value: mod, enumerable: true }) ,
mod
));
var __decoratorStart = (base) => [, , , __create(null)];
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
var __decoratorContext = (kind, name14, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name: name14, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
var __runInitializers = (array, flags, self, value) => {
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
return value;
};
var __decorateElement = (array, flags, name14, decorators, target, extra) => {
var fn, it, done, ctx, access, k = flags & 7, s = false, p = false;
var j = array.length + 1 , key = __decoratorStrings[k + 5];
var initializers = (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
var desc = ((target = target.prototype), __getOwnPropDesc({ get [name14]() {
return __privateGet(this, extra);
}, set [name14](x) {
return __privateSet(this, extra, x);
} }, name14));
for (var i = decorators.length - 1; i >= 0; i--) {
ctx = __decoratorContext(k, name14, done = {}, array[3], extraInitializers);
{
ctx.static = s, ctx.private = p, access = ctx.access = { has: (x) => name14 in x };
access.get = (x) => x[name14];
access.set = (x, y) => x[name14] = y;
}
it = (0, decorators[i])({ get: desc.get, set: desc.set } , ctx), done._ = 1;
if (it === void 0) __expectFn(it) && (desc[key] = it );
else if (typeof it !== "object" || it === null) __typeError("Object expected");
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
}
return desc && __defProp(target, name14, desc), target;
};
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
// ../../node_modules/.pnpm/secure-json-parse@2.7.0/node_modules/secure-json-parse/index.js
var require_secure_json_parse = __commonJS({
"../../node_modules/.pnpm/secure-json-parse@2.7.0/node_modules/secure-json-parse/index.js"(exports, module) {
var hasBuffer = typeof Buffer !== "undefined";
var suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
var suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
function _parse(text, reviver, options) {
if (options == null) {
if (reviver !== null && typeof reviver === "object") {
options = reviver;
reviver = void 0;
}
}
if (hasBuffer && Buffer.isBuffer(text)) {
text = text.toString();
}
if (text && text.charCodeAt(0) === 65279) {
text = text.slice(1);
}
const obj = JSON.parse(text, reviver);
if (obj === null || typeof obj !== "object") {
return obj;
}
const protoAction = options && options.protoAction || "error";
const constructorAction = options && options.constructorAction || "error";
if (protoAction === "ignore" && constructorAction === "ignore") {
return obj;
}
if (protoAction !== "ignore" && constructorAction !== "ignore") {
if (suspectProtoRx.test(text) === false && suspectConstructorRx.test(text) === false) {
return obj;
}
} else if (protoAction !== "ignore" && constructorAction === "ignore") {
if (suspectProtoRx.test(text) === false) {
return obj;
}
} else {
if (suspectConstructorRx.test(text) === false) {
return obj;
}
}
return filter(obj, { protoAction, constructorAction, safe: options && options.safe });
}
function filter(obj, { protoAction = "error", constructorAction = "error", safe } = {}) {
let next = [obj];
while (next.length) {
const nodes = next;
next = [];
for (const node of nodes) {
if (protoAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "__proto__")) {
if (safe === true) {
return null;
} else if (protoAction === "error") {
throw new SyntaxError("Object contains forbidden prototype property");
}
delete node.__proto__;
}
if (constructorAction !== "ignore" && Object.prototype.hasOwnProperty.call(node, "constructor") && Object.prototype.hasOwnProperty.call(node.constructor, "prototype")) {
if (safe === true) {
return null;
} else if (constructorAction === "error") {
throw new SyntaxError("Object contains forbidden prototype property");
}
delete node.constructor;
}
for (const key in node) {
const value = node[key];
if (value && typeof value === "object") {
next.push(value);
}
}
}
}
return obj;
}
function parse2(text, reviver, options) {
const stackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
try {
return _parse(text, reviver, options);
} finally {
Error.stackTraceLimit = stackTraceLimit;
}
}
function safeParse(text, reviver) {
const stackTraceLimit = Error.stackTraceLimit;
Error.stackTraceLimit = 0;
try {
return _parse(text, reviver, { safe: true });
} catch (_e) {
return null;
} finally {
Error.stackTraceLimit = stackTraceLimit;
}
}
module.exports = parse2;
module.exports.default = parse2;
module.exports.parse = parse2;
module.exports.safeParse = safeParse;
module.exports.scan = filter;
}
});
// src/document/prompts/format.ts
function format(str, params) {
return str.replace(/{(\w+)}/g, (_, k) => params[k] ?? "");
}
// src/document/prompts/base.ts
var BasePromptTemplate = class {
templateVars = /* @__PURE__ */ new Set();
options = {};
constructor(options) {
const { templateVars } = options;
if (templateVars) {
this.templateVars = new Set(templateVars);
}
if (options.options) {
this.options = options.options;
}
}
};
var PromptTemplate = class _PromptTemplate extends BasePromptTemplate {
#template;
constructor(options) {
const { template, ...rest } = options;
super(rest);
this.#template = template;
}
partialFormat(options) {
const prompt = new _PromptTemplate({
template: this.template,
templateVars: [...this.templateVars],
options: this.options
});
prompt.options = {
...prompt.options,
...options
};
return prompt;
}
format(options) {
const allOptions = {
...this.options,
...options
};
return format(this.template, allOptions);
}
formatMessages(options) {
const prompt = this.format(options);
return [
{
role: "user",
content: prompt
}
];
}
get template() {
return this.#template;
}
};
// src/document/prompts/prompt.ts
var defaultSummaryPrompt = new PromptTemplate({
templateVars: ["context"],
template: `Write a summary of the following. Try to use only the information provided. Try to include as many key details as possible.
{context}
SUMMARY:"""
`
});
var defaultKeywordExtractPrompt = new PromptTemplate({
templateVars: ["maxKeywords", "context"],
template: `
Some text is provided below. Given the text, extract up to {maxKeywords} keywords from the text. Avoid stopwords.
---------------------
{context}
---------------------
Provide keywords in the following comma-separated format: 'KEYWORDS: <keywords>'
`
}).partialFormat({
maxKeywords: "10"
});
var defaultQuestionExtractPrompt = new PromptTemplate({
templateVars: ["numQuestions", "context"],
template: `(
"Given the contextual informations below, generate {numQuestions} questions this context can provides specific answers to which are unlikely to be found else where. Higher-level summaries of surrounding context may be provided as well. "
"Try using these summaries to generate better questions that this context can answer."
"---------------------"
"{context}"
"---------------------"
"Provide questions in the following format: 'QUESTIONS: <questions>'"
)`
}).partialFormat({
numQuestions: "5"
});
var defaultTitleExtractorPromptTemplate = new PromptTemplate({
templateVars: ["context"],
template: `{context}
Give a title that summarizes all of the unique entities, titles or themes found in the context.
Title: `
});
var defaultTitleCombinePromptTemplate = new PromptTemplate({
templateVars: ["context"],
template: `{context}
Based on the above candidate titles and contents, what is the comprehensive title for this document?
Title: `
});
var _hash_dec, _init, _hash;
_hash_dec = [lazyInitHash];
var BaseNode = class {
constructor(init) {
__publicField(this, "id_");
__publicField(this, "metadata");
__publicField(this, "relationships");
__privateAdd(this, _hash, __runInitializers(_init, 8, this, "")), __runInitializers(_init, 11, this);
const { id_, metadata, relationships } = init || {};
this.id_ = id_ ?? randomUUID();
this.metadata = metadata ?? {};
this.relationships = relationships ?? {};
}
get sourceNode() {
const relationship = this.relationships["SOURCE" /* SOURCE */];
if (Array.isArray(relationship)) {
throw new Error("Source object must be a single RelatedNodeInfo object");
}
return relationship;
}
get prevNode() {
const relationship = this.relationships["PREVIOUS" /* PREVIOUS */];
if (Array.isArray(relationship)) {
throw new Error("Previous object must be a single RelatedNodeInfo object");
}
return relationship;
}
get nextNode() {
const relationship = this.relationships["NEXT" /* NEXT */];
if (Array.isArray(relationship)) {
throw new Error("Next object must be a single RelatedNodeInfo object");
}
return relationship;
}
get parentNode() {
const relationship = this.relationships["PARENT" /* PARENT */];
if (Array.isArray(relationship)) {
throw new Error("Parent object must be a single RelatedNodeInfo object");
}
return relationship;
}
get childNodes() {
const relationship = this.relationships["CHILD" /* CHILD */];
if (!Array.isArray(relationship)) {
throw new Error("Child object must be a an array of RelatedNodeInfo objects");
}
return relationship;
}
};
_init = __decoratorStart();
_hash = new WeakMap();
__decorateElement(_init, 4, "hash", _hash_dec, BaseNode, _hash);
__decoratorMetadata(_init, BaseNode);
var TextNode = class extends BaseNode {
text;
startCharIdx;
endCharIdx;
metadataSeparator;
constructor(init = {}) {
super(init);
const { text, startCharIdx, endCharIdx, metadataSeparator } = init;
this.text = text ?? "";
if (startCharIdx) {
this.startCharIdx = startCharIdx;
}
if (endCharIdx) {
this.endCharIdx = endCharIdx;
}
this.metadataSeparator = metadataSeparator ?? "\n";
}
/**
* Generate a hash of the text node.
* The ID is not part of the hash as it can change independent of content.
* @returns
*/
generateHash() {
const hashFunction = createSHA256();
hashFunction.update(`type=${this.type}`);
hashFunction.update(`startCharIdx=${this.startCharIdx} endCharIdx=${this.endCharIdx}`);
hashFunction.update(this.getContent());
return hashFunction.digest();
}
get type() {
return "TEXT" /* TEXT */;
}
getContent() {
const metadataStr = this.getMetadataStr().trim();
return `${metadataStr}
${this.text}`.trim();
}
getMetadataStr() {
const usableMetadataKeys = new Set(Object.keys(this.metadata).sort());
return [...usableMetadataKeys].map((key) => `${key}: ${this.metadata[key]}`).join(this.metadataSeparator);
}
getNodeInfo() {
return { start: this.startCharIdx, end: this.endCharIdx };
}
getText() {
return this.text;
}
};
var Document = class extends TextNode {
constructor(init) {
super(init);
}
get type() {
return "DOCUMENT" /* DOCUMENT */;
}
};
function lazyInitHash(value, _context) {
return {
get() {
const oldValue = value.get.call(this);
if (oldValue === "") {
const hash = this.generateHash();
value.set.call(this, hash);
}
return value.get.call(this);
},
set(newValue) {
value.set.call(this, newValue);
},
init(value2) {
return value2;
}
};
}
function createSHA256() {
const hash = createHash("sha256");
return {
update(data) {
hash.update(data);
},
digest() {
return hash.digest("base64");
}
};
}
// src/document/extractors/base.ts
var BaseExtractor = class {
isTextNodeOnly = true;
/**
*
* @param nodes Nodes to extract metadata from.
* @returns Metadata extracted from the nodes.
*/
async processNodes(nodes) {
let newNodes = nodes;
const curMetadataList = await this.extract(newNodes);
for (const idx in newNodes) {
newNodes[idx].metadata = {
...newNodes[idx].metadata,
...curMetadataList[idx]
};
}
return newNodes;
}
};
// ../../node_modules/.pnpm/@ai-sdk+provider@1.1.3/node_modules/@ai-sdk/provider/dist/index.mjs
var marker = "vercel.ai.error";
var symbol = Symbol.for(marker);
var _a;
var _AISDKError = class _AISDKError2 extends Error {
/**
* Creates an AI SDK Error.
*
* @param {Object} params - The parameters for creating the error.
* @param {string} params.name - The name of the error.
* @param {string} params.message - The error message.
* @param {unknown} [params.cause] - The underlying cause of the error.
*/
constructor({
name: name14,
message,
cause
}) {
super(message);
this[_a] = true;
this.name = name14;
this.cause = cause;
}
/**
* Checks if the given error is an AI SDK Error.
* @param {unknown} error - The error to check.
* @returns {boolean} True if the error is an AI SDK Error, false otherwise.
*/
static isInstance(error) {
return _AISDKError2.hasMarker(error, marker);
}
static hasMarker(error, marker15) {
const markerSymbol = Symbol.for(marker15);
return error != null && typeof error === "object" && markerSymbol in error && typeof error[markerSymbol] === "boolean" && error[markerSymbol] === true;
}
};
_a = symbol;
var AISDKError = _AISDKError;
var name = "AI_APICallError";
var marker2 = `vercel.ai.error.${name}`;
var symbol2 = Symbol.for(marker2);
var _a2;
var APICallError = class extends AISDKError {
constructor({
message,
url,
requestBodyValues,
statusCode,
responseHeaders,
responseBody,
cause,
isRetryable = statusCode != null && (statusCode === 408 || // request timeout
statusCode === 409 || // conflict
statusCode === 429 || // too many requests
statusCode >= 500),
// server error
data
}) {
super({ name, message, cause });
this[_a2] = true;
this.url = url;
this.requestBodyValues = requestBodyValues;
this.statusCode = statusCode;
this.responseHeaders = responseHeaders;
this.responseBody = responseBody;
this.isRetryable = isRetryable;
this.data = data;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker2);
}
};
_a2 = symbol2;
var name2 = "AI_EmptyResponseBodyError";
var marker3 = `vercel.ai.error.${name2}`;
var symbol3 = Symbol.for(marker3);
var _a3;
var EmptyResponseBodyError = class extends AISDKError {
// used in isInstance
constructor({ message = "Empty response body" } = {}) {
super({ name: name2, message });
this[_a3] = true;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker3);
}
};
_a3 = symbol3;
function getErrorMessage(error) {
if (error == null) {
return "unknown error";
}
if (typeof error === "string") {
return error;
}
if (error instanceof Error) {
return error.message;
}
return JSON.stringify(error);
}
var name3 = "AI_InvalidArgumentError";
var marker4 = `vercel.ai.error.${name3}`;
var symbol4 = Symbol.for(marker4);
var _a4;
var InvalidArgumentError = class extends AISDKError {
constructor({
message,
cause,
argument
}) {
super({ name: name3, message, cause });
this[_a4] = true;
this.argument = argument;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker4);
}
};
_a4 = symbol4;
var name4 = "AI_InvalidPromptError";
var marker5 = `vercel.ai.error.${name4}`;
var symbol5 = Symbol.for(marker5);
var _a5;
var InvalidPromptError = class extends AISDKError {
constructor({
prompt,
message,
cause
}) {
super({ name: name4, message: `Invalid prompt: ${message}`, cause });
this[_a5] = true;
this.prompt = prompt;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker5);
}
};
_a5 = symbol5;
var name5 = "AI_InvalidResponseDataError";
var marker6 = `vercel.ai.error.${name5}`;
var symbol6 = Symbol.for(marker6);
var _a6;
var InvalidResponseDataError = class extends AISDKError {
constructor({
data,
message = `Invalid response data: ${JSON.stringify(data)}.`
}) {
super({ name: name5, message });
this[_a6] = true;
this.data = data;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker6);
}
};
_a6 = symbol6;
var name6 = "AI_JSONParseError";
var marker7 = `vercel.ai.error.${name6}`;
var symbol7 = Symbol.for(marker7);
var _a7;
var JSONParseError = class extends AISDKError {
constructor({ text, cause }) {
super({
name: name6,
message: `JSON parsing failed: Text: ${text}.
Error message: ${getErrorMessage(cause)}`,
cause
});
this[_a7] = true;
this.text = text;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker7);
}
};
_a7 = symbol7;
var name7 = "AI_LoadAPIKeyError";
var marker8 = `vercel.ai.error.${name7}`;
var symbol8 = Symbol.for(marker8);
var _a8;
var LoadAPIKeyError = class extends AISDKError {
// used in isInstance
constructor({ message }) {
super({ name: name7, message });
this[_a8] = true;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker8);
}
};
_a8 = symbol8;
var name11 = "AI_TooManyEmbeddingValuesForCallError";
var marker12 = `vercel.ai.error.${name11}`;
var symbol12 = Symbol.for(marker12);
var _a12;
var TooManyEmbeddingValuesForCallError = class extends AISDKError {
constructor(options) {
super({
name: name11,
message: `Too many values for a single embedding call. The ${options.provider} model "${options.modelId}" can only embed up to ${options.maxEmbeddingsPerCall} values per call, but ${options.values.length} values were provided.`
});
this[_a12] = true;
this.provider = options.provider;
this.modelId = options.modelId;
this.maxEmbeddingsPerCall = options.maxEmbeddingsPerCall;
this.values = options.values;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker12);
}
};
_a12 = symbol12;
var name12 = "AI_TypeValidationError";
var marker13 = `vercel.ai.error.${name12}`;
var symbol13 = Symbol.for(marker13);
var _a13;
var _TypeValidationError = class _TypeValidationError2 extends AISDKError {
constructor({ value, cause }) {
super({
name: name12,
message: `Type validation failed: Value: ${JSON.stringify(value)}.
Error message: ${getErrorMessage(cause)}`,
cause
});
this[_a13] = true;
this.value = value;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker13);
}
/**
* Wraps an error into a TypeValidationError.
* If the cause is already a TypeValidationError with the same value, it returns the cause.
* Otherwise, it creates a new TypeValidationError.
*
* @param {Object} params - The parameters for wrapping the error.
* @param {unknown} params.value - The value that failed validation.
* @param {unknown} params.cause - The original error or cause of the validation failure.
* @returns {TypeValidationError} A TypeValidationError instance.
*/
static wrap({
value,
cause
}) {
return _TypeValidationError2.isInstance(cause) && cause.value === value ? cause : new _TypeValidationError2({ value, cause });
}
};
_a13 = symbol13;
var TypeValidationError = _TypeValidationError;
var name13 = "AI_UnsupportedFunctionalityError";
var marker14 = `vercel.ai.error.${name13}`;
var symbol14 = Symbol.for(marker14);
var _a14;
var UnsupportedFunctionalityError = class extends AISDKError {
constructor({
functionality,
message = `'${functionality}' functionality not supported.`
}) {
super({ name: name13, message });
this[_a14] = true;
this.functionality = functionality;
}
static isInstance(error) {
return AISDKError.hasMarker(error, marker14);
}
};
_a14 = symbol14;
// ../../node_modules/.pnpm/nanoid@3.3.11/node_modules/nanoid/non-secure/index.js
var customAlphabet = (alphabet, defaultSize = 21) => {
return (size = defaultSize) => {
let id = "";
let i = size | 0;
while (i--) {
id += alphabet[Math.random() * alphabet.length | 0];
}
return id;
};
};
// ../../node_modules/.pnpm/@ai-sdk+provider-utils@2.2.8_zod@3.25.76/node_modules/@ai-sdk/provider-utils/dist/index.mjs
var import_secure_json_parse = __toESM(require_secure_json_parse());
function combineHeaders(...headers) {
return headers.reduce(
(combinedHeaders, currentHeaders) => ({
...combinedHeaders,
...currentHeaders != null ? currentHeaders : {}
}),
{}
);
}
function createEventSourceParserStream() {
let buffer = "";
let event = void 0;
let data = [];
let lastEventId = void 0;
let retry = void 0;
function parseLine(line, controller) {
if (line === "") {
dispatchEvent(controller);
return;
}
if (line.startsWith(":")) {
return;
}
const colonIndex = line.indexOf(":");
if (colonIndex === -1) {
handleField(line, "");
return;
}
const field = line.slice(0, colonIndex);
const valueStart = colonIndex + 1;
const value = valueStart < line.length && line[valueStart] === " " ? line.slice(valueStart + 1) : line.slice(valueStart);
handleField(field, value);
}
function dispatchEvent(controller) {
if (data.length > 0) {
controller.enqueue({
event,
data: data.join("\n"),
id: lastEventId,
retry
});
data = [];
event = void 0;
retry = void 0;
}
}
function handleField(field, value) {
switch (field) {
case "event":
event = value;
break;
case "data":
data.push(value);
break;
case "id":
lastEventId = value;
break;
case "retry":
const parsedRetry = parseInt(value, 10);
if (!isNaN(parsedRetry)) {
retry = parsedRetry;
}
break;
}
}
return new TransformStream({
transform(chunk, controller) {
const { lines, incompleteLine } = splitLines(buffer, chunk);
buffer = incompleteLine;
for (let i = 0; i < lines.length; i++) {
parseLine(lines[i], controller);
}
},
flush(controller) {
parseLine(buffer, controller);
dispatchEvent(controller);
}
});
}
function splitLines(buffer, chunk) {
const lines = [];
let currentLine = buffer;
for (let i = 0; i < chunk.length; ) {
const char = chunk[i++];
if (char === "\n") {
lines.push(currentLine);
currentLine = "";
} else if (char === "\r") {
lines.push(currentLine);
currentLine = "";
if (chunk[i] === "\n") {
i++;
}
} else {
currentLine += char;
}
}
return { lines, incompleteLine: currentLine };
}
function extractResponseHeaders(response) {
const headers = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
return headers;
}
var createIdGenerator = ({
prefix,
size: defaultSize = 16,
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
separator = "-"
} = {}) => {
const generator = customAlphabet(alphabet, defaultSize);
if (prefix == null) {
return generator;
}
if (alphabet.includes(separator)) {
throw new InvalidArgumentError({
argument: "separator",
message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".`
});
}
return (size) => `${prefix}${separator}${generator(size)}`;
};
var generateId = createIdGenerator();
function removeUndefinedEntries(record) {
return Object.fromEntries(
Object.entries(record).filter(([_key, value]) => value != null)
);
}
function isAbortError(error) {
return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
}
function loadApiKey({
apiKey,
environmentVariableName,
apiKeyParameterName = "apiKey",
description
}) {
if (typeof apiKey === "string") {
return apiKey;
}
if (apiKey != null) {
throw new LoadAPIKeyError({
message: `${description} API key must be a string.`
});
}
if (typeof process === "undefined") {
throw new LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
});
}
apiKey = process.env[environmentVariableName];
if (apiKey == null) {
throw new LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
});
}
if (typeof apiKey !== "string") {
throw new LoadAPIKeyError({
message: `${description} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
});
}
return apiKey;
}
var validatorSymbol = Symbol.for("vercel.ai.validator");
function validator(validate) {
return { [validatorSymbol]: true, validate };
}
function isValidator(value) {
return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value;
}
function asValidator(value) {
return isValidator(value) ? value : zodValidator(value);
}
function zodValidator(zodSchema) {
return validator((value) => {
const result = zodSchema.safeParse(value);
return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
});
}
function validateTypes({
value,
schema: inputSchema
}) {
const result = safeValidateTypes({ value, schema: inputSchema });
if (!result.success) {
throw TypeValidationError.wrap({ value, cause: result.error });
}
return result.value;
}
function safeValidateTypes({
value,
schema
}) {
const validator2 = asValidator(schema);
try {
if (validator2.validate == null) {
return { success: true, value };
}
const result = validator2.validate(value);
if (result.success) {
return result;
}
return {
success: false,
error: TypeValidationError.wrap({ value, cause: result.error })
};
} catch (error) {
return {
success: false,
error: TypeValidationError.wrap({ value, cause: error })
};
}
}
function parseJSON({
text,
schema
}) {
try {
const value = import_secure_json_parse.default.parse(text);
if (schema == null) {
return value;
}
return validateTypes({ value, schema });
} catch (error) {
if (JSONParseError.isInstance(error) || TypeValidationError.isInstance(error)) {
throw error;
}
throw new JSONParseError({ text, cause: error });
}
}
function safeParseJSON({
text,
schema
}) {
try {
const value = import_secure_json_parse.default.parse(text);
if (schema == null) {
return { success: true, value, rawValue: value };
}
const validationResult = safeValidateTypes({ value, schema });
return validationResult.success ? { ...validationResult, rawValue: value } : validationResult;
} catch (error) {
return {
success: false,
error: JSONParseError.isInstance(error) ? error : new JSONParseError({ text, cause: error })
};
}
}
function isParsableJson(input) {
try {
import_secure_json_parse.default.parse(input);
return true;
} catch (e) {
return false;
}
}
function parseProviderOptions({
provider,
providerOptions,
schema
}) {
if ((providerOptions == null ? void 0 : providerOptions[provider]) == null) {
return void 0;
}
const parsedProviderOptions = safeValidateTypes({
value: providerOptions[provider],
schema
});
if (!parsedProviderOptions.success) {
throw new InvalidArgumentError({
argument: "providerOptions",
message: `invalid ${provider} provider options`,
cause: parsedProviderOptions.error
});
}
return parsedProviderOptions.value;
}
var getOriginalFetch2 = () => globalThis.fetch;
var postJsonToApi = async ({
url,
headers,
body,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch: fetch2
}) => postToApi({
url,
headers: {
"Content-Type": "application/json",
...headers
},
body: {
content: JSON.stringify(body),
values: body
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch: fetch2
});
var postFormDataToApi = async ({
url,
headers,
formData,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch: fetch2
}) => postToApi({
url,
headers,
body: {
content: formData,
values: Object.fromEntries(formData.entries())
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch: fetch2
});
var postToApi = async ({
url,
headers = {},
body,
successfulResponseHandler,
failedResponseHandler,
abortSignal,
fetch: fetch2 = getOriginalFetch2()
}) => {
try {
const response = await fetch2(url, {
method: "POST",
headers: removeUndefinedEntries(headers),
body: body.content,
signal: abortSignal
});
const responseHeaders = extractResponseHeaders(response);
if (!response.ok) {
let errorInformation;
try {
errorInformation = await failedResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (isAbortError(error) || APICallError.isInstance(error)) {
throw error;
}
throw new APICallError({
message: "Failed to process error response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
throw errorInformation.value;
}
try {
return await successfulResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (error instanceof Error) {
if (isAbortError(error) || APICallError.isInstance(error)) {
throw error;
}
}
throw new APICallError({
message: "Failed to process successful response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
} catch (error) {
if (isAbortError(error)) {
throw error;
}
if (error instanceof TypeError && error.message === "fetch failed") {
const cause = error.cause;
if (cause != null) {
throw new APICallError({
message: `Cannot connect to API: ${cause.message}`,
cause,
url,
requestBodyValues: body.values,
isRetryable: true
// retry when network error
});
}
}
throw error;
}
};
var createJsonErrorResponseHandler = ({
errorSchema,
errorToMessage,
isRetryable
}) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const responseHeaders = extractResponseHeaders(response);
if (responseBody.trim() === "") {
return {
responseHeaders,
value: new APICallError({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
try {
const parsedError = parseJSON({
text: responseBody,
schema: errorSchema
});
return {
responseHeaders,
value: new APICallError({
message: errorToMessage(parsedError),
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
data: parsedError,
isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError)
})
};
} catch (parseError) {
return {
responseHeaders,
value: new APICallError({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
};
var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
const responseHeaders = extractResponseHeaders(response);
if (response.body == null) {
throw new EmptyResponseBodyError({});
}
return {
responseHeaders,
value: response.body.pipeThrough(new TextDecoderStream()).pipeThrough(createEventSourceParserStream()).pipeThrough(
new TransformStream({
transform({ data }, controller) {
if (data === "[DONE]") {
return;
}
controller.enqueue(
safeParseJSON({
text: data,
schema: chunkSchema
})
);
}
})
)
};
};
var createJsonResponseHandler = (responseSchema) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const parsedResult = safeParseJSON({
text: responseBody,
schema: responseSchema
});
const responseHeaders = extractResponseHeaders(response);
if (!parsedResult.success) {
throw new APICallError({
message: "Invalid JSON response",
cause: parsedResult.error,
statusCode: response.status,
responseHeaders,
responseBody,
url,
requestBodyValues
});
}
return {
responseHeaders,
value: parsedResult.value,
rawValue: parsedResult.rawValue
};
};
var createBinaryResponseHandler = () => async ({ response, url, requestBodyValues }) => {
const responseHeaders = extractResponseHeaders(response);
if (!response.body) {
throw new APICallError({
message: "Response body is empty",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0
});
}
try {
const buffer = await response.arrayBuffer();
return {
responseHeaders,
value: new Uint8Array(buffer)
};
} catch (error) {
throw new APICallError({
message: "Failed to read response as array buffer",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0,
cause: error
});
}
};
var { btoa, atob } = globalThis;
function convertBase64ToUint8Array(base64String) {
const base64Url = base64String.replace(/-/g, "+").replace(/_/g, "/");
const latin1string = atob(base64Url);
return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0));
}
function convertUint8ArrayToBase64(array) {
let latin1string = "";
for (let i = 0; i < array.length; i++) {
latin1string += String.fromCodePoint(array[i]);
}
return btoa(latin1string);
}
function withoutTrailingSlash(url) {
return url == null ? void 0 : url.replace(/\/$/, "");
}
function convertToOpenAIChatMessages({
prompt,
useLegacyFunctionCalling = false,
systemMessageMode = "system"
}) {
const messages = [];
const warnings = [];
for (const { role, content } of prompt) {
switch (role) {
case "system": {
switch (systemMessageMode) {
case "system": {
messages.push({ role: "system", content });
break;
}
case "developer": {
messages.push({ role: "developer", content });
break;
}
case "remove": {
warnings.push({
type: "other",
message: "system messages are removed for this model"
});
break;
}
default: {
const _exhaustiveCheck = systemMessageMode;
throw new Error(
`Unsupported system message mode: ${_exhaustiveCheck}`
);
}
}
break;
}
case "user": {
if (content.length === 1 && content[0].type === "text") {
messages.push({ role: "user", content: content[0].text });
break;
}
messages.push({
role: "user",
content: content.map((part, index) => {
var _a15, _b, _c, _d;
switch (part.type) {
case "text": {
return { type: "text", text: part.text };
}
case "image": {
return {
type: "image_url",
image_url: {
url: part.image instanceof URL ? part.image.toString() : `data:${(_a15 = part.mimeType) != null ? _a15 : "image/jpeg"};base64,${convertUint8ArrayToBase64(part.image)}`,
// OpenAI specific extension: image detail
detail: (_c = (_b = part.providerMetadata) == null ? void 0 : _b.openai) == null ? void 0 : _c.imageDetail
}
};
}
case "file": {
if (part.data instanceof URL) {
throw new UnsupportedFunctionalityError({
functionality: "'File content parts with URL data' functionality not supported."
});
}
switch (part.mimeType) {
case "audio/wav": {
return {
type: "input_audio",
input_audio: { data: part.data, format: "wav" }
};
}
case "audio/mp3":
case "audio/mpeg": {
return {
type: "input_audio",
input_audio: { data: part.data, format: "mp3" }
};
}
case "application/pdf": {
return {
type: "file",
file: {
filename: (_d = part.filename) != null ? _d : `part-${index}.pdf`,
file_data: `data:application/pdf;base64,${part.data}`
}
};
}
default: {
throw new UnsupportedFunctionalityError({
functionality: `File content part type ${part.mimeType} in user messages`
});
}
}
}
}
})
});
break;
}
case "assistant": {
let text = "";
const toolCalls = [];
for (const part of content) {
switch (part.type) {
case "text": {
text += part.text;
break;
}
case "tool-call": {
toolCalls.push({
id: part.toolCallId,
type: "function",
function: {
name: part.toolName,
arguments: JSON.stringify(part.args)
}
});
break;
}
}
}
if (useLegacyFunctionCalling) {
if (toolCalls.length > 1) {
throw new UnsupportedFunctionalityError({
functionality: "useLegacyFunctionCalling with multiple tool calls in one message"
});
}
messages.push({
role: "assistant",
content: text,
function_call: toolCalls.length > 0 ? toolCalls[0].function : void 0
});
} else {
messages.push({
role: "assistant",
content: text,
tool_calls: toolCalls.length > 0 ? toolCalls : void 0
});
}
break;
}
case "tool": {
for (const toolResponse of content) {
if (useLegacyFunctionCalling) {
messages.push({
role: "function",
name: toolResponse.toolName,
content: JSON.stringify(toolResponse.result)
});
} else {
messages.push({
role: "tool",
tool_call_id: toolResponse.toolCallId,
content: JSON.stringify(toolResponse.result)
});
}
}
break;
}
default: {
const _exhaustiveCheck = role;
throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
}
}
}
return { messages, warnings };
}
function mapOpenAIChatLogProbsOutput(logprobs) {
var _a15, _b;
return (_b = (_a15 = logprobs == null ? void 0 : logprobs.content) == null ? void 0 : _a15.map(({ token, logprob, top_logprobs }) => ({
token,
logprob,
topLogprobs: top_logprobs ? top_logprobs.map(({ token: token2, logprob: logprob2 }) => ({
token: token2,
logprob: logprob2
})) : []
}))) != null ? _b : void 0;
}
function mapOpenAIFinishReason(finishReason) {
switch (finishReason) {
case "stop":
return "stop";
case "length":
return "length";
case "content_filter":
return "content-filter";
case "function_call":
case "tool_calls":
return "tool-calls";
default:
return "unknown";
}
}
var openaiErrorDataSchema = z.object({
error: z.object({
message: z.string(),
// The additional information below is handled loosely to support
// OpenAI-compatible providers that have slightly different error
// responses:
type: z.string().nullish(),
param: z.any().nullish(),
code: z.union([z.string(), z.number()]).nullish()
})
});
var openaiFailedResponseHandler = createJsonErrorResponseHandler({
errorSchema: openaiErrorDataSchema,
errorToMessage: (data) => data.error.message
});
function getResponseMetadata({
id,
model,
created
}) {
return {
id: id != null ? id : void 0,
modelId: model != null ? model : void 0,
timestamp: created != null ? new Date(created * 1e3) : void 0
};
}
function prepareTools({
mode,
useLegacyFunctionCalling = false,
structuredOutputs
}) {
var _a15;
const tools = ((_a15 = mode.tools) == null ? void 0 : _a15.length) ? mode.tools : void 0;
const toolWarnings = [];
if (tools == null) {
return { tools: void 0, tool_choice: void 0, toolWarnings };
}
const toolChoice = mode.toolChoice;
if (useLegacyFunctionCalling) {
const openaiFunctions = [];
for (const tool of tools) {
if (tool.type === "provider-defined") {
toolWarnings.push({ type: "unsupported-tool", tool });
} else {
openaiFunctions.push({
name: tool.name,
description: tool.description,
parameters: tool.parameters
});
}
}
if (toolChoice == null) {
return {
functions: openaiFunctions,
function_call: void 0,
toolWarnings
};
}
const type2 = toolChoice.type;
switch (type2) {
case "auto":
case "none":
case void 0:
return {
functions: openaiFunctions,
function_call: void 0,
toolWarnings
};
case "required":
throw new UnsupportedFunctionalityError({
functionality: "useLegacyFunctionCalling and toolChoice: required"
});
default:
return {
functions: openaiFunctions,
function_call: { name: toolChoice.toolName },
toolWarnings
};
}
}
const openaiTools2 = [];
for (const tool of tools) {
if (tool.type === "provider-defined") {
toolWarnings.push({ type: "unsupported-tool", tool });
} else {
openaiTools2.push({
type: "function",
function: {
name: tool.name,
description: tool.description,
parameters: tool.parameters,
strict: structuredOutputs ? true : void 0
}
});
}
}
if (toolChoice == null) {
return { tools: openaiTools2, tool_choice: void 0, toolWarnings };
}
const type = toolChoice.type;
switch (type) {
case "auto":
case "none":
case "required":
return { tools: openaiTools2, tool_choice: type, toolWarnings };
case "tool":
return {
tools: openaiTools2,
tool_choice: {
type: "function",
function: {
name: toolChoice.toolName
}
},
toolWarnings
};
default: {
const _exhaustiveCheck = type;
throw new UnsupportedFunctionalityError({
functionality: `Unsupported tool choice type: ${_exhaustiveCheck}`
});
}
}
}
var OpenAIChatLanguageModel = class {
constructor(modelId, settings, config) {
this.specificationVersion = "v1";
this.modelId = modelId;
this.settings = settings;
this.config = config;
}
get supportsStructuredOutputs() {
var _a15;
return (_a15 = this.settings.structuredOutputs) != null ? _a15 : isReasoningModel(this.modelId);
}
get defaultObjectGenerationMode() {
if (isAudioModel(this.modelId)) {
return "tool";
}
return this.supportsStructuredOutputs ? "json" : "tool";
}
get provider() {
return this.config.provider;
}
get supportsImageUrls() {
return !this.settings.downloadImages;
}
getArgs({
mode,
prompt,
maxTokens,
temperature,
topP,
topK,
frequencyPenalty,
presencePenalty,
stopSequences,
responseFormat,
seed,
providerMetadata
}) {
var _a15, _b, _c, _d, _e, _f, _g, _h;
const type = mode.type;
const warnings = [];
if (topK != null) {
warnings.push({
type: "unsupported-setting",
setting: "topK"
});
}
if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !this.supportsStructuredOutputs) {
warnings.push({
type: "unsupported-setting",
setting: "responseFo