UNPKG

mastra-browser-core

Version:

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

1,368 lines (1,365 loc) 85.5 kB
import { createMastraProxy } from './chunk-HXRGB7YQ.js'; import { MastraBase } from './chunk-LE72NI7K.js'; import { __name, __publicField, __privateAdd, __privateSet, __privateGet, __privateMethod } from './chunk-WH5OY6PO.js'; import { context, trace } from '@opentelemetry/api'; import { z } from 'zod'; import { get } from 'radash'; import EventEmitter from 'events'; import sift from 'sift'; import { createActor, setup, assign, fromPromise } from 'xstate'; // src/workflows/step.ts var _Step = class _Step { constructor({ id, description, execute, payload, outputSchema, inputSchema, retryConfig }) { __publicField(this, "id"); __publicField(this, "description"); __publicField(this, "inputSchema"); __publicField(this, "outputSchema"); __publicField(this, "payload"); __publicField(this, "execute"); __publicField(this, "retryConfig"); __publicField(this, "mastra"); this.id = id; this.description = description ?? ""; this.inputSchema = inputSchema; this.payload = payload; this.outputSchema = outputSchema; this.execute = execute; this.retryConfig = retryConfig; } }; __name(_Step, "Step"); var Step = _Step; function createStep(opts) { return new Step(opts); } __name(createStep, "createStep"); // src/workflows/types.ts var WhenConditionReturnValue = /* @__PURE__ */ ((WhenConditionReturnValue2) => { WhenConditionReturnValue2["CONTINUE"] = "continue"; WhenConditionReturnValue2["CONTINUE_FAILED"] = "continue_failed"; WhenConditionReturnValue2["ABORT"] = "abort"; WhenConditionReturnValue2["LIMBO"] = "limbo"; return WhenConditionReturnValue2; })(WhenConditionReturnValue || {}); function isErrorEvent(stateEvent) { return stateEvent.type.startsWith("xstate.error.actor."); } __name(isErrorEvent, "isErrorEvent"); function isTransitionEvent(stateEvent) { return stateEvent.type.startsWith("xstate.done.actor."); } __name(isTransitionEvent, "isTransitionEvent"); function isVariableReference(value) { return typeof value === "object" && "step" in value && "path" in value; } __name(isVariableReference, "isVariableReference"); function getStepResult(result) { if (result?.status === "success") return result.output; return void 0; } __name(getStepResult, "getStepResult"); function getSuspendedPaths({ value, path, suspendedPaths }) { if (typeof value === "string") { if (value === "suspended") { suspendedPaths.add(path); } } else { Object.keys(value).forEach( (key) => getSuspendedPaths({ value: value[key], path: path ? `${path}.${key}` : key, suspendedPaths }) ); } } __name(getSuspendedPaths, "getSuspendedPaths"); function isFinalState(status) { return ["completed", "failed"].includes(status); } __name(isFinalState, "isFinalState"); function isLimboState(status) { return status === "limbo"; } __name(isLimboState, "isLimboState"); function recursivelyCheckForFinalState({ value, suspendedPaths, path }) { if (typeof value === "string") { return isFinalState(value) || isLimboState(value) || suspendedPaths.has(path); } return Object.keys(value).every( (key) => recursivelyCheckForFinalState({ value: value[key], suspendedPaths, path: path ? `${path}.${key}` : key }) ); } __name(recursivelyCheckForFinalState, "recursivelyCheckForFinalState"); function getActivePathsAndStatus(value) { const paths = []; const traverse = /* @__PURE__ */ __name((current, path = []) => { for (const [key, value2] of Object.entries(current)) { const currentPath = [...path, key]; if (typeof value2 === "string") { paths.push({ stepPath: currentPath, stepId: key, status: value2 }); } else if (typeof value2 === "object" && value2 !== null) { traverse(value2, currentPath); } } }, "traverse"); traverse(value); return paths; } __name(getActivePathsAndStatus, "getActivePathsAndStatus"); function mergeChildValue(startStepId, parent, child) { const traverse = /* @__PURE__ */ __name((current) => { const obj = {}; for (const [key, value] of Object.entries(current)) { if (key === startStepId) { obj[key] = { ...child }; } else if (typeof value === "string") { obj[key] = value; } else if (typeof value === "object" && value !== null) { obj[key] = traverse(value); } } return obj; }, "traverse"); return traverse(parent); } __name(mergeChildValue, "mergeChildValue"); var updateStepInHierarchy = /* @__PURE__ */ __name((value, targetStepId) => { const result = {}; for (const key of Object.keys(value)) { const currentValue = value[key]; if (key === targetStepId) { result[key] = "pending"; } else if (typeof currentValue === "object" && currentValue !== null) { result[key] = updateStepInHierarchy(currentValue, targetStepId); } else { result[key] = currentValue; } } return result; }, "updateStepInHierarchy"); function getResultActivePaths(state) { return getActivePathsAndStatus(state.value).reduce((acc, curr) => { const entry = { status: curr.status }; if (curr.status === "suspended") { entry.suspendPayload = state.context.steps[curr.stepId].suspendPayload; } acc.set(curr.stepId, entry); return acc; }, /* @__PURE__ */ new Map()); } __name(getResultActivePaths, "getResultActivePaths"); function isWorkflow(step) { return !!step?.name; } __name(isWorkflow, "isWorkflow"); function resolveVariables({ runId, logger, variables, context }) { const resolvedData = {}; for (const [key, variable] of Object.entries(variables)) { const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id ?? variable.step.name]); logger.debug( `Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id ?? variable.step.name}`, { sourceData, path: variable.path, runId } ); if (!sourceData && variable.step !== "trigger") { resolvedData[key] = void 0; continue; } const value = variable.path === "" || variable.path === "." ? sourceData : get(sourceData, variable.path); logger.debug(`Resolved variable ${key}`, { value, runId }); resolvedData[key] = value; } return resolvedData; } __name(resolveVariables, "resolveVariables"); function workflowToStep(workflow, { mastra }) { workflow.setNested(true); return { id: workflow.name, workflow, execute: /* @__PURE__ */ __name(async ({ context, suspend, emit, runId, mastra: mastra2 }) => { if (mastra2) { workflow.__registerMastra(mastra2); workflow.__registerPrimitives({ logger: mastra2.getLogger(), telemetry: mastra2.getTelemetry() }); } const run = context.isResume ? workflow.createRun({ runId: context.isResume.runId }) : workflow.createRun(); const unwatch = run.watch((state) => { emit("state-update", workflow.name, state.value, { ...context, ...{ [workflow.name]: state.context } }); }); const awaitedResult = context.isResume && context.isResume.stepId.includes(".") ? await run.resume({ stepId: context.isResume.stepId.split(".").slice(1).join("."), context: context.inputData }) : await run.start({ triggerData: context.inputData }); unwatch(); if (!awaitedResult) { throw new Error("Workflow run failed"); } if (awaitedResult.activePaths?.size > 0) { const suspendedStep = [...awaitedResult.activePaths.entries()].find(([stepId, { status }]) => { return status === "suspended"; }); if (suspendedStep) { await suspend(suspendedStep[1].suspendPayload, { ...awaitedResult, runId: run.runId }); } } return { ...awaitedResult, runId: run.runId }; }, "execute") }; } __name(workflowToStep, "workflowToStep"); var _mastra, _workflowInstance, _executionSpan, _stepGraph, _machine, _runId, _startStepId, _actor, _steps, _retryConfig, _Machine_instances, cleanup_fn, makeDelayMap_fn, getDefaultActions_fn, getDefaultActors_fn, resolveVariables_fn, buildStateHierarchy_fn, buildBaseState_fn, evaluateCondition_fn; var _Machine = class _Machine extends EventEmitter { constructor({ logger, mastra, workflowInstance, executionSpan, name, runId, steps, stepGraph, retryConfig, startStepId }) { super(); __privateAdd(this, _Machine_instances); __publicField(this, "logger"); __privateAdd(this, _mastra); __privateAdd(this, _workflowInstance); __privateAdd(this, _executionSpan); __privateAdd(this, _stepGraph); __privateAdd(this, _machine); __privateAdd(this, _runId); __privateAdd(this, _startStepId); __publicField(this, "name"); __privateAdd(this, _actor, null); __privateAdd(this, _steps, {}); __privateAdd(this, _retryConfig); __privateSet(this, _mastra, mastra); __privateSet(this, _workflowInstance, workflowInstance); __privateSet(this, _executionSpan, executionSpan); this.logger = logger; __privateSet(this, _runId, runId); __privateSet(this, _startStepId, startStepId); this.name = name; __privateSet(this, _stepGraph, stepGraph); __privateSet(this, _steps, steps); __privateSet(this, _retryConfig, retryConfig); this.initializeMachine(); } get startStepId() { return __privateGet(this, _startStepId); } async execute({ stepId, input, snapshot, resumeData } = {}) { if (snapshot) { this.logger.debug(`Workflow snapshot received`, { runId: __privateGet(this, _runId), snapshot }); } const origSteps = input.steps; const isResumedInitialStep = __privateGet(this, _stepGraph)?.initial[0]?.step?.id === stepId; if (isResumedInitialStep) { snapshot = void 0; input.steps = {}; } this.logger.debug(`Machine input prepared`, { runId: __privateGet(this, _runId), input }); const actorSnapshot = snapshot ? { ...snapshot, context: { ...input, inputData: { ...snapshot?.context?.inputData || {}, ...resumeData }, // ts-ignore is needed here because our snapshot types don't really match xstate snapshot types right now. We should fix this in general. // @ts-ignore isResume: { runId: snapshot?.context?.steps[stepId.split(".")?.[0]]?.output?.runId || __privateGet(this, _runId), stepId } } } : void 0; this.logger.debug(`Creating actor with configuration`, { input, actorSnapshot, runId: __privateGet(this, _runId), machineStates: __privateGet(this, _machine).config.states }); __privateSet(this, _actor, createActor(__privateGet(this, _machine), { inspect: /* @__PURE__ */ __name((inspectionEvent) => { this.logger.debug("XState inspection event", { type: inspectionEvent.type, event: inspectionEvent.event, runId: __privateGet(this, _runId) }); }, "inspect"), input: { ...input, inputData: { ...snapshot?.context?.inputData || {}, ...resumeData } }, snapshot: actorSnapshot })); __privateGet(this, _actor).start(); if (stepId) { __privateGet(this, _actor).send({ type: "RESET_TO_PENDING", stepId }); } this.logger.debug("Actor started", { runId: __privateGet(this, _runId) }); return new Promise((resolve, reject) => { if (!__privateGet(this, _actor)) { this.logger.error("Actor not initialized", { runId: __privateGet(this, _runId) }); const e = new Error("Actor not initialized"); __privateGet(this, _executionSpan)?.recordException(e); __privateGet(this, _executionSpan)?.end(); reject(e); return; } const suspendedPaths = /* @__PURE__ */ new Set(); __privateGet(this, _actor).subscribe(async (state) => { this.emit("state-update", __privateGet(this, _startStepId), state.value, state.context); getSuspendedPaths({ value: state.value, path: "", suspendedPaths }); const allStatesValue = state.value; const allStatesComplete = recursivelyCheckForFinalState({ value: allStatesValue, suspendedPaths, path: "" }); this.logger.debug("State completion check", { allStatesComplete, suspendedPaths: Array.from(suspendedPaths), runId: __privateGet(this, _runId) }); if (!allStatesComplete) { this.logger.debug("Not all states complete", { allStatesComplete, suspendedPaths: Array.from(suspendedPaths), runId: __privateGet(this, _runId) }); return; } try { this.logger.debug("All states complete", { runId: __privateGet(this, _runId) }); await __privateGet(this, _workflowInstance).persistWorkflowSnapshot(); __privateMethod(this, _Machine_instances, cleanup_fn).call(this); __privateGet(this, _executionSpan)?.end(); resolve({ results: isResumedInitialStep ? { ...origSteps, ...state.context.steps } : state.context.steps, activePaths: getResultActivePaths( state ) }); } catch (error) { this.logger.debug("Failed to persist final snapshot", { error }); __privateMethod(this, _Machine_instances, cleanup_fn).call(this); __privateGet(this, _executionSpan)?.end(); resolve({ results: isResumedInitialStep ? { ...origSteps, ...state.context.steps } : state.context.steps, activePaths: getResultActivePaths( state ) }); } }); }); } initializeMachine() { const machine = setup({ types: {}, delays: __privateMethod(this, _Machine_instances, makeDelayMap_fn).call(this), actions: __privateMethod(this, _Machine_instances, getDefaultActions_fn).call(this), actors: __privateMethod(this, _Machine_instances, getDefaultActors_fn).call(this) }).createMachine({ id: this.name, type: "parallel", context: /* @__PURE__ */ __name(({ input }) => ({ ...input }), "context"), states: __privateMethod(this, _Machine_instances, buildStateHierarchy_fn).call(this, __privateGet(this, _stepGraph)) }); __privateSet(this, _machine, machine); return machine; } getSnapshot() { const snapshot = __privateGet(this, _actor)?.getSnapshot(); return snapshot; } }; _mastra = new WeakMap(); _workflowInstance = new WeakMap(); _executionSpan = new WeakMap(); _stepGraph = new WeakMap(); _machine = new WeakMap(); _runId = new WeakMap(); _startStepId = new WeakMap(); _actor = new WeakMap(); _steps = new WeakMap(); _retryConfig = new WeakMap(); _Machine_instances = new WeakSet(); cleanup_fn = /* @__PURE__ */ __name(function() { if (__privateGet(this, _actor)) { __privateGet(this, _actor).stop(); __privateSet(this, _actor, null); } this.removeAllListeners(); }, "#cleanup"); makeDelayMap_fn = /* @__PURE__ */ __name(function() { const delayMap = {}; Object.keys(__privateGet(this, _steps)).forEach((stepId) => { delayMap[stepId] = __privateGet(this, _steps)[stepId]?.retryConfig?.delay || __privateGet(this, _retryConfig)?.delay || 1e3; }); return delayMap; }, "#makeDelayMap"); getDefaultActions_fn = /* @__PURE__ */ __name(function() { return { updateStepResult: assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (!isTransitionEvent(event)) return context.steps; const { stepId, result } = event.output; return { ...context.steps, [stepId]: { status: "success", output: result } }; }, "steps") }), setStepError: assign({ steps: /* @__PURE__ */ __name(({ context, event }, params) => { if (!isErrorEvent(event)) return context.steps; const { stepId } = params; if (!stepId) return context.steps; return { ...context.steps, [stepId]: { status: "failed", error: event.error.message } }; }, "steps") }), notifyStepCompletion: /* @__PURE__ */ __name(async (_, params) => { const { stepId } = params; this.logger.debug(`Step ${stepId} completed`); }, "notifyStepCompletion"), snapshotStep: assign({ _snapshot: /* @__PURE__ */ __name(({}, params) => { const { stepId } = params; return { stepId }; }, "_snapshot") }), persistSnapshot: /* @__PURE__ */ __name(async ({ context }) => { if (context._snapshot) { await __privateGet(this, _workflowInstance).persistWorkflowSnapshot(); } return; }, "persistSnapshot"), decrementAttemptCount: assign({ attempts: /* @__PURE__ */ __name(({ context, event }, params) => { if (!isTransitionEvent(event)) return context.attempts; const { stepId } = params; const attemptCount = context.attempts[stepId]; if (attemptCount === void 0) return context.attempts; return { ...context.attempts, [stepId]: attemptCount - 1 }; }, "attempts") }) }; }, "#getDefaultActions"); getDefaultActors_fn = /* @__PURE__ */ __name(function() { return { resolverFunction: fromPromise(async ({ input }) => { const { stepNode, context } = input; const attemptCount = context.attempts[stepNode.step.id]; const resolvedData = __privateMethod(this, _Machine_instances, resolveVariables_fn).call(this, { stepConfig: stepNode.config, context, stepId: stepNode.step.id }); this.logger.debug(`Resolved variables for ${stepNode.step.id}`, { resolvedData, runId: __privateGet(this, _runId) }); const logger = this.logger; let mastraProxy = void 0; if (__privateGet(this, _mastra)) { mastraProxy = createMastraProxy({ mastra: __privateGet(this, _mastra), logger }); } let result = void 0; try { result = await stepNode.config.handler({ context: { ...context, inputData: { ...context?.inputData || {}, ...resolvedData }, getStepResult: /* @__PURE__ */ __name((stepId) => { const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id; if (resolvedStepId === "trigger") { return context.triggerData; } const result2 = context.steps[resolvedStepId]; if (result2 && result2.status === "success") { return result2.output; } return void 0; }, "getStepResult") }, emit: /* @__PURE__ */ __name((event, ...args) => { this.emit(event, ...args); }, "emit"), suspend: /* @__PURE__ */ __name(async (payload, softSuspend) => { await __privateGet(this, _workflowInstance).suspend(stepNode.step.id, this); if (__privateGet(this, _actor)) { context.steps[stepNode.step.id] = { status: "suspended", suspendPayload: payload, output: softSuspend }; this.logger.debug(`Sending SUSPENDED event for step ${stepNode.step.id}`); __privateGet(this, _actor)?.send({ type: "SUSPENDED", suspendPayload: payload, stepId: stepNode.step.id, softSuspend }); } else { this.logger.debug(`Actor not available for step ${stepNode.step.id}`); } }, "suspend"), runId: __privateGet(this, _runId), mastra: mastraProxy }); } catch (error) { this.logger.debug(`Step ${stepNode.step.id} failed`, { stepId: stepNode.step.id, error, runId: __privateGet(this, _runId) }); this.logger.debug(`Attempt count for step ${stepNode.step.id}`, { attemptCount, attempts: context.attempts, runId: __privateGet(this, _runId), stepId: stepNode.step.id }); if (!attemptCount || attemptCount < 0) { return { type: "STEP_FAILED", error: error instanceof Error ? error.message : `Step:${stepNode.step.id} failed with error: ${error}`, stepId: stepNode.step.id }; } return { type: "STEP_WAITING", stepId: stepNode.step.id }; } this.logger.debug(`Step ${stepNode.step.id} result`, { stepId: stepNode.step.id, result, runId: __privateGet(this, _runId) }); return { type: "STEP_SUCCESS", result, stepId: stepNode.step.id }; }), conditionCheck: fromPromise(async ({ input }) => { const { context, stepNode } = input; const stepConfig = stepNode.config; this.logger.debug(`Checking conditions for step ${stepNode.step.id}`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); if (!stepConfig?.when) { return { type: "CONDITIONS_MET" }; } this.logger.debug(`Checking conditions for step ${stepNode.step.id}`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); if (typeof stepConfig?.when === "function") { let conditionMet = await stepConfig.when({ context: { ...context, getStepResult: /* @__PURE__ */ __name((stepId) => { const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id; if (resolvedStepId === "trigger") { return context.triggerData; } const result = context.steps[resolvedStepId]; if (result && result.status === "success") { return result.output; } return void 0; }, "getStepResult") }, mastra: __privateGet(this, _mastra) }); if (conditionMet === "abort" /* ABORT */) { conditionMet = false; } else if (conditionMet === "continue_failed" /* CONTINUE_FAILED */) { return { type: "CONDITIONS_SKIP_TO_COMPLETED" }; } else if (conditionMet === "limbo" /* LIMBO */) { return { type: "CONDITIONS_LIMBO" }; } else if (conditionMet) { this.logger.debug(`Condition met for step ${stepNode.step.id}`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); return { type: "CONDITIONS_MET" }; } return __privateGet(this, _workflowInstance).hasSubscribers(stepNode.step.id) ? { type: "CONDITIONS_SKIPPED" } : { type: "CONDITIONS_LIMBO" }; } else { const conditionMet = __privateMethod(this, _Machine_instances, evaluateCondition_fn).call(this, stepConfig.when, context); if (!conditionMet) { return { type: "CONDITION_FAILED", error: `Step:${stepNode.step.id} condition check failed` }; } } return { type: "CONDITIONS_MET" }; }), spawnSubscriberFunction: fromPromise( async ({ input }) => { const { parentStepId, context } = input; const result = await __privateGet(this, _workflowInstance).runMachine(parentStepId, context); return Promise.resolve({ steps: result.reduce((acc, r) => { return { ...acc, ...r?.results }; }, {}) }); } ) }; }, "#getDefaultActors"); resolveVariables_fn = /* @__PURE__ */ __name(function({ stepConfig, context, stepId }) { this.logger.debug(`Resolving variables for step ${stepId}`, { stepId, runId: __privateGet(this, _runId) }); const resolvedData = {}; for (const [key, variable] of Object.entries(stepConfig.data)) { const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id]); this.logger.debug( `Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id}`, { sourceData, path: variable.path, runId: __privateGet(this, _runId) } ); if (!sourceData && variable.step !== "trigger") { resolvedData[key] = void 0; continue; } const value = variable.path === "" || variable.path === "." ? sourceData : get(sourceData, variable.path); this.logger.debug(`Resolved variable ${key}`, { value, runId: __privateGet(this, _runId) }); resolvedData[key] = value; } return resolvedData; }, "#resolveVariables"); buildStateHierarchy_fn = /* @__PURE__ */ __name(function(stepGraph) { const states = {}; stepGraph.initial.forEach((stepNode) => { const nextSteps = [...stepGraph[stepNode.step.id] || []]; states[stepNode.step.id] = { ...__privateMethod(this, _Machine_instances, buildBaseState_fn).call(this, stepNode, nextSteps) }; }); return states; }, "#buildStateHierarchy"); buildBaseState_fn = /* @__PURE__ */ __name(function(stepNode, nextSteps = []) { const nextStep = nextSteps.shift(); return { initial: "pending", on: { RESET_TO_PENDING: { target: ".pending" // Note the dot to target child state } }, states: { pending: { entry: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} pending`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, "entry"), exit: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} finished pending`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, "exit"), invoke: { src: "conditionCheck", input: /* @__PURE__ */ __name(({ context }) => { return { context, stepNode }; }, "input"), onDone: [ { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "SUSPENDED"; }, "guard"), target: "suspended", actions: [ assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "SUSPENDED") return context.steps; if (event.output.softSuspend) { return { ...context.steps, [stepNode.step.id]: { status: "suspended", ...context.steps?.[stepNode.step.id] || {}, output: event.output.softSuspend } }; } return { ...context.steps, [stepNode.step.id]: { status: "suspended", ...context.steps?.[stepNode.step.id] || {} } }; }, "steps"), attempts: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "SUSPENDED") return context.attempts; return { ...context.attempts, [stepNode.step.id]: stepNode.step.retryConfig?.attempts || 0 }; }, "attempts") }) ] }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "WAITING"; }, "guard"), target: "waiting", actions: [ { type: "decrementAttemptCount", params: { stepId: stepNode.step.id } }, assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "WAITING") return context.steps; return { ...context.steps, [stepNode.step.id]: { status: "waiting" } }; }, "steps") }) ] }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "CONDITIONS_MET"; }, "guard"), target: "executing" }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "CONDITIONS_SKIP_TO_COMPLETED"; }, "guard"), target: "completed" }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "CONDITIONS_SKIPPED"; }, "guard"), actions: assign({ steps: /* @__PURE__ */ __name(({ context }) => { const newStep = { ...context.steps, [stepNode.step.id]: { status: "skipped" } }; this.logger.debug(`Step ${stepNode.step.id} skipped`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); return newStep; }, "steps") }), target: "runningSubscribers" }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "CONDITIONS_LIMBO"; }, "guard"), target: "limbo", actions: assign({ steps: /* @__PURE__ */ __name(({ context }) => { const newStep = { ...context.steps, [stepNode.step.id]: { status: "skipped" } }; this.logger.debug(`Step ${stepNode.step.id} skipped`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); return newStep; }, "steps") }) }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "CONDITION_FAILED"; }, "guard"), target: "failed", actions: assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "CONDITION_FAILED") return context.steps; this.logger.debug(`Workflow condition check failed`, { error: event.output.error, stepId: stepNode.step.id }); return { ...context.steps, [stepNode.step.id]: { status: "failed", error: event.output.error } }; }, "steps") }) } ] } }, waiting: { entry: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} waiting`, { stepId: stepNode.step.id, timestamp: (/* @__PURE__ */ new Date()).toISOString(), runId: __privateGet(this, _runId) }); }, "entry"), exit: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} finished waiting`, { stepId: stepNode.step.id, timestamp: (/* @__PURE__ */ new Date()).toISOString(), runId: __privateGet(this, _runId) }); }, "exit"), after: { [stepNode.step.id]: { target: "pending" } } }, limbo: { // no target, will stay in limbo indefinitely entry: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} limbo`, { stepId: stepNode.step.id, timestamp: (/* @__PURE__ */ new Date()).toISOString(), runId: __privateGet(this, _runId) }); }, "entry"), exit: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} finished limbo`, { stepId: stepNode.step.id, timestamp: (/* @__PURE__ */ new Date()).toISOString(), runId: __privateGet(this, _runId) }); }, "exit") }, suspended: { type: "final", entry: [ () => { this.logger.debug(`Step ${stepNode.step.id} suspended`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { return { ...context.steps, [stepNode.step.id]: { ...context?.steps?.[stepNode.step.id] || {}, status: "suspended", suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0, output: event.type === "SUSPENDED" ? event.softSuspend : void 0 } }; }, "steps") }) ] }, executing: { entry: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} executing`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, "entry"), on: { SUSPENDED: { target: "suspended", actions: [ assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { return { ...context.steps, [stepNode.step.id]: { status: "suspended", suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0, output: event.type === "SUSPENDED" ? event.softSuspend : void 0 } }; }, "steps") }) ] } }, invoke: { src: "resolverFunction", input: /* @__PURE__ */ __name(({ context }) => ({ context, stepNode }), "input"), onDone: [ { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "STEP_FAILED"; }, "guard"), target: "failed", actions: assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "STEP_FAILED") return context.steps; const newStep = { ...context.steps, [stepNode.step.id]: { status: "failed", error: event.output.error } }; this.logger.debug(`Step ${stepNode.step.id} failed`, { error: event.output.error, stepId: stepNode.step.id }); return newStep; }, "steps") }) }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "STEP_SUCCESS"; }, "guard"), actions: [ ({ event }) => { this.logger.debug(`Step ${stepNode.step.id} finished executing`, { stepId: stepNode.step.id, output: event.output, runId: __privateGet(this, _runId) }); }, { type: "updateStepResult", params: { stepId: stepNode.step.id } }, { type: "spawnSubscribers", params: { stepId: stepNode.step.id } } ], target: "runningSubscribers" }, { guard: /* @__PURE__ */ __name(({ event }) => { return event.output.type === "STEP_WAITING"; }, "guard"), target: "waiting", actions: [ { type: "decrementAttemptCount", params: { stepId: stepNode.step.id } }, assign({ steps: /* @__PURE__ */ __name(({ context, event }) => { if (event.output.type !== "STEP_WAITING") return context.steps; return { ...context.steps, [stepNode.step.id]: { status: "waiting" } }; }, "steps") }) ] } ], onError: { target: "failed", actions: [{ type: "setStepError", params: { stepId: stepNode.step.id } }] } } }, runningSubscribers: { entry: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} running subscribers`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, "entry"), exit: /* @__PURE__ */ __name(() => { this.logger.debug(`Step ${stepNode.step.id} finished running subscribers`, { stepId: stepNode.step.id, runId: __privateGet(this, _runId) }); }, "exit"), invoke: { src: "spawnSubscriberFunction", input: /* @__PURE__ */ __name(({ context }) => ({ parentStepId: stepNode.step.id, context }), "input"), onDone: { target: nextStep ? nextStep.step.id : "completed", actions: [ assign({ steps: /* @__PURE__ */ __name(({ context, event }) => ({ ...context.steps, ...event.output.steps }), "steps") }), () => this.logger.debug(`Subscriber execution completed`, { stepId: stepNode.step.id }) ] }, onError: { target: nextStep ? nextStep.step.id : "completed", actions: /* @__PURE__ */ __name(({ event }) => { this.logger.debug(`Subscriber execution failed`, { error: event.error, stepId: stepNode.step.id }); }, "actions") } } }, completed: { type: "final", entry: [ { type: "notifyStepCompletion", params: { stepId: stepNode.step.id } }, { type: "snapshotStep", params: { stepId: stepNode.step.id } }, { type: "persistSnapshot" } ] }, failed: { type: "final", entry: [ { type: "notifyStepCompletion", params: { stepId: stepNode.step.id } }, { type: "snapshotStep", params: { stepId: stepNode.step.id } }, { type: "persistSnapshot" } ] }, // build chain of next steps recursively ...nextStep ? { [nextStep.step.id]: { ...__privateMethod(this, _Machine_instances, buildBaseState_fn).call(this, nextStep, nextSteps) } } : {} } }; }, "#buildBaseState"); evaluateCondition_fn = /* @__PURE__ */ __name(function(condition, context) { let andBranchResult = true; let baseResult = true; let orBranchResult = true; const simpleCondition = Object.entries(condition).find(([key]) => key.includes(".")); if (simpleCondition) { const [key, queryValue] = simpleCondition; const [stepId, ...pathParts] = key.split("."); const path = pathParts.join("."); const sourceData = stepId === "trigger" ? context.triggerData : getStepResult(context.steps[stepId]); this.logger.debug(`Got condition data from step ${stepId}`, { stepId, sourceData, runId: __privateGet(this, _runId) }); if (!sourceData) { return false; } let value = get(sourceData, path); if (stepId !== "trigger" && path === "status" && !value) { value = "success"; } if (typeof queryValue === "object" && queryValue !== null) { baseResult = sift(queryValue)(value); } else { baseResult = value === queryValue; } } if ("ref" in condition) { const { ref, query } = condition; const sourceData = ref.step === "trigger" ? context.triggerData : getStepResult(context.steps[ref.step.id]); this.logger.debug(`Got condition data from ${ref.step === "trigger" ? "trigger" : ref.step.id}`, { sourceData, runId: __privateGet(this, _runId) }); if (!sourceData) { return false; } let value = get(sourceData, ref.path); if (ref.step !== "trigger" && ref.path === "status" && !value) { value = "success"; } baseResult = sift(query)(value); } if ("and" in condition) { andBranchResult = condition.and.every((cond) => __privateMethod(this, _Machine_instances, evaluateCondition_fn).call(this, cond, context)); this.logger.debug(`Evaluated AND condition`, { andBranchResult, runId: __privateGet(this, _runId) }); } if ("or" in condition) { orBranchResult = condition.or.some((cond) => __privateMethod(this, _Machine_instances, evaluateCondition_fn).call(this, cond, context)); this.logger.debug(`Evaluated OR condition`, { orBranchResult, runId: __privateGet(this, _runId) }); } if ("not" in condition) { baseResult = !__privateMethod(this, _Machine_instances, evaluateCondition_fn).call(this, condition.not, context); this.logger.debug(`Evaluated NOT condition`, { baseResult, runId: __privateGet(this, _runId) }); } const finalResult = baseResult && andBranchResult && orBranchResult; this.logger.debug(`Evaluated condition`, { finalResult, runId: __privateGet(this, _runId) }); return finalResult; }, "#evaluateCondition"); __name(_Machine, "Machine"); var Machine = _Machine; // src/workflows/workflow-instance.ts var _mastra2, _machines, _steps2, _stepGraph2, _stepSubscriberGraph, _retryConfig2, _runId2, _state, _executionSpan2, _onStepTransition, _onFinish, _resultMapping, _suspendedMachines, _compoundDependencies, _WorkflowInstance_instances, loadWorkflowSnapshot_fn, initializeCompoundDependencies_fn, makeStepDef_fn, isCompoundKey_fn; var _WorkflowInstance = class _WorkflowInstance { constructor({ name, logger, steps, runId, retryConfig, mastra, stepGraph, stepSubscriberGraph, onFinish, onStepTransition, resultMapping, events }) { __privateAdd(this, _WorkflowInstance_instances); __publicField(this, "name"); __privateAdd(this, _mastra2); __privateAdd(this, _machines, {}); __publicField(this, "logger"); __privateAdd(this, _steps2, {}); __privateAdd(this, _stepGraph2); __privateAdd(this, _stepSubscriberGraph, {}); __privateAdd(this, _retryConfig2); __publicField(this, "events"); __privateAdd(this, _runId2); __privateAdd(this, _state, null); __privateAdd(this, _executionSpan2); __privateAdd(this, _onStepTransition, /* @__PURE__ */ new Set()); __privateAdd(this, _onFinish); __privateAdd(this, _resultMapping); // indexed by stepId __privateAdd(this, _suspendedMachines, {}); // {step1&&step2: {step1: true, step2: true}} __privateAdd(this, _compoundDependencies, {}); this.name = name; this.logger = logger; __privateSet(this, _steps2, steps); __privateSet(this, _stepGraph2, stepGraph); __privateSet(this, _stepSubscriberGraph, stepSubscriberGraph); __privateSet(this, _retryConfig2, retryConfig); __privateSet(this, _mastra2, mastra); __privateSet(this, _runId2, runId ?? crypto.randomUUID()); __privateSet(this, _onFinish, onFinish); __privateSet(this, _resultMapping, resultMapping); this.events = events; onStepTransition?.forEach((handler) => __privateGet(this, _onStepTransition).add(handler)); __privateMethod(this, _WorkflowInstance_instances, initializeCompoundDependencies_fn).call(this); } setState(state) { __privateSet(this, _state, state); } get runId() { return __privateGet(this, _runId2); } get executionSpan() { return __privateGet(this, _executionSpan2); } watch(onTransition) { __privateGet(this, _onStepTransition).add(onTransition); return () => { __privateGet(this, _onStepTransition).delete(onTransition); }; } async start({ triggerData } = {}) { const results = await this.execute({ triggerData }); if (__privateGet(this, _onFinish)) { __privateGet(this, _onFinish).call(this); } return { ...results, runId: this.runId }; } isCompoundDependencyMet(stepKey) { if (!__privateMethod(this, _WorkflowInstance_instances, isCompoundKey_fn).call(this, stepKey)) return true; const dependencies = __privateGet(this, _compoundDependencies)[stepKey]; return dependencies ? Object.values(dependencies).every((status) => status === true) : true; } async execute({ triggerData, snapshot, stepId, resumeData } = {}) { __privateSet(this, _executionSpan2, __privateGet(this, _mastra2)?.getTelemetry()?.tracer.startSpan(`workflow.${this.name}.execute`, { attributes: { componentName: this.name, runId: this.runId } })); let machineInput = { // Maintain the original step results and their output steps: {}, triggerData: triggerData || {}, attempts: Object.keys(__privateGet(this, _steps2)).reduce( (acc, stepKey) => { acc[stepKey] = __privateGet(this, _steps2)[stepKey]?.retryConfig?.attempts || __privateGet(this, _retryConfig2)?.attempts || 0; return acc; }, {} ) }; let stepGraph = __privateGet(this, _stepGraph2); let startStepId = "trigger"; if (snapshot) { const runState = snapshot; if (stepId && runState?.suspendedSteps?.[stepId]) { startStepId = runState.suspendedSteps[stepId]; stepGraph = __privateGet(this, _stepSubscriberGraph)[startStepId] ?? __privateGet(this, _stepGraph2); machineInput = runState.context; } } const defaultMachine = new Machine({ logger: this.logger, mastra: __privateGet(this, _mastra2), workflowInstance: this, name: this.name, runId: this.runId, steps: __privateGet(this, _steps2), stepGraph, executionSpan: __privateGet(this, _executionSpan2), startStepId, retryConfig: __privateGet(this, _retryConfig2) }); __privateGet(this, _machines)[startStepId] = defaultMachine; const stateUpdateHandler = /* @__PURE__ */ __name((startStepId2, state, context) => { if (startStepId2 === "trigger") { __privateSet(this, _state, state); } else { __privateSet(this, _state, mergeChildValue(startStepId2, __privateGet(this, _state), state)); } const now = Date.now(); if (__privateGet(this, _onStepTransition)) { __privateGet(this, _onStepTransition).forEach((onTransition) => { void onTransition({ runId: __privateGet(this, _runId2), value: __privateGet(this, _state), context, activePaths: getActivePathsAndStatus(__privateGet(this, _state)), timestamp: now }); }); } }, "stateUpdateHandler"); defaultMachine.on("state-update", stateUpdateHandler); const { results, activePaths } = await defaultMachine.execute({ snapshot, stepId, input: machineInput, resumeData }); await this.persistWorkflowSnapshot(); const result = { results, activePaths }; if (__privateGet(this, _resultMapping)) { result.result = resolveVariables({ runId: __privateGet(this, _runId2), logger: this.logger, variables: __privateGet(this, _resultMapping), context: { steps: results, triggerData} }); } return result; } hasSubscribers(stepId) { return Object.keys(__privateGet(this, _stepSubscriberGraph)).some((key) => key.split("&&").includes(stepId)); } async runMachine(parentStepId, input) { const stepStatus = input.steps[parentStepId]?.status; const subscriberKeys = Object.keys(__privateGet(this, _stepSubscriberGraph)).filter((key) => key.split("&&").includes(parentStepId)); subscriberKeys.forEach((key) => { if (["success", "failure", "skipped"].includes(stepStatus) && __privateMethod(this, _WorkflowInstance_instances, isCompoundKey_fn).call(this, key)) { __privateGet(this, _compoundDependencies)[key][parentStepId] = true; } }); const stateUpdateHandler = /* @__PURE__ */ __name((startStepId, state, context) => { if (startStepId === "trigger") { __privateSet(this, _state, state); } else { __privateSet(this, _state, mergeChildValue(startStepId, __privateGet(this, _state), state)); } const now = Date.now(); if (__privateGet(this, _onStepTransition)) { __privateGet(this, _onStepTransition).forEach((onTransition) => { void onTransition({ runId: __privateGet(this, _runId2), value: __privateGet(this, _state), context, activePaths: getActivePathsAndStatus(__privateGet(this, _state)), timestamp: n