UNPKG

@mastra/rag

Version:

The Retrieval-Augmented Generation (RAG) module contains document processing and embedding utilities.

1,652 lines (1,638 loc) • 274 kB
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