UNPKG

@mastra/core

Version:
1 lines 13.5 kB
{"version":3,"file":"index.cjs","names":["DurableAgent","globalRunRegistry","createObservabilityContext"],"sources":["../../../src/agent/durable/workflows/shared/execute-tool-calls.ts","../../../src/agent/durable/evented-agent.ts","../../../src/agent/durable/create-evented-agent.ts"],"sourcesContent":["import type { RequestContext } from '../../../../request-context';\nimport type { Workspace } from '../../../../workspace';\nimport type { DurableToolCallInput, DurableToolCallOutput } from '../../types';\n\n/**\n * Context for tool execution\n */\nexport interface ToolExecutionContext {\n /** Tool calls from the LLM output */\n toolCalls: DurableToolCallInput[];\n /** Resolved tools with execute functions */\n tools: Record<string, any>;\n /** Run identifier */\n runId: string;\n /** Agent identifier */\n agentId: string;\n /** Message identifier */\n messageId: string;\n /** Serializable state */\n state: any;\n /** Workspace for file/sandbox operations */\n workspace?: Workspace;\n /** Request context for auth data, feature flags, etc. */\n requestContext?: RequestContext;\n\n /**\n * Optional hooks for observability/streaming.\n * All hooks can be sync or async.\n */\n\n /** Called before starting tool execution (for span creation) */\n onToolStart?: (toolCall: DurableToolCallInput) => void | Promise<void>;\n /** Called after successful tool execution (for span close, pubsub emit) */\n onToolResult?: (toolCall: DurableToolCallInput, result: unknown) => void | Promise<void>;\n /** Called on tool execution error (for span error, pubsub emit) */\n onToolError?: (toolCall: DurableToolCallInput, error: ToolExecutionError) => void | Promise<void>;\n}\n\n/**\n * Error structure for tool execution failures\n */\nexport interface ToolExecutionError {\n name: string;\n message: string;\n stack?: string;\n}\n\n/**\n * Execute tool calls durably with optional hooks for observability and streaming.\n *\n * This is the shared implementation used by:\n * - Core DurableAgent workflow\n * - Inngest durable agent workflow (with observability hooks)\n * - Evented durable agent workflow\n *\n * @param ctx - Tool execution context with tool calls, resolved tools, and optional hooks\n * @returns Array of tool call outputs with results or errors\n */\nexport async function executeDurableToolCalls(ctx: ToolExecutionContext): Promise<DurableToolCallOutput[]> {\n const toolResults: DurableToolCallOutput[] = [];\n\n for (const toolCall of ctx.toolCalls) {\n // Handle provider-executed tools (e.g., OpenAI function calling with parallel_tool_calls)\n if (toolCall.providerExecuted && toolCall.output !== undefined) {\n toolResults.push({\n ...toolCall,\n result: toolCall.output,\n });\n continue;\n }\n\n // Resolve the tool from the tools record\n const tool = ctx.tools[toolCall.toolName];\n\n if (!tool) {\n const error: ToolExecutionError = {\n name: 'ToolNotFoundError',\n message: `Tool ${toolCall.toolName} not found`,\n };\n await ctx.onToolError?.(toolCall, error);\n toolResults.push({\n ...toolCall,\n error,\n });\n continue;\n }\n\n // Notify start of tool execution (for observability)\n await ctx.onToolStart?.(toolCall);\n\n // Execute the tool\n try {\n if (tool.execute) {\n const result = await tool.execute(toolCall.args, {\n toolCallId: toolCall.toolCallId,\n messages: [],\n workspace: ctx.workspace,\n requestContext: ctx.requestContext,\n });\n await ctx.onToolResult?.(toolCall, result);\n toolResults.push({\n ...toolCall,\n result,\n });\n } else {\n // Tool has no execute function - return undefined result\n await ctx.onToolResult?.(toolCall, undefined);\n toolResults.push({\n ...toolCall,\n result: undefined,\n });\n }\n } catch (error) {\n const toolError: ToolExecutionError = {\n name: 'ToolExecutionError',\n message: error instanceof Error ? error.message : String(error),\n stack: error instanceof Error ? error.stack : undefined,\n };\n await ctx.onToolError?.(toolCall, toolError);\n toolResults.push({\n ...toolCall,\n error: toolError,\n });\n }\n }\n\n return toolResults;\n}\n","/**\n * EventedAgent - A durable agent that uses fire-and-forget execution.\n *\n * EventedAgent extends DurableAgent and overrides the execution strategy to use\n * fire-and-forget execution via the workflow engine's startAsync() method.\n *\n * Unlike DurableAgent which runs the workflow synchronously, EventedAgent:\n * 1. Uses startAsync() for non-blocking execution\n * 2. Fire-and-forget pattern - execution starts and returns immediately\n * 3. Events are streamed via pubsub as the workflow executes\n */\n\nimport { createObservabilityContext } from '../../observability';\nimport type { ToolsInput } from '../types';\n\nimport { DurableAgent } from './durable-agent';\nimport type { DurableAgentConfig } from './durable-agent';\nimport { globalRunRegistry } from './run-registry';\nimport type { DurableAgenticWorkflowInput } from './types';\n\n/**\n * Configuration for EventedAgent - wraps an existing Agent with fire-and-forget execution\n */\nexport interface EventedAgentConfig<\n TAgentId extends string = string,\n TTools extends ToolsInput = ToolsInput,\n TOutput = undefined,\n> extends DurableAgentConfig<TAgentId, TTools, TOutput> {}\n\n/**\n * EventedAgent extends DurableAgent to use fire-and-forget execution.\n *\n * This agent type uses the built-in evented workflow engine, which is useful when:\n * - You don't need an external execution engine (like Inngest)\n * - You want fire-and-forget execution with pubsub streaming\n * - You need resumable streams with event caching\n *\n * The key difference from DurableAgent is the execution strategy:\n * - DurableAgent: Runs the workflow synchronously via createRun + start\n * - EventedAgent: Uses run.startAsync() for fire-and-forget execution\n *\n * @example\n * ```typescript\n * import { Agent } from '@mastra/core/agent';\n * import { EventedAgent } from '@mastra/core/agent/durable';\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * instructions: 'You are a helpful assistant',\n * model: openai('gpt-4'),\n * });\n *\n * const eventedAgent = new EventedAgent({ agent });\n *\n * const { output, runId, cleanup } = await eventedAgent.stream('Hello!');\n * const text = await output.text;\n * cleanup();\n * ```\n */\nexport class EventedAgent<\n TAgentId extends string = string,\n TTools extends ToolsInput = ToolsInput,\n TOutput = undefined,\n> extends DurableAgent<TAgentId, TTools, TOutput> {\n /**\n * Create a new EventedAgent that wraps an existing Agent\n */\n constructor(config: EventedAgentConfig<TAgentId, TTools, TOutput>) {\n super(config);\n }\n\n /**\n * Execute the durable workflow using fire-and-forget pattern.\n *\n * Unlike DurableAgent which runs the workflow synchronously, EventedAgent uses\n * the workflow's startAsync() method for non-blocking execution.\n *\n * @param runId - The unique run ID\n * @param workflowInput - The serialized workflow input\n * @internal\n */\n protected override async executeWorkflow(runId: string, workflowInput: DurableAgenticWorkflowInput): Promise<void> {\n try {\n const workflow = this.getWorkflow();\n const run = await workflow.createRun({\n runId,\n pubsub: this.pubsubInternal,\n });\n // Fire and forget - use startAsync for non-blocking execution.\n // Pass the caller's requestContext (so config selectors pick the same observability\n // instance the root spans were created with) and parent the run under the AGENT_RUN span.\n const entry = globalRunRegistry.get(runId);\n await run.startAsync({\n inputData: workflowInput,\n requestContext: entry?.requestContext,\n actor: workflowInput.options?.actor,\n ...createObservabilityContext({ currentSpan: entry?.agentSpan }),\n });\n } catch (error) {\n await this.emitError(runId, error instanceof Error ? error : new Error(String(error)));\n }\n }\n}\n\n/**\n * Check if an object is an EventedAgent class instance\n */\nexport function isEventedAgentClass(obj: any): obj is EventedAgent {\n return obj instanceof EventedAgent;\n}\n","/**\n * Factory function to create an EventedAgent that wraps an existing Agent.\n *\n * This creates a durable agent that uses fire-and-forget execution via\n * the built-in workflow engine with startAsync().\n *\n * @example\n * ```typescript\n * import { Agent } from '@mastra/core/agent';\n * import { createEventedAgent } from '@mastra/core/agent/durable';\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant',\n * model: openai('gpt-4'),\n * });\n *\n * const eventedAgent = createEventedAgent({ agent });\n *\n * const mastra = new Mastra({\n * agents: { myAgent: eventedAgent },\n * });\n * ```\n */\n\nimport type { MastraServerCache } from '../../cache/base';\nimport type { PubSub } from '../../events/pubsub';\nimport type { Agent } from '../agent';\n\nimport { EventedAgent } from './evented-agent';\nimport type { EventedAgentConfig } from './evented-agent';\n\n/**\n * Options for createEventedAgent factory function.\n */\nexport interface CreateEventedAgentOptions<\n TAgentId extends string = string,\n TTools extends Record<string, any> = Record<string, any>,\n TOutput = undefined,\n> {\n /** The Agent to wrap with evented durable execution capabilities */\n agent: Agent<TAgentId, TTools, TOutput>;\n\n /**\n * PubSub instance for streaming events.\n * Optional - if not provided, defaults to EventEmitterPubSub.\n */\n pubsub?: PubSub;\n\n /**\n * Cache instance for storing stream events.\n * Enables resumable streams - clients can disconnect and reconnect\n * without missing events.\n *\n * - If not provided: Inherits from Mastra instance, or uses InMemoryServerCache\n * - If provided: Uses the provided cache backend (e.g., Redis)\n * - If set to `false`: Disables caching (streams are not resumable)\n */\n cache?: MastraServerCache | false;\n\n /** Maximum steps for agentic loop */\n maxSteps?: number;\n}\n\n/**\n * Create an EventedAgent that wraps an existing Agent.\n *\n * This factory function creates an EventedAgent instance with fire-and-forget\n * execution via the built-in workflow engine.\n *\n * @param options - Configuration options\n * @returns An EventedAgent instance\n *\n * @example\n * ```typescript\n * const agent = new Agent({\n * id: 'my-agent',\n * instructions: 'You are helpful',\n * model: openai('gpt-4'),\n * });\n *\n * const eventedAgent = createEventedAgent({ agent });\n *\n * const mastra = new Mastra({\n * agents: { myAgent: eventedAgent },\n * });\n * ```\n */\nexport function createEventedAgent<\n TAgentId extends string = string,\n TTools extends Record<string, any> = Record<string, any>,\n TOutput = undefined,\n>(options: CreateEventedAgentOptions<TAgentId, TTools, TOutput>): EventedAgent<TAgentId, TTools, TOutput> {\n const { agent, pubsub, cache, maxSteps } = options;\n\n return new EventedAgent({\n agent,\n pubsub,\n cache,\n maxSteps,\n } as EventedAgentConfig<TAgentId, TTools, TOutput>);\n}\n\n/**\n * Check if an object is an EventedAgent\n */\nexport function isEventedAgent(obj: any): obj is EventedAgent {\n return obj instanceof EventedAgent;\n}\n\n// Re-export types for convenience\nexport type { EventedAgentConfig } from './evented-agent';\n"],"mappings":";;;;;;;;;;;;;;;;AA0DA,eAAsB,wBAAwB,KAA6D;CACzG,MAAM,cAAuC,CAAC;CAE9C,KAAK,MAAM,YAAY,IAAI,WAAW;EAEpC,IAAI,SAAS,oBAAoB,SAAS,WAAW,KAAA,GAAW;GAC9D,YAAY,KAAK;IACf,GAAG;IACH,QAAQ,SAAS;GACnB,CAAC;GACD;EACF;EAGA,MAAM,OAAO,IAAI,MAAM,SAAS;EAEhC,IAAI,CAAC,MAAM;GACT,MAAM,QAA4B;IAChC,MAAM;IACN,SAAS,QAAQ,SAAS,SAAS;GACrC;GACA,MAAM,IAAI,cAAc,UAAU,KAAK;GACvC,YAAY,KAAK;IACf,GAAG;IACH;GACF,CAAC;GACD;EACF;EAGA,MAAM,IAAI,cAAc,QAAQ;EAGhC,IAAI;GACF,IAAI,KAAK,SAAS;IAChB,MAAM,SAAS,MAAM,KAAK,QAAQ,SAAS,MAAM;KAC/C,YAAY,SAAS;KACrB,UAAU,CAAC;KACX,WAAW,IAAI;KACf,gBAAgB,IAAI;IACtB,CAAC;IACD,MAAM,IAAI,eAAe,UAAU,MAAM;IACzC,YAAY,KAAK;KACf,GAAG;KACH;IACF,CAAC;GACH,OAAO;IAEL,MAAM,IAAI,eAAe,UAAU,KAAA,CAAS;IAC5C,YAAY,KAAK;KACf,GAAG;KACH,QAAQ,KAAA;IACV,CAAC;GACH;EACF,SAAS,OAAO;GACd,MAAM,YAAgC;IACpC,MAAM;IACN,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;IAC9D,OAAO,iBAAiB,QAAQ,MAAM,QAAQ,KAAA;GAChD;GACA,MAAM,IAAI,cAAc,UAAU,SAAS;GAC3C,YAAY,KAAK;IACf,GAAG;IACH,OAAO;GACT,CAAC;EACH;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpEA,IAAa,eAAb,cAIUA,6BAAAA,aAAwC;;;;CAIhD,YAAY,QAAuD;EACjE,MAAM,MAAM;CACd;;;;;;;;;;;CAYA,MAAyB,gBAAgB,OAAe,eAA2D;EACjH,IAAI;GAEF,MAAM,MAAM,MADK,KAAK,YACG,CAAC,CAAC,UAAU;IACnC;IACA,QAAQ,KAAK;GACf,CAAC;GAID,MAAM,QAAQC,6BAAAA,kBAAkB,IAAI,KAAK;GACzC,MAAM,IAAI,WAAW;IACnB,WAAW;IACX,gBAAgB,OAAO;IACvB,OAAO,cAAc,SAAS;IAC9B,GAAGC,sBAAAA,2BAA2B,EAAE,aAAa,OAAO,UAAU,CAAC;GACjE,CAAC;EACH,SAAS,OAAO;GACd,MAAM,KAAK,UAAU,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC,CAAC;EACvF;CACF;AACF;;;;AAKA,SAAgB,oBAAoB,KAA+B;CACjE,OAAO,eAAe;AACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpBA,SAAgB,mBAId,SAAwG;CACxG,MAAM,EAAE,OAAO,QAAQ,OAAO,aAAa;CAE3C,OAAO,IAAI,aAAa;EACtB;EACA;EACA;EACA;CACF,CAAkD;AACpD;;;;AAKA,SAAgB,eAAe,KAA+B;CAC5D,OAAO,eAAe;AACxB"}