UNPKG

@mastra/core

Version:

The core foundation of the Mastra framework, providing essential components and interfaces for building AI-powered applications.

1,553 lines (1,543 loc) • 143 kB
'use strict'; var chunkZ2M2MAHJ_cjs = require('./chunk-Z2M2MAHJ.cjs'); var chunk6NCAW2KJ_cjs = require('./chunk-6NCAW2KJ.cjs'); var chunkST5RMVLG_cjs = require('./chunk-ST5RMVLG.cjs'); var chunkPK4TS7JL_cjs = require('./chunk-PK4TS7JL.cjs'); var chunkL5FURQXC_cjs = require('./chunk-L5FURQXC.cjs'); var chunkUOKJ7SQO_cjs = require('./chunk-UOKJ7SQO.cjs'); var chunkU3XRKJNN_cjs = require('./chunk-U3XRKJNN.cjs'); var chunkP3Q73CAW_cjs = require('./chunk-P3Q73CAW.cjs'); var chunkZIZ3CVHN_cjs = require('./chunk-ZIZ3CVHN.cjs'); var chunkLABUWBKX_cjs = require('./chunk-LABUWBKX.cjs'); var chunkU64IJDC5_cjs = require('./chunk-U64IJDC5.cjs'); var api = require('@opentelemetry/api'); var zod = require('zod'); var radash = require('radash'); var crypto$1 = require('crypto'); var EventEmitter = require('events'); var sift = require('sift'); var xstate = require('xstate'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter); var sift__default = /*#__PURE__*/_interopDefault(sift); // ../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js var require_fast_deep_equal = chunkU64IJDC5_cjs.__commonJS({ "../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js"(exports, module) { module.exports = function equal(a, b) { if (a === b) return true; if (a && b && typeof a == "object" && typeof b == "object") { if (a.constructor !== b.constructor) return false; var length, i, keys; if (Array.isArray(a)) { length = a.length; if (length != b.length) return false; for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false; return true; } if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags; if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf(); if (a.toString !== Object.prototype.toString) return a.toString() === b.toString(); keys = Object.keys(a); length = keys.length; if (length !== Object.keys(b).length) return false; for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false; for (i = length; i-- !== 0;) { var key = keys[i]; if (!equal(a[key], b[key])) return false; } return true; } return a !== a && b !== b; }; } }); // src/workflows/legacy/step.ts var LegacyStep = class { id; description; inputSchema; outputSchema; payload; execute; retryConfig; mastra; constructor({ id, description, execute, payload, outputSchema, inputSchema, retryConfig }) { this.id = id; this.description = description ?? ""; this.inputSchema = inputSchema; this.payload = payload; this.outputSchema = outputSchema; this.execute = execute; this.retryConfig = retryConfig; } }; // src/workflows/legacy/types.ts var WhenConditionReturnValue = /* @__PURE__ */(WhenConditionReturnValue2 => { WhenConditionReturnValue2["CONTINUE"] = "continue"; WhenConditionReturnValue2["CONTINUE_FAILED"] = "continue_failed"; WhenConditionReturnValue2["ABORT"] = "abort"; WhenConditionReturnValue2["LIMBO"] = "limbo"; return WhenConditionReturnValue2; })(WhenConditionReturnValue || {}); // src/agent/index.ts var import_fast_deep_equal = chunkU64IJDC5_cjs.__toESM(require_fast_deep_equal(), 1); function resolveMaybePromise(value, cb) { if (value instanceof Promise) { return value.then(cb); } return cb(value); } function resolveThreadIdFromArgs(args) { if (args?.memory?.thread) { if (typeof args.memory.thread === "string") return { id: args.memory.thread }; if (typeof args.memory.thread === "object" && args.memory.thread.id) return args.memory.thread; } if (args?.threadId) return { id: args.threadId }; return void 0; } var _Agent_decorators, _init, _a; _Agent_decorators = [chunkL5FURQXC_cjs.InstrumentClass({ prefix: "agent", excludeMethods: ["hasOwnMemory", "getMemory", "__primitive", "__registerMastra", "__registerPrimitives", "__setTools", "__setLogger", "__setTelemetry", "log", "getModel", "getInstructions", "getTools", "getLLM", "getWorkflows", "getDefaultGenerateOptions", "getDefaultStreamOptions", "getDescription"] })]; exports.Agent = class Agent extends (_a = chunkP3Q73CAW_cjs.MastraBase) { id; name; #instructions; #description; model; #mastra; #memory; #workflows; #defaultGenerateOptions; #defaultStreamOptions; #tools; /** @deprecated This property is deprecated. Use evals instead. */ metrics; evals; #voice; constructor(config) { super({ component: chunkZIZ3CVHN_cjs.RegisteredLogger.AGENT }); this.name = config.name; this.id = config.name; this.#instructions = config.instructions; this.#description = config.description; if (!config.model) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_CONSTRUCTOR_MODEL_REQUIRED", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: config.name }, text: `LanguageModel is required to create an Agent. Please provide the 'model'.` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } this.model = config.model; if (config.workflows) { this.#workflows = config.workflows; } this.#defaultGenerateOptions = config.defaultGenerateOptions || {}; this.#defaultStreamOptions = config.defaultStreamOptions || {}; this.#tools = config.tools || {}; this.metrics = {}; this.evals = {}; if (config.mastra) { this.__registerMastra(config.mastra); this.__registerPrimitives({ telemetry: config.mastra.getTelemetry(), logger: config.mastra.getLogger() }); } if (config.metrics) { this.logger.warn("The metrics property is deprecated. Please use evals instead to add evaluation metrics."); this.metrics = config.metrics; this.evals = config.metrics; } if (config.evals) { this.evals = config.evals; } if (config.memory) { this.#memory = config.memory; } if (config.voice) { this.#voice = config.voice; if (typeof config.tools !== "function") { this.#voice?.addTools(this.tools); } if (typeof config.instructions === "string") { this.#voice?.addInstructions(config.instructions); } } else { this.#voice = new chunkZ2M2MAHJ_cjs.DefaultVoice(); } } hasOwnMemory() { return Boolean(this.#memory); } getMemory() { const memory = this.#memory; if (memory && !memory.hasOwnStorage && this.#mastra) { const storage = this.#mastra.getStorage(); if (storage) { memory.setStorage(storage); } } return memory; } get voice() { if (typeof this.#instructions === "function") { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_VOICE_INCOMPATIBLE_WITH_FUNCTION_INSTRUCTIONS", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: "Voice is not compatible when instructions are a function. Please use getVoice() instead." }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return this.#voice; } async getWorkflows({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { let workflowRecord; if (typeof this.#workflows === "function") { workflowRecord = await Promise.resolve(this.#workflows({ runtimeContext })); } else { workflowRecord = this.#workflows ?? {}; } Object.entries(workflowRecord || {}).forEach(([_workflowName, workflow]) => { if (this.#mastra) { workflow.__registerMastra(this.#mastra); } }); return workflowRecord; } async getVoice({ runtimeContext } = {}) { if (this.#voice) { const voice = this.#voice; voice?.addTools(await this.getTools({ runtimeContext })); voice?.addInstructions(await this.getInstructions({ runtimeContext })); return voice; } else { return new chunkZ2M2MAHJ_cjs.DefaultVoice(); } } get instructions() { this.logger.warn("The instructions property is deprecated. Please use getInstructions() instead."); if (typeof this.#instructions === "function") { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_INSTRUCTIONS_INCOMPATIBLE_WITH_FUNCTION_INSTRUCTIONS", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: "Instructions are not compatible when instructions are a function. Please use getInstructions() instead." }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return this.#instructions; } getInstructions({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { if (typeof this.#instructions === "string") { return this.#instructions; } const result = this.#instructions({ runtimeContext }); return resolveMaybePromise(result, instructions => { if (!instructions) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_INSTRUCTIONS_FUNCTION_EMPTY_RETURN", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: "Instructions are required to use an Agent. The function-based instructions returned an empty value." }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return instructions; }); } getDescription() { return this.#description ?? ""; } getDefaultGenerateOptions({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { if (typeof this.#defaultGenerateOptions !== "function") { return this.#defaultGenerateOptions; } const result = this.#defaultGenerateOptions({ runtimeContext }); return resolveMaybePromise(result, options => { if (!options) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_DEFAULT_GENERATE_OPTIONS_FUNCTION_EMPTY_RETURN", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: `[Agent:${this.name}] - Function-based default generate options returned empty value` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return options; }); } getDefaultStreamOptions({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { if (typeof this.#defaultStreamOptions !== "function") { return this.#defaultStreamOptions; } const result = this.#defaultStreamOptions({ runtimeContext }); return resolveMaybePromise(result, options => { if (!options) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_DEFAULT_STREAM_OPTIONS_FUNCTION_EMPTY_RETURN", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: `[Agent:${this.name}] - Function-based default stream options returned empty value` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return options; }); } get tools() { this.logger.warn("The tools property is deprecated. Please use getTools() instead."); if (typeof this.#tools === "function") { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_TOOLS_FUNCTION_INCOMPATIBLE_WITH_TOOL_FUNCTION_TYPE", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: "Tools are not compatible when tools are a function. Please use getTools() instead." }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return chunkUOKJ7SQO_cjs.ensureToolProperties(this.#tools); } getTools({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { if (typeof this.#tools !== "function") { return chunkUOKJ7SQO_cjs.ensureToolProperties(this.#tools); } const result = this.#tools({ runtimeContext }); return resolveMaybePromise(result, tools => { if (!tools) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_TOOLS_FUNCTION_EMPTY_RETURN", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: `[Agent:${this.name}] - Function-based tools returned empty value` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return chunkUOKJ7SQO_cjs.ensureToolProperties(tools); }); } get llm() { this.logger.warn("The llm property is deprecated. Please use getLLM() instead."); if (typeof this.model === "function") { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_LLM_GETTER_INCOMPATIBLE_WITH_FUNCTION_MODEL", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: "LLM is not compatible when model is a function. Please use getLLM() instead." }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return this.getLLM(); } /** * Gets or creates an LLM instance based on the current model * @param options Options for getting the LLM * @returns A promise that resolves to the LLM instance */ getLLM({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { const model = this.getModel({ runtimeContext }); return resolveMaybePromise(model, model2 => { const llm = new chunkPK4TS7JL_cjs.MastraLLM({ model: model2, mastra: this.#mastra }); if (this.#primitives) { llm.__registerPrimitives(this.#primitives); } if (this.#mastra) { llm.__registerMastra(this.#mastra); } return llm; }); } /** * Gets the model, resolving it if it's a function * @param options Options for getting the model * @returns A promise that resolves to the model */ getModel({ runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() } = {}) { if (typeof this.model !== "function") { if (!this.model) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_MODEL_MISSING_MODEL_INSTANCE", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: `[Agent:${this.name}] - No model provided` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return this.model; } const result = this.model({ runtimeContext }); return resolveMaybePromise(result, model => { if (!model) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_GET_MODEL_FUNCTION_EMPTY_RETURN", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name }, text: `[Agent:${this.name}] - Function-based model returned empty value` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } return model; }); } __updateInstructions(newInstructions) { this.#instructions = newInstructions; this.logger.debug(`[Agents:${this.name}] Instructions updated.`, { model: this.model, name: this.name }); } #primitives; __registerPrimitives(p) { if (p.telemetry) { this.__setTelemetry(p.telemetry); } if (p.logger) { this.__setLogger(p.logger); } this.#primitives = p; this.logger.debug(`[Agents:${this.name}] initialized.`, { model: this.model, name: this.name }); } __registerMastra(mastra) { this.#mastra = mastra; } /** * Set the concrete tools for the agent * @param tools */ __setTools(tools) { this.#tools = tools; this.logger.debug(`[Agents:${this.name}] Tools set for agent ${this.name}`, { model: this.model, name: this.name }); } async generateTitleFromUserMessage({ message, runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext() }) { const llm = await this.getLLM({ runtimeContext }); const normMessage = new chunk6NCAW2KJ_cjs.MessageList().add(message, "user").get.all.ui().at(-1); if (!normMessage) { throw new Error(`Could not generate title from input ${JSON.stringify(message)}`); } const partsToGen = []; for (const part of normMessage.parts) { if (part.type === `text`) { partsToGen.push(part); } else if (part.type === `source`) { partsToGen.push({ type: "text", text: `User added URL: ${part.source.url.substring(0, 100)}` }); } else if (part.type === `file`) { partsToGen.push({ type: "text", text: `User added ${part.mimeType} file: ${part.data.substring(0, 100)}` }); } } const { text } = await llm.__text({ runtimeContext, messages: [{ role: "system", content: ` - you will generate a short title based on the first message a user begins a conversation with - ensure it is not more than 80 characters long - the title should be a summary of the user's message - do not use quotes or colons - the entire text you return will be used as the title` }, { role: "user", content: JSON.stringify(partsToGen) }] }); const cleanedText = text.replace(/<think>[\s\S]*?<\/think>/g, "").trim(); return cleanedText; } getMostRecentUserMessage(messages) { const userMessages = messages.filter(message => message.role === "user"); return userMessages.at(-1); } async genTitle(userMessage, runtimeContext) { let title = `New Thread ${(/* @__PURE__ */new Date()).toISOString()}`; try { if (userMessage) { const normMessage = new chunk6NCAW2KJ_cjs.MessageList().add(userMessage, "user").get.all.ui().at(-1); if (normMessage) { title = await this.generateTitleFromUserMessage({ message: normMessage, runtimeContext }); } } } catch (e) { this.logger.error("Error generating title:", e); } return title; } /* @deprecated use agent.getMemory() and query memory directly */ async fetchMemory({ threadId, thread: passedThread, memoryConfig, resourceId, runId, userMessages, systemMessage, messageList = new chunk6NCAW2KJ_cjs.MessageList({ threadId, resourceId }) }) { const memory = this.getMemory(); if (memory) { const thread = passedThread ?? (await memory.getThreadById({ threadId })); if (!thread) { return { threadId: threadId || "", messages: userMessages || [] }; } if (userMessages && userMessages.length > 0) { messageList.add(userMessages, "memory"); } if (systemMessage?.role === "system") { messageList.addSystem(systemMessage, "memory"); } const [memoryMessages, memorySystemMessage] = threadId && memory ? await Promise.all([memory.rememberMessages({ threadId, resourceId, config: memoryConfig, vectorMessageSearch: messageList.getLatestUserContent() || "" }).then(r => r.messagesV2), memory.getSystemMessage({ threadId, memoryConfig })]) : [[], null]; this.logger.debug("Fetched messages from memory", { threadId, runId, fetchedCount: memoryMessages.length }); if (memorySystemMessage) { messageList.addSystem(memorySystemMessage, "memory"); } messageList.add(memoryMessages, "memory"); const systemMessages = messageList.getSystemMessages()?.map(m => m.content)?.join(` `) ?? void 0; const newMessages = messageList.get.input.v1(); const processedMemoryMessages = memory.processMessages({ // these will be processed messages: messageList.get.remembered.v1(), // these are here for inspecting but shouldn't be returned by the processor // - ex TokenLimiter needs to measure all tokens even though it's only processing remembered messages newMessages, systemMessage: systemMessages, memorySystemMessage: memorySystemMessage || void 0 }); const returnList = new chunk6NCAW2KJ_cjs.MessageList().addSystem(systemMessages).add(processedMemoryMessages, "memory").add(newMessages, "user"); return { threadId: thread.id, messages: returnList.get.all.prompt() }; } return { threadId: threadId || "", messages: userMessages || [] }; } async getMemoryTools({ runId, resourceId, threadId, runtimeContext, mastraProxy }) { let convertedMemoryTools = {}; const memory = this.getMemory(); const memoryTools = memory?.getTools?.(); if (memoryTools) { const memoryToolEntries = await Promise.all(Object.entries(memoryTools).map(async ([k, tool]) => { return [k, { description: tool.description, parameters: tool.parameters, execute: typeof tool?.execute === "function" ? async (args, options) => { try { this.logger.debug(`[Agent:${this.name}] - Executing memory tool ${k}`, { name: k, description: tool.description, args, runId, threadId, resourceId }); return tool?.execute?.({ context: args, mastra: mastraProxy, memory, runId, threadId, resourceId, logger: this.logger, agentName: this.name, runtimeContext }, options) ?? void 0; } catch (err) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_MEMORY_TOOL_EXECUTION_FAILED", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name, runId: runId || "", threadId: threadId || "", resourceId: resourceId || "" }, text: `[Agent:${this.name}] - Failed memory tool execution` }, err); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } } : void 0 }]; })); convertedMemoryTools = Object.fromEntries(memoryToolEntries.filter(entry => Boolean(entry))); } return convertedMemoryTools; } async getAssignedTools({ runtimeContext, runId, resourceId, threadId, mastraProxy }) { let toolsForRequest = {}; this.logger.debug(`[Agents:${this.name}] - Assembling assigned tools`, { runId, threadId, resourceId }); const memory = this.getMemory(); const assignedTools = await this.getTools({ runtimeContext }); const assignedToolEntries = Object.entries(assignedTools || {}); const assignedCoreToolEntries = await Promise.all(assignedToolEntries.map(async ([k, tool]) => { if (!tool) { return; } const options = { name: k, runId, threadId, resourceId, logger: this.logger, mastra: mastraProxy, memory, agentName: this.name, runtimeContext, model: typeof this.model === "function" ? await this.getModel({ runtimeContext }) : this.model }; return [k, chunkUOKJ7SQO_cjs.makeCoreTool(tool, options)]; })); const assignedToolEntriesConverted = Object.fromEntries(assignedCoreToolEntries.filter(entry => Boolean(entry))); toolsForRequest = { ...assignedToolEntriesConverted }; return toolsForRequest; } async getToolsets({ runId, threadId, resourceId, toolsets, runtimeContext, mastraProxy }) { let toolsForRequest = {}; const memory = this.getMemory(); const toolsFromToolsets = Object.values(toolsets || {}); if (toolsFromToolsets.length > 0) { this.logger.debug(`[Agent:${this.name}] - Adding tools from toolsets ${Object.keys(toolsets || {}).join(", ")}`, { runId }); for (const toolset of toolsFromToolsets) { for (const [toolName, tool] of Object.entries(toolset)) { const toolObj = tool; const options = { name: toolName, runId, threadId, resourceId, logger: this.logger, mastra: mastraProxy, memory, agentName: this.name, runtimeContext, model: typeof this.model === "function" ? await this.getModel({ runtimeContext }) : this.model }; const convertedToCoreTool = chunkUOKJ7SQO_cjs.makeCoreTool(toolObj, options, "toolset"); toolsForRequest[toolName] = convertedToCoreTool; } } } return toolsForRequest; } async getClientTools({ runId, threadId, resourceId, runtimeContext, mastraProxy, clientTools }) { let toolsForRequest = {}; const memory = this.getMemory(); const clientToolsForInput = Object.entries(clientTools || {}); if (clientToolsForInput.length > 0) { this.logger.debug(`[Agent:${this.name}] - Adding client tools ${Object.keys(clientTools || {}).join(", ")}`, { runId }); for (const [toolName, tool] of clientToolsForInput) { const { execute, ...rest } = tool; const options = { name: toolName, runId, threadId, resourceId, logger: this.logger, mastra: mastraProxy, memory, agentName: this.name, runtimeContext, model: typeof this.model === "function" ? await this.getModel({ runtimeContext }) : this.model }; const convertedToCoreTool = chunkUOKJ7SQO_cjs.makeCoreTool(rest, options, "client-tool"); toolsForRequest[toolName] = convertedToCoreTool; } } return toolsForRequest; } async getWorkflowTools({ runId, threadId, resourceId, runtimeContext }) { let convertedWorkflowTools = {}; const workflows = await this.getWorkflows({ runtimeContext }); if (Object.keys(workflows).length > 0) { convertedWorkflowTools = Object.entries(workflows).reduce((memo, [workflowName, workflow]) => { memo[workflowName] = { description: workflow.description || `Workflow: ${workflowName}`, parameters: workflow.inputSchema || { type: "object", properties: {} }, execute: async args => { try { this.logger.debug(`[Agent:${this.name}] - Executing workflow as tool ${workflowName}`, { name: workflowName, description: workflow.description, args, runId, threadId, resourceId }); const run = workflow.createRun(); const result = await run.start({ inputData: args, runtimeContext }); return result; } catch (err) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_WORKFLOW_TOOL_EXECUTION_FAILED", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name, runId: runId || "", threadId: threadId || "", resourceId: resourceId || "" }, text: `[Agent:${this.name}] - Failed workflow tool execution` }, err); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } } }; return memo; }, {}); } return convertedWorkflowTools; } async convertTools({ toolsets, clientTools, threadId, resourceId, runId, runtimeContext }) { let mastraProxy = void 0; const logger = this.logger; if (this.#mastra) { mastraProxy = chunkUOKJ7SQO_cjs.createMastraProxy({ mastra: this.#mastra, logger }); } const assignedTools = await this.getAssignedTools({ runId, resourceId, threadId, runtimeContext, mastraProxy }); const memoryTools = await this.getMemoryTools({ runId, resourceId, threadId, runtimeContext, mastraProxy }); const toolsetTools = await this.getToolsets({ runId, resourceId, threadId, runtimeContext, mastraProxy, toolsets }); const clientsideTools = await this.getClientTools({ runId, resourceId, threadId, runtimeContext, mastraProxy, clientTools }); const workflowTools = await this.getWorkflowTools({ runId, resourceId, threadId, runtimeContext }); return { ...assignedTools, ...memoryTools, ...toolsetTools, ...clientsideTools, ...workflowTools }; } __primitive({ instructions, messages, context, thread, memoryConfig, resourceId, runId, toolsets, clientTools, runtimeContext, generateMessageId }) { return { before: async () => { if (process.env.NODE_ENV !== "test") { this.logger.debug(`[Agents:${this.name}] - Starting generation`, { runId }); } const memory = this.getMemory(); const toolEnhancements = [ // toolsets toolsets && Object.keys(toolsets || {}).length > 0 ? `toolsets present (${Object.keys(toolsets || {}).length} tools)` : void 0, // memory tools memory && resourceId ? "memory and resourceId available" : void 0].filter(Boolean).join(", "); this.logger.debug(`[Agent:${this.name}] - Enhancing tools: ${toolEnhancements}`, { runId, toolsets: toolsets ? Object.keys(toolsets) : void 0, clientTools: clientTools ? Object.keys(clientTools) : void 0, hasMemory: !!this.getMemory(), hasResourceId: !!resourceId }); const threadId = thread?.id; const convertedTools = await this.convertTools({ toolsets, clientTools, threadId, resourceId, runId, runtimeContext }); const messageList = new chunk6NCAW2KJ_cjs.MessageList({ threadId, resourceId, generateMessageId }).addSystem({ role: "system", content: instructions || `${this.instructions}.` }).add(context || [], "context"); if (!memory || !threadId && !resourceId) { messageList.add(messages, "user"); return { messageObjects: messageList.get.all.prompt(), convertedTools, messageList }; } if (!threadId || !resourceId) { const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_MEMORY_MISSING_RESOURCE_ID", domain: "AGENT" /* AGENT */, category: "USER" /* USER */, details: { agentName: this.name, threadId: threadId || "", resourceId: resourceId || "" }, text: `A resourceId must be provided when passing a threadId and using Memory. Saw threadId ${threadId} but resourceId is ${resourceId}` }); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } const store = memory.constructor.name; this.logger.debug(`[Agent:${this.name}] - Memory persistence enabled: store=${store}, resourceId=${resourceId}`, { runId, resourceId, threadId, memoryStore: store }); let threadObject = void 0; const existingThread = await memory.getThreadById({ threadId }); if (existingThread) { if (!existingThread.metadata && thread.metadata || thread.metadata && !(0, import_fast_deep_equal.default)(existingThread.metadata, thread.metadata)) { threadObject = await memory.saveThread({ thread: { ...existingThread, metadata: thread.metadata }, memoryConfig }); } else { threadObject = existingThread; } } else { threadObject = await memory.createThread({ threadId, metadata: thread.metadata, title: thread.title, memoryConfig, resourceId }); } let [memoryMessages, memorySystemMessage, userContextMessage] = thread.id && memory ? await Promise.all([memory.rememberMessages({ threadId: threadObject.id, resourceId, config: memoryConfig, // The new user messages aren't in the list yet cause we add memory messages first to try to make sure ordering is correct (memory comes before new user messages) vectorMessageSearch: new chunk6NCAW2KJ_cjs.MessageList().add(messages, `user`).getLatestUserContent() || "" }).then(r => r.messagesV2), memory.getSystemMessage({ threadId: threadObject.id, memoryConfig }), memory.getUserContextMessage({ threadId: threadObject.id })]) : [[], null, null]; this.logger.debug("Fetched messages from memory", { threadId: threadObject.id, runId, fetchedCount: memoryMessages.length }); const resultsFromOtherThreads = memoryMessages.filter(m => m.threadId !== threadObject.id); if (resultsFromOtherThreads.length && !memorySystemMessage) { memorySystemMessage = ``; } if (resultsFromOtherThreads.length) { memorySystemMessage += ` The following messages were remembered from a different conversation: <remembered_from_other_conversation> ${JSON.stringify( // get v1 since they're closer to CoreMessages (which get sent to the LLM) but also include timestamps new chunk6NCAW2KJ_cjs.MessageList().add(resultsFromOtherThreads, "memory").get.all.v1())} <end_remembered_from_other_conversation>`; } if (memorySystemMessage) { messageList.addSystem(memorySystemMessage, "memory"); } if (userContextMessage) { messageList.add(userContextMessage, "context"); } messageList.add(memoryMessages.filter(m => m.threadId === threadObject.id), // filter out messages from other threads. those are added to system message above "memory").add(messages, "user"); const systemMessage = messageList.getSystemMessages()?.map(m => m.content)?.join(` `) ?? void 0; const processedMemoryMessages = memory.processMessages({ // these will be processed messages: messageList.get.remembered.v1(), // these are here for inspecting but shouldn't be returned by the processor // - ex TokenLimiter needs to measure all tokens even though it's only processing remembered messages newMessages: messageList.get.input.v1(), systemMessage, memorySystemMessage: memorySystemMessage || void 0 }); const processedList = new chunk6NCAW2KJ_cjs.MessageList({ threadId: threadObject.id, resourceId }).addSystem(instructions || `${this.instructions}.`).addSystem(memorySystemMessage).add(context || [], "context").add(userContextMessage || [], "context").add(processedMemoryMessages, "memory").add(messageList.get.input.v2(), "user").get.all.prompt(); return { convertedTools, thread: threadObject, messageList, // add old processed messages + new input messages messageObjects: processedList }; }, after: async ({ result, thread: threadAfter, threadId, memoryConfig: memoryConfig2, outputText, runId: runId2, messageList }) => { const resToLog = { text: result?.text, object: result?.object, toolResults: result?.toolResults, toolCalls: result?.toolCalls, usage: result?.usage, steps: result?.steps?.map(s => { return { stepType: s?.stepType, text: result?.text, object: result?.object, toolResults: result?.toolResults, toolCalls: result?.toolCalls, usage: result?.usage }; }) }; this.logger.debug(`[Agent:${this.name}] - Post processing LLM response`, { runId: runId2, result: resToLog, threadId }); const memory = this.getMemory(); const thread2 = threadAfter || (threadId ? await memory?.getThreadById({ threadId }) : void 0); if (memory && resourceId && thread2) { try { let responseMessages = result.response.messages; if (!responseMessages && result.object) { responseMessages = [{ role: "assistant", content: [{ type: "text", text: outputText // outputText contains the stringified object }] }]; } if (responseMessages) { messageList.add(responseMessages, "response"); } void (async () => { if (!thread2.title?.startsWith("New Thread")) { return; } const config = memory.getMergedThreadConfig(memoryConfig2); const userMessage = this.getMostRecentUserMessage(messageList.get.all.ui()); const title = config?.threads?.generateTitle && userMessage ? await this.genTitle(userMessage, runtimeContext) : void 0; if (!title) { return; } return memory.createThread({ threadId: thread2.id, resourceId, memoryConfig: memoryConfig2, title, metadata: thread2.metadata }); })(); await memory.saveMessages({ messages: messageList.drainUnsavedMessages(), memoryConfig: memoryConfig2 }); } catch (e) { if (e instanceof chunkU3XRKJNN_cjs.MastraError) { throw e; } const mastraError = new chunkU3XRKJNN_cjs.MastraError({ id: "AGENT_MEMORY_PERSIST_RESPONSE_MESSAGES_FAILED", domain: "AGENT" /* AGENT */, category: "SYSTEM" /* SYSTEM */, details: { agentName: this.name, runId: runId2 || "", threadId: threadId || "", result: JSON.stringify(resToLog) } }, e); this.logger.trackException(mastraError); this.logger.error(mastraError.toString()); throw mastraError; } } if (Object.keys(this.evals || {}).length > 0) { const userInputMessages = messageList.get.all.ui().filter(m => m.role === "user"); const input = userInputMessages.map(message => typeof message.content === "string" ? message.content : "").join("\n"); const runIdToUse = runId2 || crypto.randomUUID(); for (const metric of Object.values(this.evals || {})) { chunkST5RMVLG_cjs.executeHook("onGeneration" /* ON_GENERATION */, { input, output: outputText, runId: runIdToUse, metric, agentName: this.name, instructions: instructions || this.instructions }); } } } }; } async generate(messages, generateOptions = {}) { const defaultGenerateOptions = await this.getDefaultGenerateOptions({ runtimeContext: generateOptions.runtimeContext }); const { context, memoryOptions: memoryConfigFromArgs, resourceId: resourceIdFromArgs, maxSteps, onStepFinish, output, toolsets, clientTools, temperature, toolChoice = "auto", experimental_output, telemetry, runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext(), ...args } = Object.assign({}, defaultGenerateOptions, generateOptions); const generateMessageId = `experimental_generateMessageId` in args && typeof args.experimental_generateMessageId === `function` ? args.experimental_generateMessageId : void 0; const threadFromArgs = resolveThreadIdFromArgs({ ...args, ...generateOptions }); const resourceId = args.memory?.resource || resourceIdFromArgs; const memoryConfig = args.memory?.options || memoryConfigFromArgs; const runId = args.runId || crypto$1.randomUUID(); const instructions = args.instructions || (await this.getInstructions({ runtimeContext })); const llm = await this.getLLM({ runtimeContext }); const { before, after } = this.__primitive({ messages, instructions, context, thread: threadFromArgs, memoryConfig, resourceId, runId, toolsets, clientTools, runtimeContext, generateMessageId }); const { thread, messageObjects, convertedTools, messageList } = await before(); const threadId = thread?.id; if (!output && experimental_output) { const result2 = await llm.__text({ messages: messageObjects, tools: convertedTools, onStepFinish: result3 => { return onStepFinish?.(result3); }, maxSteps, runId, temperature, toolChoice: toolChoice || "auto", experimental_output, threadId, resourceId, memory: this.getMemory(), runtimeContext, ...args }); const outputText2 = result2.text; await after({ result: result2, threadId, thread, memoryConfig, outputText: outputText2, runId, messageList }); const newResult = result2; newResult.object = result2.experimental_output; return newResult; } if (!output) { const result2 = await llm.__text({ messages: messageObjects, tools: convertedTools, onStepFinish: result3 => { return onStepFinish?.(result3); }, maxSteps, runId, temperature, toolChoice, telemetry, threadId, resourceId, memory: this.getMemory(), runtimeContext, ...args }); const outputText2 = result2.text; await after({ result: result2, thread, threadId, memoryConfig, outputText: outputText2, runId, messageList }); return result2; } const result = await llm.__textObject({ messages: messageObjects, tools: convertedTools, structuredOutput: output, onStepFinish: result2 => { return onStepFinish?.(result2); }, maxSteps, runId, temperature, toolChoice, telemetry, memory: this.getMemory(), runtimeContext, ...args }); const outputText = JSON.stringify(result.object); await after({ result, thread, threadId, memoryConfig, outputText, runId, messageList }); return result; } async stream(messages, streamOptions = {}) { const defaultStreamOptions = await this.getDefaultStreamOptions({ runtimeContext: streamOptions.runtimeContext }); const { context, memoryOptions: memoryConfigFromArgs, resourceId: resourceIdFromArgs, maxSteps, onFinish, onStepFinish, toolsets, clientTools, output, temperature, toolChoice = "auto", experimental_output, telemetry, runtimeContext = new chunkLABUWBKX_cjs.RuntimeContext(), ...args } = Object.assign({}, defaultStreamOptions, streamOptions); const generateMessageId = `experimental_generateMessageId` in args && typeof args.experimental_generateMessageId === `function` ? args.experimental_generateMessageId : void 0; const threadFromArgs = resolveThreadIdFromArgs({ ...args, ...streamOptions }); const resourceId = args.memory?.resource || resourceIdFromArgs; const memoryConfig = args.memory?.options || memoryConfigFromArgs; const runId = args.runId || crypto$1.randomUUID(); const instructions = args.instructions || (await this.getInstructions({ runtimeContext })); const llm = await this.getLLM({ runtimeContext }); const { before, after } = this.__primitive({ instructions, messages, context, thread: threadFromArgs, memoryConfig, resourceId, runId, toolsets, clientTools, runtimeContext, generateMessageId }); const { thread, messageObjects, convertedTools, messageList } = await before(); const threadId = thread?.id; if (!output && experimental_output) { this.logger.debug(`Starting agent ${this.name} llm stream call`, { runId }); const streamResult = await llm.__stream({ messages: messageObjects, temperature, tools: convertedTools, onStepFinish: result => { return onStepFinish?.(result); }, onFinish: async result => { try { const outputText = result.text; await after({ result, thread, threadId, memoryConfig, outputText, runId, messageList }); } catch (e) { this.logger.error("Error saving memory on finish", { error: e, runId }); } await onFinish?.(result); }, maxSteps, runId, toolChoice, experimental_output, telemetry, memory: this.getMemory(), runtimeContext, threadId: thread?.id, resourceId, ...args }); const newStreamResult = streamResult; newStreamResult.partialObjectStream = streamResult.experimental_partialOutputStream; return newStreamResult; } else if (!output) { this.logger.debug(`Starting agent ${this.name} llm stream call`, { runId }); return llm.__stream({ messages: messageObjects, temperature, tools: convertedTools, onStepFinish: result => { return onStepFinish?.(result); }, onFinish: async result => { try { const outputText = result.text; await after({ result, thread, threadId, memoryConfig, outputText, runId, messageList }); } catch (e) { this.logger.error("Error saving memory on finish", { error: e, runId }); } await onFinish?.(result); }, maxSteps, runId, toolChoice, telemetry, memory: this.getMemory(), runtimeContext, threadId: thread?.id, resourceId, ...args }); } this.logger.debug(`Starting agent ${this.name} llm streamObject call`, { runId }); return llm.__streamObject({ messages: messageObjects,