UNPKG

@mastra/core

Version:
350 lines (349 loc) 15.9 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const require_agent = require("../agent-DCD4MApC.cjs"); const require_cron = require("../cron-CrmzJKFJ.cjs"); const require_workflow_event_processor = require("../workflow-event-processor-CkjVcesJ.cjs"); const require_scheduler = require("../scheduler-D9Mqp8B5.cjs"); const require_validate = require("../validate-C0iI8guc.cjs"); let _mastra_schema_compat_schema = require("@mastra/schema-compat/schema"); //#region src/workflows/stored/serialize.ts /** * Live → Storable half of the workflow round-trip: walk a live `stepFlow` * (runtime references, closures) and emit the JSON-safe storable form * (ids + serialized mapping configs, no closures). * * The static subset that round-trips: * - agent / tool by id * - mapping with `value`, `step`, `initData`, `requestContextPath`, `template`, * `state` sources (no `fn` source — closures don't round-trip) * - sleep / sleepUntil with literal duration/date * - parallel (inner entries must themselves be static) * - foreach with literal concurrency * - conditional / loop with declarative predicates (closure predicates throw) * - generic `.then(step)` falls back to a minimal step descriptor — usable * only when the step's id resolves on the live Mastra at load time * * Anything outside the subset throws at `toStorableGraph` time: silent loss * would ship broken workflows unnoticed. */ /** * Walk a live `stepFlow` and emit a JSON-safe `SerializedStepFlowEntry[]` with * full (un-truncated) mapping configs and all step/agent/tool references stored * as ids. Throws on entries that can't round-trip (closures, closure predicates). */ function toStorableGraph(stepFlow) { return stepFlow.map((entry) => serializeEntry(entry)); } function serializeEntry(entry) { switch (entry.type) { case "step": case "agent": case "tool": case "mapping": return serializeSingleEntry(entry); case "sleep": if (typeof entry.duration !== "number") throw new Error(`Sleep step "${entry.id}" cannot be stored: dynamic duration (function) is not supported.`); return { type: "sleep", id: entry.id, duration: entry.duration }; case "sleepUntil": if (!(entry.date instanceof Date)) throw new Error(`SleepUntil step "${entry.id}" cannot be stored: dynamic date (function) is not supported.`); return { type: "sleepUntil", id: entry.id, date: entry.date }; case "parallel": return { type: "parallel", steps: entry.steps.map((s) => serializeSingleEntry(s)) }; case "foreach": if (entry.step.type === "mapping") throw new Error(`Foreach step cannot iterate a mapping: mappings project data, they don't execute per item. Use an agent, tool, or plain step as the foreach body.`); return { type: "foreach", step: serializeSingleEntry(entry.step), opts: typeof entry.opts.concurrency === "function" ? { fn: entry.opts.concurrency.toString() } : { concurrency: entry.opts.concurrency } }; case "conditional": { const predicates = entry.predicates; if (!predicates || predicates.some((p) => !p || typeof p !== "object")) throw new Error(`Conditional (branch) step cannot be stored: closure predicates do not round-trip. Use the declarative form ({ predicate: {...} }) for each branch.`); return { type: "conditional", steps: entry.steps.map((s) => serializeSingleEntry(s)), serializedConditions: entry.serializedConditions, predicates }; } case "loop": { const predicate = entry.predicate; if (!predicate || typeof predicate !== "object") throw new Error(`Loop step "${require_workflow_event_processor.getSingleStepEntryId(entry.step)}" cannot be stored: closure predicates do not round-trip. Use the declarative form ({ predicate: {...} }).`); return { type: "loop", step: serializeSingleEntry(entry.step), serializedCondition: entry.serializedCondition, loopType: entry.loopType, predicate }; } default: throw new Error(`Unknown step entry type: ${JSON.stringify(entry)}`); } } function serializeSingleEntry(entry) { if (entry.type === "agent") { const options = pickSerializableStepOptions(entry.options, entry.id, "agent"); const outputSchema = extractStructuredOutputJsonSchema(entry.options, entry.id); return { type: "agent", id: entry.id, agentId: entry.agentId, description: entry.agent?.description, ...outputSchema ? { outputSchema } : {}, ...options ? { options } : {} }; } if (entry.type === "tool") { const options = pickSerializableStepOptions(entry.options, entry.id, "tool"); return { type: "tool", id: entry.id, toolId: entry.toolId, description: entry.tool?.description, ...options ? { options } : {} }; } if (entry.type === "mapping") { if (typeof entry.mapConfig === "function") throw new Error(`Mapping step "${entry.id}" cannot be stored: the function form does not round-trip. Use the declarative form (template / step / initData / value).`); const serialized = {}; for (const [key, mapping] of Object.entries(entry.mapConfig)) { const m = mapping; if (m.fn !== void 0) throw new Error(`Mapping step "${entry.id}" key "${key}" cannot be stored: source is a function.`); if (m.value !== void 0) serialized[key] = { value: m.value }; else if (m.requestContextPath) serialized[key] = { requestContextPath: m.requestContextPath }; else if (typeof m.template === "string") serialized[key] = { template: m.template }; else if (m.initData) serialized[key] = { initData: m.initData?.id, path: m.path }; else if (m.step) serialized[key] = { step: Array.isArray(m.step) ? m.step.map((s) => s?.id) : m.step?.id, path: m.path }; else serialized[key] = m; } return { type: "mapping", id: entry.id, mapConfig: JSON.stringify(serialized) }; } if (entry.step?.component === "WORKFLOW") { const nestedFlow = entry.step.serializedStepGraph ?? entry.step.serializedStepFlow; return { type: "workflow", id: entry.step.id, workflowId: entry.step.id, ...entry.step.description ? { description: entry.step.description } : {}, ...nestedFlow ? { serializedStepFlow: nestedFlow } : {} }; } return { type: "step", step: stepDescriptor(entry.step) }; } function stepDescriptor(step) { return { id: step.id, description: step.description, metadata: step.metadata, component: step.component, canSuspend: Boolean(step.suspendSchema || step.resumeSchema) }; } /** * Pull the JSON-safe fields (`retries`, `metadata`) out of the options bag * carried on a live agent/tool `SingleStepEntry`. Closure-valued fields must * hard-crash here rather than silently vanish through storage. */ function pickSerializableStepOptions(options, entryId, kind) { if (!options || typeof options !== "object") return void 0; for (const { key, hint } of [ { key: "onFinish", hint: "callback closure" }, { key: "onChunk", hint: "callback closure" }, { key: "onError", hint: "callback closure" }, { key: "onStepFinish", hint: "callback closure" }, { key: "onAbort", hint: "callback closure" }, { key: "toolChoice", hint: "may be a function" } ]) if (typeof options[key] === "function") throw new Error(`${kind === "agent" ? "Agent" : "Tool"} step "${entryId}" cannot be stored: option "${key}" is a ${hint} that does not round-trip. Remove it or move that logic outside the persisted workflow.`); if (typeof options.scorers === "function") throw new Error(`${kind === "agent" ? "Agent" : "Tool"} step "${entryId}" cannot be stored: "scorers" is a function; only the static array form round-trips.`); const out = {}; if (typeof options.retries === "number") out.retries = options.retries; if (options.metadata && typeof options.metadata === "object") out.metadata = options.metadata; return Object.keys(out).length > 0 ? out : void 0; } /** * If the agent-step options carry `structuredOutput.schema`, that schema IS * the step's output shape (see `createStepFromAgent`). Emit it as JSON Schema * so rehydration can wire the same structured output back in. */ function extractStructuredOutputJsonSchema(options, entryId) { const raw = options?.structuredOutput?.schema; if (raw === void 0 || raw === null) return void 0; try { return (0, _mastra_schema_compat_schema.standardSchemaToJSONSchema)((0, _mastra_schema_compat_schema.toStandardSchema)(raw)); } catch (e) { throw new Error(`Agent step "${entryId}" cannot be stored: structuredOutput.schema is not convertible to JSON Schema (${e.message}).`); } } //#endregion //#region src/workflows/state-reader.ts const getStep = (state, stepId) => state.steps?.[stepId]; const getFirstStepResult = (step) => { return Array.isArray(step) ? step.find((result) => result?.status === "suspended") ?? step[0] : step; }; const getNestedSuspendPath = (step) => { const path = getFirstStepResult(step)?.suspendPayload?.__workflow_meta?.path; return Array.isArray(path) ? path.filter((part) => typeof part === "string") : []; }; function getWorkflowStepOutput(state, stepId) { const step = getStep(state, stepId); return Array.isArray(step) ? step.map((result) => result?.output) : step?.output; } function getWorkflowStepPayload(state, stepId) { const step = getStep(state, stepId); return Array.isArray(step) ? step.map((result) => result?.payload) : step?.payload; } function getWorkflowResumeLabel(state, label) { const resumeLabel = state.resumeLabels?.[label]; return resumeLabel ? { ...resumeLabel } : void 0; } function getWorkflowResumeLabels(state) { return Object.entries(state.resumeLabels ?? {}).reduce((labels, [label, value]) => { labels[label] = { ...value }; return labels; }, {}); } function getWorkflowSuspendedSteps(state) { return Object.entries(state.suspendedPaths ?? {}).map(([stepId, executionPath]) => { const step = getStep(state, stepId); const firstStepResult = getFirstStepResult(step); const nestedPath = getNestedSuspendPath(step); const path = nestedPath.length > 0 ? nestedPath[0] === stepId ? nestedPath : [stepId, ...nestedPath] : [stepId]; const resumeLabels = Object.entries(state.resumeLabels ?? {}).reduce((labels, [label, value]) => { if (value.stepId === stepId) labels[label] = { ...value }; return labels; }, {}); return { stepId, path, executionPath, step, payload: Array.isArray(step) ? step.map((result) => result?.payload) : step?.payload, suspendPayload: firstStepResult?.suspendPayload, suspendOutput: firstStepResult?.suspendOutput, resumeLabels }; }); } function getWorkflowSuspendedStep(state) { return getWorkflowSuspendedSteps(state)[0]; } function createWorkflowStateReader(state) { return { getStatus: () => state.status, getResult: () => state.result, getError: () => state.error, getStepOutput: (stepId) => getWorkflowStepOutput(state, stepId), getStepPayload: (stepId) => getWorkflowStepPayload(state, stepId), getSuspendedStep: () => getWorkflowSuspendedStep(state), getSuspendedSteps: () => getWorkflowSuspendedSteps(state), getResumeLabel: (label) => getWorkflowResumeLabel(state, label), getResumeLabels: () => getWorkflowResumeLabels(state) }; } //#endregion exports.DefaultExecutionEngine = require_agent.DefaultExecutionEngine; exports.ExecutionEngine = require_agent.ExecutionEngine; exports.Run = require_agent.Run; exports.Scheduler = require_scheduler.Scheduler; exports.Workflow = require_agent.Workflow; exports.WorkflowScheduler = require_scheduler.WorkflowScheduler; exports.analyzeMapConfig = require_validate.analyzeMapConfig; exports.assertValidStoredWorkflow = require_validate.assertValidStoredWorkflow; exports.cleanStepResult = require_workflow_event_processor.cleanStepResult; exports.cloneStep = require_agent.cloneStep$1; exports.cloneWorkflow = require_agent.cloneWorkflow; exports.collectNestedWorkflowIds = require_validate.collectNestedWorkflowIds; exports.computeNextFireAt = require_cron.computeNextFireAt; exports.createDeprecationProxy = require_workflow_event_processor.createDeprecationProxy; exports.createEventedWorkflow = require_agent.createEventedWorkflow; exports.createMappingStep = require_agent.createMappingStep; exports.createRestartExecutionParams = require_workflow_event_processor.createRestartExecutionParams; exports.createStep = require_agent.createStep$1; exports.createStepFromAgent = require_agent.createStepFromAgent; exports.createStepFromTool = require_agent.createStepFromTool; exports.createTimeTravelExecutionParams = require_workflow_event_processor.createTimeTravelExecutionParams; exports.createWorkflow = require_agent.createWorkflow; exports.createWorkflowStateReader = createWorkflowStateReader; exports.derivePredicateLabel = require_agent.derivePredicateLabel; exports.evaluatePredicate = require_agent.evaluatePredicate; exports.forEachSingleStepEntry = require_validate.forEachSingleStepEntry; exports.forEachSingleStepEntryWithPath = require_validate.forEachSingleStepEntryWithPath; exports.getEntryId = require_workflow_event_processor.getEntryId; exports.getEntryWorkflow = require_workflow_event_processor.getEntryWorkflow; exports.getResumeLabelsByStepId = require_workflow_event_processor.getResumeLabelsByStepId; exports.getSingleStepEntryId = require_workflow_event_processor.getSingleStepEntryId; exports.getStepIds = require_workflow_event_processor.getStepIds; exports.getStepResult = require_workflow_event_processor.getStepResult; exports.getWorkflowResumeLabel = getWorkflowResumeLabel; exports.getWorkflowResumeLabels = getWorkflowResumeLabels; exports.getWorkflowStepOutput = getWorkflowStepOutput; exports.getWorkflowStepPayload = getWorkflowStepPayload; exports.getWorkflowSuspendedStep = getWorkflowSuspendedStep; exports.getWorkflowSuspendedSteps = getWorkflowSuspendedSteps; exports.hydrateSerializedStepErrors = require_workflow_event_processor.hydrateSerializedStepErrors; exports.inferGraphSchemas = require_validate.inferGraphSchemas; exports.isProcessor = require_agent.isProcessor; exports.isSingleStepEntry = require_workflow_event_processor.isSingleStepEntry; exports.jsonSchemaToZod = require_validate.jsonSchemaToZod; exports.mapVariable = require_agent.mapVariable; exports.parseMapConfig = require_validate.parseMapConfig; exports.predicateSchema = require_agent.predicateSchema; exports.predicateToCondition = require_agent.predicateToCondition; exports.rehydrateWorkflow = require_validate.rehydrateWorkflow; exports.resolveForeachConcurrency = require_workflow_event_processor.resolveForeachConcurrency; exports.runCountDeprecationMessage = require_workflow_event_processor.runCountDeprecationMessage; exports.schemaCompatibility = require_validate.schemaCompatibility; exports.toJsonSchemaOrUndefined = require_validate.toJsonSchemaOrUndefined; exports.toStorableGraph = toStorableGraph; exports.validateCron = require_cron.validateCron; exports.validateStepInput = require_workflow_event_processor.validateStepInput; exports.validateStepRequestContext = require_workflow_event_processor.validateStepRequestContext; exports.validateStepResumeData = require_workflow_event_processor.validateStepResumeData; exports.validateStepStateData = require_workflow_event_processor.validateStepStateData; exports.validateStepSuspendData = require_workflow_event_processor.validateStepSuspendData; exports.validateStorableJsonSchema = require_validate.validateStorableJsonSchema; exports.validateStoredWorkflow = require_validate.validateStoredWorkflow; exports.validateWorkflowRefs = require_validate.validateWorkflowRefs; exports.validateWorkflowSchemas = require_validate.validateWorkflowSchemas; exports.validateWorkflowStructure = require_validate.validateWorkflowStructure; exports.waitForSuspendedSnapshot = require_workflow_event_processor.waitForSuspendedSnapshot; //# sourceMappingURL=index.cjs.map