@mastra/core 1.1.0 → 1.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +74 -0
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/index.cjs +8 -8
- package/dist/agent/index.js +1 -1
- package/dist/{chunk-RYVRCT7Z.cjs → chunk-22EV7GMK.cjs} +55 -19
- package/dist/chunk-22EV7GMK.cjs.map +1 -0
- package/dist/chunk-2QXNHEDL.js +8 -0
- package/dist/chunk-2QXNHEDL.js.map +1 -0
- package/dist/{chunk-OSIE5L6N.js → chunk-66BWIF4S.js} +7 -7
- package/dist/{chunk-OSIE5L6N.js.map → chunk-66BWIF4S.js.map} +1 -1
- package/dist/{chunk-IDDFKLI7.js → chunk-AC63Y6KP.js} +865 -1471
- package/dist/chunk-AC63Y6KP.js.map +1 -0
- package/dist/{chunk-4QJBNJI4.cjs → chunk-BLXWTBLL.cjs} +168 -168
- package/dist/{chunk-4QJBNJI4.cjs.map → chunk-BLXWTBLL.cjs.map} +1 -1
- package/dist/{chunk-KPIJA2R5.js → chunk-CILDTRXD.js} +2 -2
- package/dist/{chunk-KPIJA2R5.js.map → chunk-CILDTRXD.js.map} +1 -1
- package/dist/{chunk-OW7H7G5N.js → chunk-DWD5DB6W.js} +4 -4
- package/dist/{chunk-OW7H7G5N.js.map → chunk-DWD5DB6W.js.map} +1 -1
- package/dist/{chunk-MGOFRL36.cjs → chunk-EYUXOOSQ.cjs} +106 -39
- package/dist/chunk-EYUXOOSQ.cjs.map +1 -0
- package/dist/{chunk-FVVQY6UU.js → chunk-FAJYC6PA.js} +375 -23
- package/dist/chunk-FAJYC6PA.js.map +1 -0
- package/dist/{chunk-YQMDMIP6.js → chunk-FYMM4PKR.js} +1337 -312
- package/dist/chunk-FYMM4PKR.js.map +1 -0
- package/dist/{chunk-FAM74XPO.js → chunk-G6E3QNJC.js} +3741 -2912
- package/dist/chunk-G6E3QNJC.js.map +1 -0
- package/dist/{chunk-YSFYUEEG.cjs → chunk-I6PWV32C.cjs} +42 -10
- package/dist/chunk-I6PWV32C.cjs.map +1 -0
- package/dist/{chunk-VNGQXHUE.cjs → chunk-MCI7M6AT.cjs} +7 -7
- package/dist/{chunk-VNGQXHUE.cjs.map → chunk-MCI7M6AT.cjs.map} +1 -1
- package/dist/{chunk-4KQEQ4NM.js → chunk-NS33UC72.js} +55 -20
- package/dist/chunk-NS33UC72.js.map +1 -0
- package/dist/{chunk-4PERRFZD.cjs → chunk-OAOMKZXU.cjs} +1378 -353
- package/dist/chunk-OAOMKZXU.cjs.map +1 -0
- package/dist/{chunk-4ACKGMN2.cjs → chunk-ODNSWEMV.cjs} +7 -7
- package/dist/{chunk-4ACKGMN2.cjs.map → chunk-ODNSWEMV.cjs.map} +1 -1
- package/dist/{chunk-H4C5NORS.js → chunk-OQPAOUDS.js} +36 -5
- package/dist/chunk-OQPAOUDS.js.map +1 -0
- package/dist/{chunk-VAJRNUEF.js → chunk-SPVI7HCP.js} +76 -76
- package/dist/chunk-SPVI7HCP.js.map +1 -0
- package/dist/{chunk-ENLG644T.cjs → chunk-STNSGW7W.cjs} +1514 -2120
- package/dist/chunk-STNSGW7W.cjs.map +1 -0
- package/dist/{chunk-FZZI2V2T.js → chunk-USHB3SPM.js} +4 -4
- package/dist/{chunk-FZZI2V2T.js.map → chunk-USHB3SPM.js.map} +1 -1
- package/dist/{chunk-4NGQR4ML.cjs → chunk-UZL4H5P2.cjs} +5092 -4247
- package/dist/chunk-UZL4H5P2.cjs.map +1 -0
- package/dist/{chunk-DOVI2C5F.cjs → chunk-VZXYBFCX.cjs} +8 -8
- package/dist/{chunk-DOVI2C5F.cjs.map → chunk-VZXYBFCX.cjs.map} +1 -1
- package/dist/{chunk-4FUG3CNY.js → chunk-W3AQUG66.js} +3 -3
- package/dist/{chunk-4FUG3CNY.js.map → chunk-W3AQUG66.js.map} +1 -1
- package/dist/{chunk-SLMSUZBA.cjs → chunk-W57QS6F6.cjs} +400 -46
- package/dist/chunk-W57QS6F6.cjs.map +1 -0
- package/dist/{chunk-BG6DCMO2.js → chunk-XS2MED4Y.js} +105 -38
- package/dist/chunk-XS2MED4Y.js.map +1 -0
- package/dist/{chunk-HR67B4UM.cjs → chunk-XVHK5IAO.cjs} +15 -15
- package/dist/{chunk-HR67B4UM.cjs.map → chunk-XVHK5IAO.cjs.map} +1 -1
- package/dist/{chunk-RIPKI7ON.cjs → chunk-Y2SVKUOQ.cjs} +2 -2
- package/dist/{chunk-RIPKI7ON.cjs.map → chunk-Y2SVKUOQ.cjs.map} +1 -1
- package/dist/{chunk-LJOQ7WYC.cjs → chunk-ZCBG4ZQT.cjs} +4 -2
- package/dist/chunk-ZCBG4ZQT.cjs.map +1 -0
- package/dist/docs/README.md +2 -2
- package/dist/docs/SKILL.md +3 -3
- package/dist/docs/SOURCE_MAP.json +280 -270
- package/dist/docs/agents/01-overview.md +6 -2
- package/dist/docs/agents/02-using-tools.md +1 -0
- package/dist/docs/agents/06-processors.md +87 -1
- package/dist/docs/evals/01-overview.md +5 -5
- package/dist/docs/mcp/01-overview.md +2 -2
- package/dist/docs/observability/01-overview.md +1 -1
- package/dist/docs/observability/03-overview.md +3 -3
- package/dist/docs/processors/01-reference.md +100 -1
- package/dist/docs/rag/01-overview.md +1 -1
- package/dist/docs/rag/03-vector-databases.md +10 -1
- package/dist/docs/server/04-request-context.md +168 -0
- package/dist/docs/tools-mcp/01-mcp-overview.md +2 -2
- package/dist/docs/voice/01-overview.md +1 -1
- package/dist/docs/workflows/01-overview.md +9 -5
- package/dist/docs/workspace/01-overview.md +38 -31
- package/dist/docs/workspace/02-filesystem.md +9 -11
- package/dist/docs/workspace/03-sandbox.md +8 -10
- package/dist/docs/workspace/04-skills.md +24 -25
- package/dist/docs/workspace/05-search.md +34 -31
- package/dist/docs/workspace/06-reference.md +24 -149
- package/dist/evals/index.cjs +20 -20
- package/dist/evals/index.js +3 -3
- package/dist/evals/scoreTraces/index.cjs +5 -5
- package/dist/evals/scoreTraces/index.js +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.js +1 -1
- package/dist/llm/index.cjs +15 -15
- package/dist/llm/index.js +5 -5
- package/dist/llm/model/gateways/models-dev.d.ts.map +1 -1
- package/dist/llm/model/provider-types.generated.d.ts +44 -15
- package/dist/loop/index.cjs +12 -12
- package/dist/loop/index.js +1 -1
- package/dist/loop/network/index.d.ts.map +1 -1
- package/dist/mastra/index.cjs +2 -2
- package/dist/mastra/index.js +1 -1
- package/dist/memory/index.cjs +11 -11
- package/dist/memory/index.js +1 -1
- package/dist/memory/memory.d.ts +6 -0
- package/dist/memory/memory.d.ts.map +1 -1
- package/dist/models-dev-2HBSVUOS.js +3 -0
- package/dist/{models-dev-B2ESSYRH.js.map → models-dev-2HBSVUOS.js.map} +1 -1
- package/dist/models-dev-SOIECXXQ.cjs +12 -0
- package/dist/{models-dev-IQ54YHQ4.cjs.map → models-dev-SOIECXXQ.cjs.map} +1 -1
- package/dist/netlify-SSWMYSAX.js +3 -0
- package/dist/{netlify-KPCOQ52P.js.map → netlify-SSWMYSAX.js.map} +1 -1
- package/dist/netlify-TXZZCT6N.cjs +12 -0
- package/dist/{netlify-D6LNGTDH.cjs.map → netlify-TXZZCT6N.cjs.map} +1 -1
- package/dist/processors/index.cjs +44 -40
- package/dist/processors/index.js +1 -1
- package/dist/processors/processors/index.d.ts +1 -0
- package/dist/processors/processors/index.d.ts.map +1 -1
- package/dist/processors/processors/tool-search.d.ts +176 -0
- package/dist/processors/processors/tool-search.d.ts.map +1 -0
- package/dist/provider-registry-K5L4DHRK.js +3 -0
- package/dist/{provider-registry-B3CGX3OF.js.map → provider-registry-K5L4DHRK.js.map} +1 -1
- package/dist/provider-registry-ML2VWWLB.cjs +40 -0
- package/dist/{provider-registry-CHV3DFFA.cjs.map → provider-registry-ML2VWWLB.cjs.map} +1 -1
- package/dist/provider-registry.json +101 -34
- package/dist/relevance/index.cjs +3 -3
- package/dist/relevance/index.js +1 -1
- package/dist/storage/constants.cjs +16 -16
- package/dist/storage/constants.js +1 -1
- package/dist/storage/domains/workflows/inmemory.d.ts.map +1 -1
- package/dist/storage/index.cjs +101 -101
- package/dist/storage/index.js +2 -2
- package/dist/storage/types.d.ts +4 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/stream/aisdk/v5/compat/prepare-tools.d.ts.map +1 -1
- package/dist/stream/index.cjs +8 -8
- package/dist/stream/index.js +1 -1
- package/dist/tool-loop-agent/index.cjs +4 -4
- package/dist/tool-loop-agent/index.js +1 -1
- package/dist/vector/index.cjs +7 -7
- package/dist/vector/index.js +1 -1
- package/dist/workflows/constants.cjs +7 -3
- package/dist/workflows/constants.d.ts +1 -0
- package/dist/workflows/constants.d.ts.map +1 -1
- package/dist/workflows/constants.js +1 -1
- package/dist/workflows/default.d.ts.map +1 -1
- package/dist/workflows/evented/execution-engine.d.ts +8 -1
- package/dist/workflows/evented/execution-engine.d.ts.map +1 -1
- package/dist/workflows/evented/helpers.d.ts +68 -0
- package/dist/workflows/evented/helpers.d.ts.map +1 -0
- package/dist/workflows/evented/index.cjs +10 -10
- package/dist/workflows/evented/index.js +1 -1
- package/dist/workflows/evented/step-executor.d.ts +9 -17
- package/dist/workflows/evented/step-executor.d.ts.map +1 -1
- package/dist/workflows/evented/types.d.ts +29 -0
- package/dist/workflows/evented/types.d.ts.map +1 -0
- package/dist/workflows/evented/workflow-event-processor/index.d.ts +12 -3
- package/dist/workflows/evented/workflow-event-processor/index.d.ts.map +1 -1
- package/dist/workflows/evented/workflow-event-processor/loop.d.ts +2 -2
- package/dist/workflows/evented/workflow-event-processor/loop.d.ts.map +1 -1
- package/dist/workflows/evented/workflow-event-processor/parallel.d.ts +2 -2
- package/dist/workflows/evented/workflow-event-processor/parallel.d.ts.map +1 -1
- package/dist/workflows/evented/workflow-event-processor/sleep.d.ts.map +1 -1
- package/dist/workflows/evented/workflow-event-processor/utils.d.ts.map +1 -1
- package/dist/workflows/evented/workflow.d.ts +54 -3
- package/dist/workflows/evented/workflow.d.ts.map +1 -1
- package/dist/workflows/index.cjs +28 -24
- package/dist/workflows/index.js +1 -1
- package/dist/workflows/utils.d.ts +27 -0
- package/dist/workflows/utils.d.ts.map +1 -1
- package/dist/workflows/workflow.d.ts.map +1 -1
- package/dist/workspace/filesystem/local-filesystem.d.ts +3 -0
- package/dist/workspace/filesystem/local-filesystem.d.ts.map +1 -1
- package/dist/workspace/index.cjs +32 -32
- package/dist/workspace/index.js +1 -1
- package/dist/workspace/lifecycle.d.ts +2 -0
- package/dist/workspace/lifecycle.d.ts.map +1 -1
- package/dist/workspace/sandbox/local-sandbox.d.ts +1 -2
- package/dist/workspace/sandbox/local-sandbox.d.ts.map +1 -1
- package/dist/workspace/sandbox/sandbox.d.ts +0 -2
- package/dist/workspace/sandbox/sandbox.d.ts.map +1 -1
- package/dist/workspace/search/bm25.d.ts +2 -0
- package/dist/workspace/search/bm25.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/llm/model/provider-types.generated.d.ts +44 -15
- package/dist/chunk-4KQEQ4NM.js.map +0 -1
- package/dist/chunk-4NGQR4ML.cjs.map +0 -1
- package/dist/chunk-4PERRFZD.cjs.map +0 -1
- package/dist/chunk-BG6DCMO2.js.map +0 -1
- package/dist/chunk-ENLG644T.cjs.map +0 -1
- package/dist/chunk-FAM74XPO.js.map +0 -1
- package/dist/chunk-FVVQY6UU.js.map +0 -1
- package/dist/chunk-H4C5NORS.js.map +0 -1
- package/dist/chunk-IDDFKLI7.js.map +0 -1
- package/dist/chunk-LJOQ7WYC.cjs.map +0 -1
- package/dist/chunk-MGOFRL36.cjs.map +0 -1
- package/dist/chunk-RYVRCT7Z.cjs.map +0 -1
- package/dist/chunk-SLMSUZBA.cjs.map +0 -1
- package/dist/chunk-VAJRNUEF.js.map +0 -1
- package/dist/chunk-YEQB4VUA.js +0 -7
- package/dist/chunk-YEQB4VUA.js.map +0 -1
- package/dist/chunk-YQMDMIP6.js.map +0 -1
- package/dist/chunk-YSFYUEEG.cjs.map +0 -1
- package/dist/models-dev-B2ESSYRH.js +0 -3
- package/dist/models-dev-IQ54YHQ4.cjs +0 -12
- package/dist/netlify-D6LNGTDH.cjs +0 -12
- package/dist/netlify-KPCOQ52P.js +0 -3
- package/dist/provider-registry-B3CGX3OF.js +0 -3
- package/dist/provider-registry-CHV3DFFA.cjs +0 -40
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import { validateStepInput, createDeprecationProxy,
|
|
2
|
-
import { STREAM_FORMAT_SYMBOL, PUBSUB_SYMBOL } from './chunk-
|
|
1
|
+
import { validateStepInput, createDeprecationProxy, getStepResult, validateStepSuspendData, runCountDeprecationMessage, TripWire, createTimeTravelExecutionParams, validateStepResumeData, Workflow, isSupportedLanguageModel, ProcessorStepOutputSchema, ProcessorStepSchema, Run, WorkflowRunOutput, ExecutionEngine, cleanStepResult, hydrateSerializedStepErrors, Agent, ProcessorRunner } from './chunk-FAJYC6PA.js';
|
|
2
|
+
import { STREAM_FORMAT_SYMBOL, PUBSUB_SYMBOL } from './chunk-2QXNHEDL.js';
|
|
3
|
+
import { createPendingMarker } from './chunk-OQPAOUDS.js';
|
|
3
4
|
import { MessageList } from './chunk-HIP5W3LZ.js';
|
|
4
5
|
import { getErrorFromUnknown, MastraError } from './chunk-FJEVLHJT.js';
|
|
6
|
+
import { ToolStream } from './chunk-DD2VNRQM.js';
|
|
5
7
|
import { Tool } from './chunk-IW3BNL7A.js';
|
|
6
8
|
import { RequestContext } from './chunk-CCLV5CAA.js';
|
|
7
9
|
import { MastraBase } from './chunk-JIT2OY3X.js';
|
|
8
10
|
import { RegisteredLogger } from './chunk-X2WMFSPB.js';
|
|
9
|
-
import EventEmitter from 'events';
|
|
10
11
|
import { randomUUID } from 'crypto';
|
|
12
|
+
import { ReadableStream } from 'stream/web';
|
|
11
13
|
import { z } from 'zod';
|
|
14
|
+
import EventEmitter from 'events';
|
|
12
15
|
|
|
13
16
|
var StepExecutor = class extends MastraBase {
|
|
14
17
|
mastra;
|
|
@@ -19,6 +22,26 @@ var StepExecutor = class extends MastraBase {
|
|
|
19
22
|
__registerMastra(mastra) {
|
|
20
23
|
this.mastra = mastra;
|
|
21
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Creates an output writer function that publishes chunks to the workflow event stream.
|
|
27
|
+
* @param runId - The workflow run ID
|
|
28
|
+
* @returns An async function that writes chunks to the pubsub
|
|
29
|
+
*/
|
|
30
|
+
createOutputWriter(runId) {
|
|
31
|
+
return async (chunk) => {
|
|
32
|
+
try {
|
|
33
|
+
if (this.mastra?.pubsub) {
|
|
34
|
+
await this.mastra.pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
35
|
+
type: "watch",
|
|
36
|
+
runId,
|
|
37
|
+
data: chunk
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
} catch (err) {
|
|
41
|
+
this.logger.debug("Failed to publish workflow watch event", { runId, error: err });
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
22
45
|
async execute(params) {
|
|
23
46
|
const { step, stepResults, runId, requestContext, retryCount = 0, perStep } = params;
|
|
24
47
|
const abortController = params.abortController ?? new AbortController();
|
|
@@ -36,9 +59,12 @@ var StepExecutor = class extends MastraBase {
|
|
|
36
59
|
payload: (typeof params.foreachIdx === "number" ? params.input : inputData) ?? {}
|
|
37
60
|
};
|
|
38
61
|
if (params.resumeData) {
|
|
39
|
-
delete stepInfo.suspendPayload?.["__workflow_meta"];
|
|
40
62
|
stepInfo.resumePayload = params.resumeData;
|
|
41
63
|
stepInfo.resumedAt = Date.now();
|
|
64
|
+
if (stepInfo.suspendPayload && "__workflow_meta" in stepInfo.suspendPayload) {
|
|
65
|
+
const { __workflow_meta, ...userSuspendPayload } = stepInfo.suspendPayload;
|
|
66
|
+
stepInfo.suspendPayload = userSuspendPayload;
|
|
67
|
+
}
|
|
42
68
|
}
|
|
43
69
|
let suspendDataToUse = params.stepResults[step.id]?.status === "suspended" ? params.stepResults[step.id]?.suspendPayload : void 0;
|
|
44
70
|
if (suspendDataToUse && "__workflow_meta" in suspendDataToUse) {
|
|
@@ -49,6 +75,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
49
75
|
if (validationError) {
|
|
50
76
|
throw validationError;
|
|
51
77
|
}
|
|
78
|
+
const callId = randomUUID();
|
|
79
|
+
const outputWriter = this.createOutputWriter(runId);
|
|
52
80
|
const stepOutput = await step.execute(
|
|
53
81
|
createDeprecationProxy(
|
|
54
82
|
{
|
|
@@ -58,15 +86,15 @@ var StepExecutor = class extends MastraBase {
|
|
|
58
86
|
requestContext,
|
|
59
87
|
inputData,
|
|
60
88
|
state: params.state,
|
|
61
|
-
setState: async (
|
|
62
|
-
params.state
|
|
89
|
+
setState: async (newState) => {
|
|
90
|
+
Object.assign(params.state, newState);
|
|
63
91
|
},
|
|
64
92
|
retryCount,
|
|
65
93
|
resumeData: params.resumeData,
|
|
66
94
|
suspendData: suspendDataToUse,
|
|
67
95
|
getInitData: () => stepResults?.input,
|
|
68
96
|
getStepResult: getStepResult.bind(this, stepResults),
|
|
69
|
-
suspend: async (suspendPayload) => {
|
|
97
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
70
98
|
const { suspendData, validationError: validationError2 } = await validateStepSuspendData({
|
|
71
99
|
suspendData: suspendPayload,
|
|
72
100
|
step,
|
|
@@ -75,17 +103,44 @@ var StepExecutor = class extends MastraBase {
|
|
|
75
103
|
if (validationError2) {
|
|
76
104
|
throw validationError2;
|
|
77
105
|
}
|
|
78
|
-
|
|
106
|
+
const resumeLabels = {};
|
|
107
|
+
if (suspendOptions?.resumeLabel) {
|
|
108
|
+
const labels = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
109
|
+
for (const label of labels) {
|
|
110
|
+
resumeLabels[label] = {
|
|
111
|
+
stepId: step.id,
|
|
112
|
+
foreachIndex: params.foreachIdx
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
suspended = {
|
|
117
|
+
payload: {
|
|
118
|
+
...suspendData,
|
|
119
|
+
__workflow_meta: {
|
|
120
|
+
runId,
|
|
121
|
+
path: [step.id],
|
|
122
|
+
foreachIndex: params.foreachIdx,
|
|
123
|
+
resumeLabels: Object.keys(resumeLabels).length > 0 ? resumeLabels : void 0
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
79
127
|
},
|
|
80
128
|
bail: (result) => {
|
|
81
129
|
bailed = { payload: result };
|
|
82
130
|
},
|
|
83
|
-
|
|
84
|
-
|
|
131
|
+
writer: new ToolStream(
|
|
132
|
+
{
|
|
133
|
+
prefix: "workflow-step",
|
|
134
|
+
callId,
|
|
135
|
+
name: step.id,
|
|
136
|
+
runId
|
|
137
|
+
},
|
|
138
|
+
outputWriter
|
|
139
|
+
),
|
|
85
140
|
abort: () => {
|
|
86
141
|
abortController?.abort();
|
|
87
142
|
},
|
|
88
|
-
[PUBSUB_SYMBOL]: this.mastra
|
|
143
|
+
[PUBSUB_SYMBOL]: this.mastra.pubsub,
|
|
89
144
|
[STREAM_FORMAT_SYMBOL]: void 0,
|
|
90
145
|
// TODO
|
|
91
146
|
engine: {},
|
|
@@ -109,7 +164,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
109
164
|
...stepInfo,
|
|
110
165
|
status: "suspended",
|
|
111
166
|
suspendedAt: endedAt,
|
|
112
|
-
...stepOutput ? { suspendOutput: stepOutput } : {}
|
|
167
|
+
...stepOutput ? { suspendOutput: stepOutput } : {},
|
|
168
|
+
__state: params.state
|
|
113
169
|
};
|
|
114
170
|
if (suspended.payload) {
|
|
115
171
|
finalResult.suspendPayload = suspended.payload;
|
|
@@ -120,19 +176,22 @@ var StepExecutor = class extends MastraBase {
|
|
|
120
176
|
// @ts-expect-error - bailed status not in type
|
|
121
177
|
status: "bailed",
|
|
122
178
|
endedAt,
|
|
123
|
-
output: bailed.payload
|
|
179
|
+
output: bailed.payload,
|
|
180
|
+
__state: params.state
|
|
124
181
|
};
|
|
125
182
|
} else if (nestedWflowStepPaused) {
|
|
126
183
|
finalResult = {
|
|
127
184
|
...stepInfo,
|
|
128
|
-
status: "paused"
|
|
185
|
+
status: "paused",
|
|
186
|
+
__state: params.state
|
|
129
187
|
};
|
|
130
188
|
} else {
|
|
131
189
|
finalResult = {
|
|
132
190
|
...stepInfo,
|
|
133
191
|
status: "success",
|
|
134
192
|
endedAt,
|
|
135
|
-
output: stepOutput
|
|
193
|
+
output: stepOutput,
|
|
194
|
+
__state: params.state
|
|
136
195
|
};
|
|
137
196
|
}
|
|
138
197
|
return finalResult;
|
|
@@ -146,14 +205,22 @@ var StepExecutor = class extends MastraBase {
|
|
|
146
205
|
...stepInfo,
|
|
147
206
|
status: "failed",
|
|
148
207
|
endedAt,
|
|
149
|
-
error: errorInstance
|
|
208
|
+
error: errorInstance,
|
|
209
|
+
// Preserve TripWire data as plain object for proper serialization
|
|
210
|
+
// Important: Check `error` not `errorInstance` because getErrorFromUnknown
|
|
211
|
+
// converts the error and loses the prototype chain
|
|
212
|
+
tripwire: error instanceof TripWire ? {
|
|
213
|
+
reason: error.message,
|
|
214
|
+
retry: error.options?.retry,
|
|
215
|
+
metadata: error.options?.metadata,
|
|
216
|
+
processorId: error.processorId
|
|
217
|
+
} : void 0
|
|
150
218
|
};
|
|
151
219
|
}
|
|
152
220
|
}
|
|
153
221
|
async evaluateConditions(params) {
|
|
154
222
|
const { step, stepResults, runId, requestContext, retryCount = 0 } = params;
|
|
155
223
|
const abortController = params.abortController ?? new AbortController();
|
|
156
|
-
const ee = new EventEmitter();
|
|
157
224
|
const results = await Promise.all(
|
|
158
225
|
step.conditions.map((condition) => {
|
|
159
226
|
try {
|
|
@@ -168,7 +235,6 @@ var StepExecutor = class extends MastraBase {
|
|
|
168
235
|
resumeData: params.resumeData,
|
|
169
236
|
abortController,
|
|
170
237
|
stepResults,
|
|
171
|
-
emitter: ee,
|
|
172
238
|
iterationCount: 0
|
|
173
239
|
});
|
|
174
240
|
} catch (e) {
|
|
@@ -194,11 +260,12 @@ var StepExecutor = class extends MastraBase {
|
|
|
194
260
|
stepResults,
|
|
195
261
|
state,
|
|
196
262
|
requestContext,
|
|
197
|
-
emitter,
|
|
198
263
|
abortController,
|
|
199
264
|
retryCount = 0,
|
|
200
265
|
iterationCount
|
|
201
266
|
}) {
|
|
267
|
+
const callId = randomUUID();
|
|
268
|
+
const outputWriter = this.createOutputWriter(runId);
|
|
202
269
|
return condition(
|
|
203
270
|
createDeprecationProxy(
|
|
204
271
|
{
|
|
@@ -215,12 +282,19 @@ var StepExecutor = class extends MastraBase {
|
|
|
215
282
|
bail: (_result) => {
|
|
216
283
|
throw new Error("Not implemented");
|
|
217
284
|
},
|
|
218
|
-
|
|
219
|
-
|
|
285
|
+
writer: new ToolStream(
|
|
286
|
+
{
|
|
287
|
+
prefix: "workflow-step",
|
|
288
|
+
callId,
|
|
289
|
+
name: "condition",
|
|
290
|
+
runId
|
|
291
|
+
},
|
|
292
|
+
outputWriter
|
|
293
|
+
),
|
|
220
294
|
abort: () => {
|
|
221
295
|
abortController?.abort();
|
|
222
296
|
},
|
|
223
|
-
[PUBSUB_SYMBOL]: this.mastra
|
|
297
|
+
[PUBSUB_SYMBOL]: this.mastra.pubsub,
|
|
224
298
|
[STREAM_FORMAT_SYMBOL]: void 0,
|
|
225
299
|
// TODO
|
|
226
300
|
engine: {},
|
|
@@ -239,8 +313,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
239
313
|
}
|
|
240
314
|
async resolveSleep(params) {
|
|
241
315
|
const { step, stepResults, runId, requestContext, retryCount = 0 } = params;
|
|
316
|
+
const currentState = params.state ?? stepResults?.__state ?? {};
|
|
242
317
|
const abortController = params.abortController ?? new AbortController();
|
|
243
|
-
const ee = new EventEmitter();
|
|
244
318
|
if (step.duration) {
|
|
245
319
|
return step.duration;
|
|
246
320
|
}
|
|
@@ -248,6 +322,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
248
322
|
return 0;
|
|
249
323
|
}
|
|
250
324
|
try {
|
|
325
|
+
const callId = randomUUID();
|
|
326
|
+
const outputWriter = this.createOutputWriter(runId);
|
|
251
327
|
return await step.fn(
|
|
252
328
|
createDeprecationProxy(
|
|
253
329
|
{
|
|
@@ -256,9 +332,9 @@ var StepExecutor = class extends MastraBase {
|
|
|
256
332
|
mastra: this.mastra,
|
|
257
333
|
requestContext,
|
|
258
334
|
inputData: params.input,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
335
|
+
state: currentState,
|
|
336
|
+
setState: async (newState) => {
|
|
337
|
+
Object.assign(currentState, newState);
|
|
262
338
|
},
|
|
263
339
|
retryCount,
|
|
264
340
|
resumeData: params.resumeData,
|
|
@@ -273,9 +349,16 @@ var StepExecutor = class extends MastraBase {
|
|
|
273
349
|
abort: () => {
|
|
274
350
|
abortController?.abort();
|
|
275
351
|
},
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
352
|
+
writer: new ToolStream(
|
|
353
|
+
{
|
|
354
|
+
prefix: "workflow-step",
|
|
355
|
+
callId,
|
|
356
|
+
name: step.id,
|
|
357
|
+
runId
|
|
358
|
+
},
|
|
359
|
+
outputWriter
|
|
360
|
+
),
|
|
361
|
+
[PUBSUB_SYMBOL]: this.mastra.pubsub,
|
|
279
362
|
[STREAM_FORMAT_SYMBOL]: void 0,
|
|
280
363
|
// TODO
|
|
281
364
|
engine: {},
|
|
@@ -297,8 +380,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
297
380
|
}
|
|
298
381
|
async resolveSleepUntil(params) {
|
|
299
382
|
const { step, stepResults, runId, requestContext, retryCount = 0 } = params;
|
|
383
|
+
const currentState = params.state ?? stepResults?.__state ?? {};
|
|
300
384
|
const abortController = params.abortController ?? new AbortController();
|
|
301
|
-
const ee = new EventEmitter();
|
|
302
385
|
if (step.date) {
|
|
303
386
|
return step.date.getTime() - Date.now();
|
|
304
387
|
}
|
|
@@ -306,6 +389,8 @@ var StepExecutor = class extends MastraBase {
|
|
|
306
389
|
return 0;
|
|
307
390
|
}
|
|
308
391
|
try {
|
|
392
|
+
const callId = randomUUID();
|
|
393
|
+
const outputWriter = this.createOutputWriter(runId);
|
|
309
394
|
const result = await step.fn(
|
|
310
395
|
createDeprecationProxy(
|
|
311
396
|
{
|
|
@@ -314,9 +399,9 @@ var StepExecutor = class extends MastraBase {
|
|
|
314
399
|
mastra: this.mastra,
|
|
315
400
|
requestContext,
|
|
316
401
|
inputData: params.input,
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
402
|
+
state: currentState,
|
|
403
|
+
setState: async (newState) => {
|
|
404
|
+
Object.assign(currentState, newState);
|
|
320
405
|
},
|
|
321
406
|
retryCount,
|
|
322
407
|
resumeData: params.resumeData,
|
|
@@ -331,9 +416,16 @@ var StepExecutor = class extends MastraBase {
|
|
|
331
416
|
abort: () => {
|
|
332
417
|
abortController?.abort();
|
|
333
418
|
},
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
419
|
+
writer: new ToolStream(
|
|
420
|
+
{
|
|
421
|
+
prefix: "workflow-step",
|
|
422
|
+
callId,
|
|
423
|
+
name: step.id,
|
|
424
|
+
runId
|
|
425
|
+
},
|
|
426
|
+
outputWriter
|
|
427
|
+
),
|
|
428
|
+
[PUBSUB_SYMBOL]: this.mastra.pubsub,
|
|
337
429
|
[STREAM_FORMAT_SYMBOL]: void 0,
|
|
338
430
|
// TODO
|
|
339
431
|
engine: {},
|
|
@@ -356,6 +448,32 @@ var StepExecutor = class extends MastraBase {
|
|
|
356
448
|
}
|
|
357
449
|
};
|
|
358
450
|
|
|
451
|
+
// src/workflows/evented/helpers.ts
|
|
452
|
+
function isTripwireChunk(chunk) {
|
|
453
|
+
return chunk !== null && typeof chunk === "object" && "type" in chunk && chunk.type === "tripwire" && "payload" in chunk;
|
|
454
|
+
}
|
|
455
|
+
function createTripWireFromChunk(chunk) {
|
|
456
|
+
const { payload } = chunk;
|
|
457
|
+
return new TripWire(
|
|
458
|
+
payload.reason || "Agent tripwire triggered",
|
|
459
|
+
{
|
|
460
|
+
retry: payload.retry,
|
|
461
|
+
metadata: payload.metadata
|
|
462
|
+
},
|
|
463
|
+
payload.processorId
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
function getTextDeltaFromChunk(chunk, isV2Model) {
|
|
467
|
+
if (chunk.type !== "text-delta") {
|
|
468
|
+
return void 0;
|
|
469
|
+
}
|
|
470
|
+
return isV2Model ? chunk.payload?.text : chunk.textDelta;
|
|
471
|
+
}
|
|
472
|
+
function resolveCurrentState(params) {
|
|
473
|
+
const { stepResult, stepResults, state } = params;
|
|
474
|
+
return stepResult?.__state ?? stepResults?.__state ?? state ?? {};
|
|
475
|
+
}
|
|
476
|
+
|
|
359
477
|
// src/events/processor.ts
|
|
360
478
|
var EventProcessor = class {
|
|
361
479
|
mastra;
|
|
@@ -366,6 +484,8 @@ var EventProcessor = class {
|
|
|
366
484
|
this.mastra = mastra;
|
|
367
485
|
}
|
|
368
486
|
};
|
|
487
|
+
|
|
488
|
+
// src/workflows/evented/workflow-event-processor/loop.ts
|
|
369
489
|
async function processWorkflowLoop({
|
|
370
490
|
workflowId,
|
|
371
491
|
prevResult,
|
|
@@ -378,30 +498,31 @@ async function processWorkflowLoop({
|
|
|
378
498
|
parentWorkflow,
|
|
379
499
|
requestContext,
|
|
380
500
|
retryCount = 0,
|
|
381
|
-
perStep
|
|
501
|
+
perStep,
|
|
502
|
+
state,
|
|
503
|
+
outputOptions
|
|
382
504
|
}, {
|
|
383
505
|
pubsub,
|
|
384
506
|
stepExecutor,
|
|
385
507
|
step,
|
|
386
508
|
stepResult
|
|
387
509
|
}) {
|
|
510
|
+
const currentState = resolveCurrentState({ stepResult, stepResults, state });
|
|
511
|
+
const reqContext = new RequestContext(Object.entries(requestContext ?? {}));
|
|
512
|
+
const prevIterationCount = stepResults[step.step?.id]?.metadata?.iterationCount ?? 0;
|
|
513
|
+
const iterationCount = prevIterationCount + 1;
|
|
388
514
|
const loopCondition = await stepExecutor.evaluateCondition({
|
|
389
515
|
workflowId,
|
|
390
516
|
condition: step.condition,
|
|
391
517
|
runId,
|
|
392
518
|
stepResults,
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
emitter: new EventEmitter(),
|
|
396
|
-
// TODO
|
|
397
|
-
requestContext: new RequestContext(),
|
|
398
|
-
// TODO
|
|
519
|
+
state: currentState,
|
|
520
|
+
requestContext: reqContext,
|
|
399
521
|
inputData: prevResult?.status === "success" ? prevResult.output : void 0,
|
|
400
522
|
resumeData,
|
|
401
523
|
abortController: new AbortController(),
|
|
402
524
|
retryCount,
|
|
403
|
-
iterationCount
|
|
404
|
-
//TODO: implement
|
|
525
|
+
iterationCount
|
|
405
526
|
});
|
|
406
527
|
if (step.loopType === "dountil") {
|
|
407
528
|
if (loopCondition) {
|
|
@@ -419,7 +540,9 @@ async function processWorkflowLoop({
|
|
|
419
540
|
resumeData,
|
|
420
541
|
activeSteps,
|
|
421
542
|
requestContext,
|
|
422
|
-
perStep
|
|
543
|
+
perStep,
|
|
544
|
+
state: currentState,
|
|
545
|
+
outputOptions
|
|
423
546
|
}
|
|
424
547
|
});
|
|
425
548
|
} else {
|
|
@@ -433,6 +556,8 @@ async function processWorkflowLoop({
|
|
|
433
556
|
executionPath,
|
|
434
557
|
resumeSteps,
|
|
435
558
|
stepResults,
|
|
559
|
+
state: currentState,
|
|
560
|
+
outputOptions,
|
|
436
561
|
prevResult: stepResult,
|
|
437
562
|
resumeData,
|
|
438
563
|
activeSteps,
|
|
@@ -459,7 +584,9 @@ async function processWorkflowLoop({
|
|
|
459
584
|
activeSteps,
|
|
460
585
|
requestContext,
|
|
461
586
|
retryCount,
|
|
462
|
-
perStep
|
|
587
|
+
perStep,
|
|
588
|
+
state: currentState,
|
|
589
|
+
outputOptions
|
|
463
590
|
}
|
|
464
591
|
});
|
|
465
592
|
} else {
|
|
@@ -477,7 +604,9 @@ async function processWorkflowLoop({
|
|
|
477
604
|
resumeData,
|
|
478
605
|
activeSteps,
|
|
479
606
|
requestContext,
|
|
480
|
-
perStep
|
|
607
|
+
perStep,
|
|
608
|
+
state: currentState,
|
|
609
|
+
outputOptions
|
|
481
610
|
}
|
|
482
611
|
});
|
|
483
612
|
}
|
|
@@ -495,15 +624,180 @@ async function processWorkflowForEach({
|
|
|
495
624
|
resumeData,
|
|
496
625
|
parentWorkflow,
|
|
497
626
|
requestContext,
|
|
498
|
-
perStep
|
|
627
|
+
perStep,
|
|
628
|
+
state,
|
|
629
|
+
outputOptions,
|
|
630
|
+
forEachIndex
|
|
499
631
|
}, {
|
|
500
632
|
pubsub,
|
|
501
633
|
mastra,
|
|
502
634
|
step
|
|
503
635
|
}) {
|
|
636
|
+
const currentState = resolveCurrentState({ stepResults, state });
|
|
504
637
|
const currentResult = stepResults[step.step.id];
|
|
505
638
|
const idx = currentResult?.output?.length ?? 0;
|
|
506
639
|
const targetLen = prevResult?.output?.length ?? 0;
|
|
640
|
+
if (forEachIndex !== void 0 && resumeSteps?.length > 0 && idx > 0) {
|
|
641
|
+
const outputArray = currentResult?.output;
|
|
642
|
+
const outputLength = Array.isArray(outputArray) ? outputArray.length : 0;
|
|
643
|
+
if (!Array.isArray(outputArray) || forEachIndex < 0 || forEachIndex >= outputLength) {
|
|
644
|
+
const error = new Error(
|
|
645
|
+
`Invalid forEachIndex ${forEachIndex} for forEach resume: expected index in range [0, ${outputLength - 1}] but output array has length ${outputLength}`
|
|
646
|
+
);
|
|
647
|
+
await pubsub.publish("workflows", {
|
|
648
|
+
type: "workflow.fail",
|
|
649
|
+
runId,
|
|
650
|
+
data: {
|
|
651
|
+
parentWorkflow,
|
|
652
|
+
workflowId,
|
|
653
|
+
runId,
|
|
654
|
+
executionPath,
|
|
655
|
+
resumeSteps,
|
|
656
|
+
stepResults,
|
|
657
|
+
prevResult: { status: "failed", error },
|
|
658
|
+
activeSteps,
|
|
659
|
+
requestContext,
|
|
660
|
+
state: currentState,
|
|
661
|
+
outputOptions
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
const iterationResult = currentResult?.output?.[forEachIndex];
|
|
667
|
+
if (iterationResult?.status === "suspended" || iterationResult === null) {
|
|
668
|
+
const isNestedWorkflow2 = step.step.component === "WORKFLOW";
|
|
669
|
+
const targetArray2 = prevResult?.output;
|
|
670
|
+
const iterationPrevResult2 = isNestedWorkflow2 && prevResult.status === "success" && Array.isArray(targetArray2) ? { status: "success", output: targetArray2[forEachIndex] } : prevResult;
|
|
671
|
+
await pubsub.publish("workflows", {
|
|
672
|
+
type: "workflow.step.run",
|
|
673
|
+
runId,
|
|
674
|
+
data: {
|
|
675
|
+
parentWorkflow,
|
|
676
|
+
workflowId,
|
|
677
|
+
runId,
|
|
678
|
+
executionPath: [executionPath[0], forEachIndex],
|
|
679
|
+
resumeSteps,
|
|
680
|
+
timeTravel,
|
|
681
|
+
stepResults,
|
|
682
|
+
prevResult: iterationPrevResult2,
|
|
683
|
+
resumeData,
|
|
684
|
+
activeSteps,
|
|
685
|
+
requestContext,
|
|
686
|
+
perStep,
|
|
687
|
+
state: currentState,
|
|
688
|
+
outputOptions
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
return;
|
|
692
|
+
}
|
|
693
|
+
const pendingIterations = currentResult.output.filter((r) => r === null || r?.status === "suspended");
|
|
694
|
+
if (pendingIterations.length > 0) {
|
|
695
|
+
const collectedResumeLabels = {};
|
|
696
|
+
for (let i = 0; i < currentResult.output.length; i++) {
|
|
697
|
+
const iterResult = currentResult.output[i];
|
|
698
|
+
if (iterResult?.status === "suspended" && iterResult.suspendPayload?.__workflow_meta?.resumeLabels) {
|
|
699
|
+
Object.assign(collectedResumeLabels, iterResult.suspendPayload.__workflow_meta.resumeLabels);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
const suspendMeta = {
|
|
703
|
+
foreachIndex: forEachIndex
|
|
704
|
+
};
|
|
705
|
+
if (Object.keys(collectedResumeLabels).length > 0) {
|
|
706
|
+
suspendMeta.resumeLabels = collectedResumeLabels;
|
|
707
|
+
}
|
|
708
|
+
await pubsub.publish("workflows", {
|
|
709
|
+
type: "workflow.step.end",
|
|
710
|
+
runId,
|
|
711
|
+
data: {
|
|
712
|
+
parentWorkflow,
|
|
713
|
+
workflowId,
|
|
714
|
+
runId,
|
|
715
|
+
executionPath,
|
|
716
|
+
resumeSteps,
|
|
717
|
+
stepResults: {
|
|
718
|
+
...stepResults,
|
|
719
|
+
[step.step.id]: {
|
|
720
|
+
...currentResult,
|
|
721
|
+
status: "suspended",
|
|
722
|
+
suspendedAt: Date.now(),
|
|
723
|
+
suspendPayload: { __workflow_meta: suspendMeta }
|
|
724
|
+
}
|
|
725
|
+
},
|
|
726
|
+
prevResult: {
|
|
727
|
+
status: "suspended",
|
|
728
|
+
output: currentResult.output,
|
|
729
|
+
suspendPayload: { __workflow_meta: suspendMeta },
|
|
730
|
+
payload: currentResult.payload,
|
|
731
|
+
startedAt: currentResult.startedAt,
|
|
732
|
+
suspendedAt: Date.now()
|
|
733
|
+
},
|
|
734
|
+
activeSteps,
|
|
735
|
+
requestContext,
|
|
736
|
+
state: currentState,
|
|
737
|
+
outputOptions
|
|
738
|
+
}
|
|
739
|
+
});
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (resumeData !== void 0 && forEachIndex === void 0 && currentResult?.output?.length > 0) {
|
|
745
|
+
const suspendedIndices = [];
|
|
746
|
+
for (let i = 0; i < currentResult.output.length; i++) {
|
|
747
|
+
const iterResult = currentResult.output[i];
|
|
748
|
+
if (iterResult && typeof iterResult === "object" && iterResult.status === "suspended") {
|
|
749
|
+
suspendedIndices.push(i);
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
if (suspendedIndices.length > 0) {
|
|
753
|
+
const concurrency = step.opts.concurrency ?? 1;
|
|
754
|
+
const indicesToResume = suspendedIndices.slice(0, concurrency);
|
|
755
|
+
const workflowsStore2 = await mastra.getStorage()?.getStore("workflows");
|
|
756
|
+
const updatedOutput = [...currentResult.output];
|
|
757
|
+
for (const suspIdx of indicesToResume) {
|
|
758
|
+
updatedOutput[suspIdx] = createPendingMarker();
|
|
759
|
+
}
|
|
760
|
+
await workflowsStore2?.updateWorkflowResults({
|
|
761
|
+
workflowName: workflowId,
|
|
762
|
+
runId,
|
|
763
|
+
stepId: step.step.id,
|
|
764
|
+
result: {
|
|
765
|
+
...currentResult,
|
|
766
|
+
output: updatedOutput
|
|
767
|
+
},
|
|
768
|
+
requestContext
|
|
769
|
+
});
|
|
770
|
+
const isNestedWorkflow2 = step.step.component === "WORKFLOW";
|
|
771
|
+
for (const suspIdx of indicesToResume) {
|
|
772
|
+
const targetArray2 = prevResult?.output;
|
|
773
|
+
const iterationPrevResult2 = isNestedWorkflow2 && prevResult.status === "success" && Array.isArray(targetArray2) ? { status: "success", output: targetArray2[suspIdx] } : prevResult;
|
|
774
|
+
try {
|
|
775
|
+
await pubsub.publish("workflows", {
|
|
776
|
+
type: "workflow.step.run",
|
|
777
|
+
runId,
|
|
778
|
+
data: {
|
|
779
|
+
parentWorkflow,
|
|
780
|
+
workflowId,
|
|
781
|
+
runId,
|
|
782
|
+
executionPath: [executionPath[0], suspIdx],
|
|
783
|
+
resumeSteps,
|
|
784
|
+
timeTravel,
|
|
785
|
+
stepResults,
|
|
786
|
+
prevResult: iterationPrevResult2,
|
|
787
|
+
resumeData,
|
|
788
|
+
activeSteps,
|
|
789
|
+
requestContext,
|
|
790
|
+
perStep,
|
|
791
|
+
state: currentState,
|
|
792
|
+
outputOptions
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
} catch {
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
return;
|
|
799
|
+
}
|
|
800
|
+
}
|
|
507
801
|
if (idx >= targetLen && currentResult.output.filter((r) => r !== null).length >= targetLen) {
|
|
508
802
|
await pubsub.publish("workflows", {
|
|
509
803
|
type: "workflow.step.run",
|
|
@@ -517,10 +811,13 @@ async function processWorkflowForEach({
|
|
|
517
811
|
stepResults,
|
|
518
812
|
timeTravel,
|
|
519
813
|
prevResult: currentResult,
|
|
520
|
-
resumeData,
|
|
814
|
+
resumeData: void 0,
|
|
815
|
+
// No resumeData when advancing past foreach
|
|
521
816
|
activeSteps,
|
|
522
817
|
requestContext,
|
|
523
|
-
perStep
|
|
818
|
+
perStep,
|
|
819
|
+
state: currentState,
|
|
820
|
+
outputOptions
|
|
524
821
|
}
|
|
525
822
|
});
|
|
526
823
|
return;
|
|
@@ -543,7 +840,10 @@ async function processWorkflowForEach({
|
|
|
543
840
|
},
|
|
544
841
|
requestContext
|
|
545
842
|
});
|
|
843
|
+
const isNestedWorkflow2 = step.step.component === "WORKFLOW";
|
|
546
844
|
for (let i = 0; i < concurrency; i++) {
|
|
845
|
+
const targetArray2 = prevResult?.output;
|
|
846
|
+
const iterationPrevResult2 = isNestedWorkflow2 && prevResult.status === "success" && Array.isArray(targetArray2) ? { status: "success", output: targetArray2[i] } : prevResult;
|
|
547
847
|
await pubsub.publish("workflows", {
|
|
548
848
|
type: "workflow.step.run",
|
|
549
849
|
runId,
|
|
@@ -555,11 +855,13 @@ async function processWorkflowForEach({
|
|
|
555
855
|
resumeSteps,
|
|
556
856
|
stepResults,
|
|
557
857
|
timeTravel,
|
|
558
|
-
prevResult,
|
|
858
|
+
prevResult: iterationPrevResult2,
|
|
559
859
|
resumeData,
|
|
560
860
|
activeSteps,
|
|
561
861
|
requestContext,
|
|
562
|
-
perStep
|
|
862
|
+
perStep,
|
|
863
|
+
state: currentState,
|
|
864
|
+
outputOptions
|
|
563
865
|
}
|
|
564
866
|
});
|
|
565
867
|
}
|
|
@@ -578,6 +880,9 @@ async function processWorkflowForEach({
|
|
|
578
880
|
},
|
|
579
881
|
requestContext
|
|
580
882
|
});
|
|
883
|
+
const isNestedWorkflow = step.step.component === "WORKFLOW";
|
|
884
|
+
const targetArray = prevResult?.output;
|
|
885
|
+
const iterationPrevResult = isNestedWorkflow && prevResult.status === "success" && Array.isArray(targetArray) ? { status: "success", output: targetArray[idx] } : prevResult;
|
|
581
886
|
await pubsub.publish("workflows", {
|
|
582
887
|
type: "workflow.step.run",
|
|
583
888
|
runId,
|
|
@@ -589,14 +894,18 @@ async function processWorkflowForEach({
|
|
|
589
894
|
resumeSteps,
|
|
590
895
|
timeTravel,
|
|
591
896
|
stepResults,
|
|
592
|
-
prevResult,
|
|
897
|
+
prevResult: iterationPrevResult,
|
|
593
898
|
resumeData,
|
|
594
899
|
activeSteps,
|
|
595
900
|
requestContext,
|
|
596
|
-
perStep
|
|
901
|
+
perStep,
|
|
902
|
+
state: currentState,
|
|
903
|
+
outputOptions
|
|
597
904
|
}
|
|
598
905
|
});
|
|
599
906
|
}
|
|
907
|
+
|
|
908
|
+
// src/workflows/evented/workflow-event-processor/parallel.ts
|
|
600
909
|
async function processWorkflowParallel({
|
|
601
910
|
workflowId,
|
|
602
911
|
runId,
|
|
@@ -609,11 +918,14 @@ async function processWorkflowParallel({
|
|
|
609
918
|
resumeData,
|
|
610
919
|
parentWorkflow,
|
|
611
920
|
requestContext,
|
|
612
|
-
perStep
|
|
921
|
+
perStep,
|
|
922
|
+
state,
|
|
923
|
+
outputOptions
|
|
613
924
|
}, {
|
|
614
925
|
pubsub,
|
|
615
926
|
step
|
|
616
927
|
}) {
|
|
928
|
+
const currentState = resolveCurrentState({ stepResults, state });
|
|
617
929
|
for (let i = 0; i < step.steps.length; i++) {
|
|
618
930
|
const nestedStep = step.steps[i];
|
|
619
931
|
if (nestedStep?.type === "step") {
|
|
@@ -640,7 +952,9 @@ async function processWorkflowParallel({
|
|
|
640
952
|
parentWorkflow,
|
|
641
953
|
activeSteps,
|
|
642
954
|
requestContext,
|
|
643
|
-
perStep
|
|
955
|
+
perStep,
|
|
956
|
+
state: currentState,
|
|
957
|
+
outputOptions
|
|
644
958
|
}
|
|
645
959
|
});
|
|
646
960
|
})
|
|
@@ -658,23 +972,23 @@ async function processWorkflowConditional({
|
|
|
658
972
|
resumeData,
|
|
659
973
|
parentWorkflow,
|
|
660
974
|
requestContext,
|
|
661
|
-
perStep
|
|
975
|
+
perStep,
|
|
976
|
+
state,
|
|
977
|
+
outputOptions
|
|
662
978
|
}, {
|
|
663
979
|
pubsub,
|
|
664
980
|
stepExecutor,
|
|
665
981
|
step
|
|
666
982
|
}) {
|
|
983
|
+
const currentState = resolveCurrentState({ stepResults, state });
|
|
984
|
+
const reqContext = new RequestContext(Object.entries(requestContext ?? {}));
|
|
667
985
|
const idxs = await stepExecutor.evaluateConditions({
|
|
668
986
|
workflowId,
|
|
669
987
|
step,
|
|
670
988
|
runId,
|
|
671
989
|
stepResults,
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
emitter: new EventEmitter(),
|
|
675
|
-
// TODO
|
|
676
|
-
requestContext: new RequestContext(),
|
|
677
|
-
// TODO
|
|
990
|
+
state: currentState,
|
|
991
|
+
requestContext: reqContext,
|
|
678
992
|
input: prevResult?.status === "success" ? prevResult.output : void 0,
|
|
679
993
|
resumeData
|
|
680
994
|
});
|
|
@@ -705,7 +1019,9 @@ async function processWorkflowConditional({
|
|
|
705
1019
|
parentWorkflow,
|
|
706
1020
|
activeSteps,
|
|
707
1021
|
requestContext,
|
|
708
|
-
perStep
|
|
1022
|
+
perStep,
|
|
1023
|
+
state: currentState,
|
|
1024
|
+
outputOptions
|
|
709
1025
|
}
|
|
710
1026
|
});
|
|
711
1027
|
} else {
|
|
@@ -730,7 +1046,9 @@ async function processWorkflowConditional({
|
|
|
730
1046
|
parentWorkflow,
|
|
731
1047
|
activeSteps,
|
|
732
1048
|
requestContext,
|
|
733
|
-
perStep
|
|
1049
|
+
perStep,
|
|
1050
|
+
state: currentState,
|
|
1051
|
+
outputOptions
|
|
734
1052
|
}
|
|
735
1053
|
});
|
|
736
1054
|
} else {
|
|
@@ -748,7 +1066,9 @@ async function processWorkflowConditional({
|
|
|
748
1066
|
parentWorkflow,
|
|
749
1067
|
activeSteps,
|
|
750
1068
|
requestContext,
|
|
751
|
-
perStep
|
|
1069
|
+
perStep,
|
|
1070
|
+
state: currentState,
|
|
1071
|
+
outputOptions
|
|
752
1072
|
}
|
|
753
1073
|
});
|
|
754
1074
|
}
|
|
@@ -756,6 +1076,8 @@ async function processWorkflowConditional({
|
|
|
756
1076
|
);
|
|
757
1077
|
}
|
|
758
1078
|
}
|
|
1079
|
+
|
|
1080
|
+
// src/workflows/evented/workflow-event-processor/sleep.ts
|
|
759
1081
|
async function processWorkflowWaitForEvent(workflowData, {
|
|
760
1082
|
pubsub,
|
|
761
1083
|
eventName,
|
|
@@ -820,15 +1142,13 @@ async function processWorkflowSleep({
|
|
|
820
1142
|
}
|
|
821
1143
|
}
|
|
822
1144
|
});
|
|
1145
|
+
const reqContext = new RequestContext(Object.entries(requestContext ?? {}));
|
|
823
1146
|
const duration = await stepExecutor.resolveSleep({
|
|
824
1147
|
workflowId,
|
|
825
1148
|
step,
|
|
826
1149
|
runId,
|
|
827
1150
|
stepResults,
|
|
828
|
-
|
|
829
|
-
// TODO
|
|
830
|
-
requestContext: new RequestContext(),
|
|
831
|
-
// TODO
|
|
1151
|
+
requestContext: reqContext,
|
|
832
1152
|
input: prevResult?.status === "success" ? prevResult.output : void 0,
|
|
833
1153
|
resumeData
|
|
834
1154
|
});
|
|
@@ -901,15 +1221,13 @@ async function processWorkflowSleepUntil({
|
|
|
901
1221
|
step
|
|
902
1222
|
}) {
|
|
903
1223
|
const startedAt = Date.now();
|
|
1224
|
+
const reqContext = new RequestContext(Object.entries(requestContext ?? {}));
|
|
904
1225
|
const duration = await stepExecutor.resolveSleepUntil({
|
|
905
1226
|
workflowId,
|
|
906
1227
|
step,
|
|
907
1228
|
runId,
|
|
908
1229
|
stepResults,
|
|
909
|
-
|
|
910
|
-
// TODO
|
|
911
|
-
requestContext: new RequestContext(),
|
|
912
|
-
// TODO
|
|
1230
|
+
requestContext: reqContext,
|
|
913
1231
|
input: prevResult?.status === "success" ? prevResult.output : void 0,
|
|
914
1232
|
resumeData
|
|
915
1233
|
});
|
|
@@ -1095,8 +1413,12 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1095
1413
|
executionPath,
|
|
1096
1414
|
stepResults,
|
|
1097
1415
|
requestContext,
|
|
1098
|
-
perStep
|
|
1416
|
+
perStep,
|
|
1417
|
+
state,
|
|
1418
|
+
outputOptions,
|
|
1419
|
+
forEachIndex
|
|
1099
1420
|
}) {
|
|
1421
|
+
const initialState = arguments[0].initialState ?? state ?? {};
|
|
1100
1422
|
this.getOrCreateAbortController(runId);
|
|
1101
1423
|
if (parentWorkflow?.runId) {
|
|
1102
1424
|
this.parentChildRelationships.set(runId, parentWorkflow.runId);
|
|
@@ -1104,26 +1426,35 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1104
1426
|
const workflowsStore = await this.mastra.getStorage()?.getStore("workflows");
|
|
1105
1427
|
const existingRun = await workflowsStore?.getWorkflowRunById({ runId, workflowName: workflow.id });
|
|
1106
1428
|
const resourceId = existingRun?.resourceId;
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
resumeLabels: {},
|
|
1115
|
-
waitingPaths: {},
|
|
1116
|
-
activeStepsPath: {},
|
|
1117
|
-
serializedStepGraph: workflow.serializedStepGraph,
|
|
1118
|
-
timestamp: Date.now(),
|
|
1429
|
+
const shouldPersist = workflow?.options?.shouldPersistSnapshot?.({
|
|
1430
|
+
stepResults: stepResults ?? {},
|
|
1431
|
+
workflowStatus: "running"
|
|
1432
|
+
}) ?? true;
|
|
1433
|
+
if (shouldPersist) {
|
|
1434
|
+
await workflowsStore?.persistWorkflowSnapshot({
|
|
1435
|
+
workflowName: workflow.id,
|
|
1119
1436
|
runId,
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1437
|
+
resourceId,
|
|
1438
|
+
snapshot: {
|
|
1439
|
+
activePaths: [],
|
|
1440
|
+
suspendedPaths: {},
|
|
1441
|
+
resumeLabels: {},
|
|
1442
|
+
waitingPaths: {},
|
|
1443
|
+
activeStepsPath: {},
|
|
1444
|
+
serializedStepGraph: workflow.serializedStepGraph,
|
|
1445
|
+
timestamp: Date.now(),
|
|
1446
|
+
runId,
|
|
1447
|
+
context: {
|
|
1448
|
+
...stepResults ?? {
|
|
1449
|
+
input: prevResult?.status === "success" ? prevResult.output : void 0
|
|
1450
|
+
},
|
|
1451
|
+
__state: initialState
|
|
1452
|
+
},
|
|
1453
|
+
status: "running",
|
|
1454
|
+
value: initialState
|
|
1455
|
+
}
|
|
1456
|
+
});
|
|
1457
|
+
}
|
|
1127
1458
|
await this.mastra.pubsub.publish("workflows", {
|
|
1128
1459
|
type: "workflow.step.run",
|
|
1129
1460
|
runId,
|
|
@@ -1133,29 +1464,42 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1133
1464
|
runId,
|
|
1134
1465
|
executionPath: executionPath ?? [0],
|
|
1135
1466
|
resumeSteps,
|
|
1136
|
-
stepResults:
|
|
1137
|
-
|
|
1467
|
+
stepResults: {
|
|
1468
|
+
...stepResults ?? {
|
|
1469
|
+
input: prevResult?.status === "success" ? prevResult.output : void 0
|
|
1470
|
+
},
|
|
1471
|
+
__state: initialState
|
|
1138
1472
|
},
|
|
1139
1473
|
prevResult,
|
|
1140
1474
|
timeTravel,
|
|
1141
1475
|
requestContext,
|
|
1142
1476
|
resumeData,
|
|
1143
1477
|
activeSteps: {},
|
|
1144
|
-
perStep
|
|
1478
|
+
perStep,
|
|
1479
|
+
state: initialState,
|
|
1480
|
+
outputOptions,
|
|
1481
|
+
forEachIndex
|
|
1145
1482
|
}
|
|
1146
1483
|
});
|
|
1147
1484
|
}
|
|
1148
1485
|
async endWorkflow(args, status = "success") {
|
|
1149
|
-
const { workflowId, runId, prevResult, perStep } = args;
|
|
1486
|
+
const { workflowId, runId, prevResult, perStep, workflow, stepResults } = args;
|
|
1150
1487
|
const workflowsStore = await this.mastra.getStorage()?.getStore("workflows");
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1488
|
+
const finalStatus = perStep && status === "success" ? "paused" : status;
|
|
1489
|
+
const shouldPersist = workflow?.options?.shouldPersistSnapshot?.({
|
|
1490
|
+
stepResults: stepResults ?? {},
|
|
1491
|
+
workflowStatus: finalStatus
|
|
1492
|
+
}) ?? true;
|
|
1493
|
+
if (shouldPersist) {
|
|
1494
|
+
await workflowsStore?.updateWorkflowState({
|
|
1495
|
+
workflowName: workflowId,
|
|
1496
|
+
runId,
|
|
1497
|
+
opts: {
|
|
1498
|
+
status: finalStatus,
|
|
1499
|
+
result: prevResult
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
}
|
|
1159
1503
|
if (perStep) {
|
|
1160
1504
|
await this.mastra.pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
1161
1505
|
type: "watch",
|
|
@@ -1192,13 +1536,16 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1192
1536
|
requestContext,
|
|
1193
1537
|
runId,
|
|
1194
1538
|
timeTravel,
|
|
1195
|
-
perStep
|
|
1196
|
-
|
|
1539
|
+
perStep,
|
|
1540
|
+
stepResults,
|
|
1541
|
+
state} = args;
|
|
1542
|
+
const finalState = resolveCurrentState({ stepResults, state });
|
|
1197
1543
|
this.cleanupRun(runId);
|
|
1198
1544
|
if (parentWorkflow) {
|
|
1199
1545
|
await this.mastra.pubsub.publish("workflows", {
|
|
1200
1546
|
type: "workflow.step.end",
|
|
1201
|
-
runId,
|
|
1547
|
+
runId: parentWorkflow.runId,
|
|
1548
|
+
// Use parent's runId for event routing
|
|
1202
1549
|
data: {
|
|
1203
1550
|
workflowId: parentWorkflow.workflowId,
|
|
1204
1551
|
runId: parentWorkflow.runId,
|
|
@@ -1212,22 +1559,39 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1212
1559
|
parentContext: parentWorkflow,
|
|
1213
1560
|
requestContext,
|
|
1214
1561
|
timeTravel,
|
|
1215
|
-
perStep
|
|
1562
|
+
perStep,
|
|
1563
|
+
state: finalState,
|
|
1564
|
+
nestedRunId: runId
|
|
1565
|
+
// Pass nested workflow's runId for step retrieval
|
|
1216
1566
|
}
|
|
1217
1567
|
});
|
|
1218
1568
|
}
|
|
1219
1569
|
await this.mastra.pubsub.publish("workflows-finish", {
|
|
1220
1570
|
type: "workflow.end",
|
|
1221
1571
|
runId,
|
|
1222
|
-
data: { ...args, workflow: void 0 }
|
|
1572
|
+
data: { ...args, workflow: void 0, state: finalState }
|
|
1223
1573
|
});
|
|
1224
1574
|
}
|
|
1225
1575
|
async processWorkflowSuspend(args) {
|
|
1226
|
-
const {
|
|
1576
|
+
const {
|
|
1577
|
+
resumeSteps,
|
|
1578
|
+
prevResult,
|
|
1579
|
+
resumeData,
|
|
1580
|
+
parentWorkflow,
|
|
1581
|
+
activeSteps,
|
|
1582
|
+
runId,
|
|
1583
|
+
requestContext,
|
|
1584
|
+
timeTravel,
|
|
1585
|
+
stepResults,
|
|
1586
|
+
state,
|
|
1587
|
+
outputOptions
|
|
1588
|
+
} = args;
|
|
1589
|
+
const finalState = resolveCurrentState({ stepResults, state });
|
|
1227
1590
|
if (parentWorkflow) {
|
|
1228
1591
|
await this.mastra.pubsub.publish("workflows", {
|
|
1229
1592
|
type: "workflow.step.end",
|
|
1230
|
-
runId,
|
|
1593
|
+
runId: parentWorkflow.runId,
|
|
1594
|
+
// Use parent's runId for event routing
|
|
1231
1595
|
data: {
|
|
1232
1596
|
workflowId: parentWorkflow.workflowId,
|
|
1233
1597
|
runId: parentWorkflow.runId,
|
|
@@ -1249,14 +1613,18 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1249
1613
|
activeSteps,
|
|
1250
1614
|
requestContext,
|
|
1251
1615
|
parentWorkflow: parentWorkflow.parentWorkflow,
|
|
1252
|
-
parentContext: parentWorkflow
|
|
1616
|
+
parentContext: parentWorkflow,
|
|
1617
|
+
state: finalState,
|
|
1618
|
+
outputOptions,
|
|
1619
|
+
nestedRunId: runId
|
|
1620
|
+
// Pass nested workflow's runId for step retrieval
|
|
1253
1621
|
}
|
|
1254
1622
|
});
|
|
1255
1623
|
}
|
|
1256
1624
|
await this.mastra.pubsub.publish("workflows-finish", {
|
|
1257
1625
|
type: "workflow.suspend",
|
|
1258
1626
|
runId,
|
|
1259
|
-
data: { ...args, workflow: void 0 }
|
|
1627
|
+
data: { ...args, workflow: void 0, state: finalState }
|
|
1260
1628
|
});
|
|
1261
1629
|
}
|
|
1262
1630
|
async processWorkflowFail(args) {
|
|
@@ -1269,22 +1637,34 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1269
1637
|
parentWorkflow,
|
|
1270
1638
|
activeSteps,
|
|
1271
1639
|
requestContext,
|
|
1272
|
-
timeTravel
|
|
1640
|
+
timeTravel,
|
|
1641
|
+
stepResults,
|
|
1642
|
+
state,
|
|
1643
|
+
outputOptions,
|
|
1644
|
+
workflow
|
|
1273
1645
|
} = args;
|
|
1646
|
+
const finalState = resolveCurrentState({ stepResults, state });
|
|
1274
1647
|
this.cleanupRun(runId);
|
|
1275
1648
|
const workflowsStore = await this.mastra.getStorage()?.getStore("workflows");
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1649
|
+
const shouldPersist = workflow?.options?.shouldPersistSnapshot?.({
|
|
1650
|
+
stepResults: stepResults ?? {},
|
|
1651
|
+
workflowStatus: "failed"
|
|
1652
|
+
}) ?? true;
|
|
1653
|
+
if (shouldPersist) {
|
|
1654
|
+
await workflowsStore?.updateWorkflowState({
|
|
1655
|
+
workflowName: workflowId,
|
|
1656
|
+
runId,
|
|
1657
|
+
opts: {
|
|
1658
|
+
status: "failed",
|
|
1659
|
+
error: prevResult.error
|
|
1660
|
+
}
|
|
1661
|
+
});
|
|
1662
|
+
}
|
|
1284
1663
|
if (parentWorkflow) {
|
|
1285
1664
|
await this.mastra.pubsub.publish("workflows", {
|
|
1286
1665
|
type: "workflow.step.end",
|
|
1287
|
-
runId,
|
|
1666
|
+
runId: parentWorkflow.runId,
|
|
1667
|
+
// Use parent's runId for event routing
|
|
1288
1668
|
data: {
|
|
1289
1669
|
workflowId: parentWorkflow.workflowId,
|
|
1290
1670
|
runId: parentWorkflow.runId,
|
|
@@ -1297,14 +1677,18 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1297
1677
|
activeSteps,
|
|
1298
1678
|
requestContext,
|
|
1299
1679
|
parentWorkflow: parentWorkflow.parentWorkflow,
|
|
1300
|
-
parentContext: parentWorkflow
|
|
1680
|
+
parentContext: parentWorkflow,
|
|
1681
|
+
state: finalState,
|
|
1682
|
+
outputOptions,
|
|
1683
|
+
nestedRunId: runId
|
|
1684
|
+
// Pass nested workflow's runId for step retrieval
|
|
1301
1685
|
}
|
|
1302
1686
|
});
|
|
1303
1687
|
}
|
|
1304
1688
|
await this.mastra.pubsub.publish("workflows-finish", {
|
|
1305
1689
|
type: "workflow.fail",
|
|
1306
1690
|
runId,
|
|
1307
|
-
data: { ...args, workflow: void 0 }
|
|
1691
|
+
data: { ...args, workflow: void 0, state: finalState }
|
|
1308
1692
|
});
|
|
1309
1693
|
}
|
|
1310
1694
|
async processWorkflowStepRun({
|
|
@@ -1321,8 +1705,12 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1321
1705
|
parentWorkflow,
|
|
1322
1706
|
requestContext,
|
|
1323
1707
|
retryCount = 0,
|
|
1324
|
-
perStep
|
|
1708
|
+
perStep,
|
|
1709
|
+
state,
|
|
1710
|
+
outputOptions,
|
|
1711
|
+
forEachIndex
|
|
1325
1712
|
}) {
|
|
1713
|
+
const currentState = resolveCurrentState({ stepResults, state });
|
|
1326
1714
|
let stepGraph = workflow.stepGraph;
|
|
1327
1715
|
if (!executionPath?.length) {
|
|
1328
1716
|
return this.errorWorkflow(
|
|
@@ -1348,6 +1736,24 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1348
1736
|
}
|
|
1349
1737
|
let step = stepGraph[executionPath[0]];
|
|
1350
1738
|
if (!step) {
|
|
1739
|
+
if (executionPath[0] >= stepGraph.length) {
|
|
1740
|
+
return this.endWorkflow({
|
|
1741
|
+
workflow,
|
|
1742
|
+
parentWorkflow,
|
|
1743
|
+
workflowId,
|
|
1744
|
+
runId,
|
|
1745
|
+
executionPath,
|
|
1746
|
+
resumeSteps,
|
|
1747
|
+
stepResults,
|
|
1748
|
+
prevResult,
|
|
1749
|
+
activeSteps,
|
|
1750
|
+
requestContext,
|
|
1751
|
+
// Use currentState (resolved from stepResults.__state and state) instead of
|
|
1752
|
+
// the possibly-undefined state parameter, to ensure final state is preserved
|
|
1753
|
+
state: currentState,
|
|
1754
|
+
outputOptions
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1351
1757
|
return this.errorWorkflow(
|
|
1352
1758
|
{
|
|
1353
1759
|
workflowId,
|
|
@@ -1385,7 +1791,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1385
1791
|
resumeData,
|
|
1386
1792
|
parentWorkflow,
|
|
1387
1793
|
requestContext,
|
|
1388
|
-
perStep
|
|
1794
|
+
perStep,
|
|
1795
|
+
state: currentState,
|
|
1796
|
+
outputOptions
|
|
1389
1797
|
},
|
|
1390
1798
|
{
|
|
1391
1799
|
pubsub: this.mastra.pubsub,
|
|
@@ -1406,7 +1814,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1406
1814
|
resumeData,
|
|
1407
1815
|
parentWorkflow,
|
|
1408
1816
|
requestContext,
|
|
1409
|
-
perStep
|
|
1817
|
+
perStep,
|
|
1818
|
+
state: currentState,
|
|
1819
|
+
outputOptions
|
|
1410
1820
|
},
|
|
1411
1821
|
{
|
|
1412
1822
|
pubsub: this.mastra.pubsub,
|
|
@@ -1428,8 +1838,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1428
1838
|
resumeData,
|
|
1429
1839
|
parentWorkflow,
|
|
1430
1840
|
requestContext,
|
|
1431
|
-
perStep
|
|
1432
|
-
},
|
|
1841
|
+
perStep},
|
|
1433
1842
|
{
|
|
1434
1843
|
pubsub: this.mastra.pubsub,
|
|
1435
1844
|
stepExecutor: this.stepExecutor,
|
|
@@ -1450,8 +1859,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1450
1859
|
resumeData,
|
|
1451
1860
|
parentWorkflow,
|
|
1452
1861
|
requestContext,
|
|
1453
|
-
perStep
|
|
1454
|
-
},
|
|
1862
|
+
perStep},
|
|
1455
1863
|
{
|
|
1456
1864
|
pubsub: this.mastra.pubsub,
|
|
1457
1865
|
stepExecutor: this.stepExecutor,
|
|
@@ -1472,7 +1880,10 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1472
1880
|
resumeData,
|
|
1473
1881
|
parentWorkflow,
|
|
1474
1882
|
requestContext,
|
|
1475
|
-
perStep
|
|
1883
|
+
perStep,
|
|
1884
|
+
state: currentState,
|
|
1885
|
+
outputOptions,
|
|
1886
|
+
forEachIndex
|
|
1476
1887
|
},
|
|
1477
1888
|
{
|
|
1478
1889
|
pubsub: this.mastra.pubsub,
|
|
@@ -1505,7 +1916,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1505
1916
|
}
|
|
1506
1917
|
activeSteps[step.step.id] = true;
|
|
1507
1918
|
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
1508
|
-
if (step.step instanceof EventedWorkflow) {
|
|
1919
|
+
if (step.step instanceof EventedWorkflow || step.step.component === "WORKFLOW") {
|
|
1509
1920
|
if (resumeSteps?.length > 1) {
|
|
1510
1921
|
const stepData = stepResults[step.step.id];
|
|
1511
1922
|
const nestedRunId = stepData?.suspendPayload?.__workflow_meta?.runId;
|
|
@@ -1560,7 +1971,10 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1560
1971
|
resumeData,
|
|
1561
1972
|
activeSteps,
|
|
1562
1973
|
requestContext,
|
|
1563
|
-
perStep
|
|
1974
|
+
perStep,
|
|
1975
|
+
initialState: currentState,
|
|
1976
|
+
state: currentState,
|
|
1977
|
+
outputOptions
|
|
1564
1978
|
}
|
|
1565
1979
|
});
|
|
1566
1980
|
} else if (timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.step.id) {
|
|
@@ -1568,6 +1982,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1568
1982
|
workflowName: step.step.id,
|
|
1569
1983
|
runId
|
|
1570
1984
|
}) ?? { context: {} };
|
|
1985
|
+
const nestedWorkflow = step.step;
|
|
1571
1986
|
const timeTravelParams = createTimeTravelExecutionParams({
|
|
1572
1987
|
steps: timeTravel.steps.slice(1),
|
|
1573
1988
|
inputData: timeTravel.inputData,
|
|
@@ -1575,10 +1990,10 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1575
1990
|
context: timeTravel.nestedStepResults?.[step.step.id] ?? {},
|
|
1576
1991
|
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
1577
1992
|
snapshot,
|
|
1578
|
-
graph:
|
|
1993
|
+
graph: nestedWorkflow.buildExecutionGraph(),
|
|
1579
1994
|
perStep
|
|
1580
1995
|
});
|
|
1581
|
-
const nestedPrevStep = getStep(
|
|
1996
|
+
const nestedPrevStep = getStep(nestedWorkflow, timeTravelParams.executionPath);
|
|
1582
1997
|
const nestedPrevResult = timeTravelParams.stepResults[nestedPrevStep?.id ?? "input"];
|
|
1583
1998
|
await this.mastra.pubsub.publish("workflows", {
|
|
1584
1999
|
type: "workflow.start",
|
|
@@ -1603,7 +2018,10 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1603
2018
|
timeTravel: timeTravelParams,
|
|
1604
2019
|
activeSteps,
|
|
1605
2020
|
requestContext,
|
|
1606
|
-
perStep
|
|
2021
|
+
perStep,
|
|
2022
|
+
initialState: currentState,
|
|
2023
|
+
state: currentState,
|
|
2024
|
+
outputOptions
|
|
1607
2025
|
}
|
|
1608
2026
|
});
|
|
1609
2027
|
} else {
|
|
@@ -1629,7 +2047,10 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1629
2047
|
resumeData,
|
|
1630
2048
|
activeSteps,
|
|
1631
2049
|
requestContext,
|
|
1632
|
-
perStep
|
|
2050
|
+
perStep,
|
|
2051
|
+
initialState: currentState,
|
|
2052
|
+
state: currentState,
|
|
2053
|
+
outputOptions
|
|
1633
2054
|
}
|
|
1634
2055
|
});
|
|
1635
2056
|
}
|
|
@@ -1683,9 +2104,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1683
2104
|
step: step.step,
|
|
1684
2105
|
runId,
|
|
1685
2106
|
stepResults,
|
|
1686
|
-
|
|
1687
|
-
state: {},
|
|
1688
|
-
emitter: ee,
|
|
2107
|
+
state: currentState,
|
|
1689
2108
|
requestContext: rc,
|
|
1690
2109
|
input: prevResult?.output,
|
|
1691
2110
|
resumeData: resumeDataToUse,
|
|
@@ -1713,7 +2132,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1713
2132
|
prevResult: stepResult,
|
|
1714
2133
|
activeSteps,
|
|
1715
2134
|
requestContext,
|
|
1716
|
-
perStep
|
|
2135
|
+
perStep,
|
|
2136
|
+
state: currentState,
|
|
2137
|
+
outputOptions
|
|
1717
2138
|
});
|
|
1718
2139
|
return;
|
|
1719
2140
|
}
|
|
@@ -1732,7 +2153,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1732
2153
|
stepResults,
|
|
1733
2154
|
prevResult: stepResult,
|
|
1734
2155
|
activeSteps,
|
|
1735
|
-
requestContext
|
|
2156
|
+
requestContext,
|
|
2157
|
+
state: currentState,
|
|
2158
|
+
outputOptions
|
|
1736
2159
|
}
|
|
1737
2160
|
});
|
|
1738
2161
|
} else {
|
|
@@ -1750,7 +2173,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1750
2173
|
prevResult,
|
|
1751
2174
|
activeSteps,
|
|
1752
2175
|
requestContext,
|
|
1753
|
-
retryCount: retryCount + 1
|
|
2176
|
+
retryCount: retryCount + 1,
|
|
2177
|
+
state: currentState,
|
|
2178
|
+
outputOptions
|
|
1754
2179
|
}
|
|
1755
2180
|
});
|
|
1756
2181
|
}
|
|
@@ -1778,6 +2203,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1778
2203
|
}
|
|
1779
2204
|
);
|
|
1780
2205
|
} else {
|
|
2206
|
+
const updatedState = stepResult.__state ?? currentState;
|
|
1781
2207
|
await this.mastra.pubsub.publish("workflows", {
|
|
1782
2208
|
type: "workflow.step.end",
|
|
1783
2209
|
runId,
|
|
@@ -1789,11 +2215,17 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1789
2215
|
resumeSteps,
|
|
1790
2216
|
timeTravel,
|
|
1791
2217
|
//timeTravel is passed in as workflow.step.end ends the step, not the workflow, the timeTravel info is passed to the next step to run.
|
|
1792
|
-
stepResults
|
|
2218
|
+
stepResults: {
|
|
2219
|
+
...stepResults,
|
|
2220
|
+
__state: updatedState
|
|
2221
|
+
},
|
|
1793
2222
|
prevResult: stepResult,
|
|
1794
2223
|
activeSteps,
|
|
1795
2224
|
requestContext,
|
|
1796
|
-
perStep
|
|
2225
|
+
perStep,
|
|
2226
|
+
state: updatedState,
|
|
2227
|
+
outputOptions,
|
|
2228
|
+
forEachIndex
|
|
1797
2229
|
}
|
|
1798
2230
|
});
|
|
1799
2231
|
}
|
|
@@ -1811,8 +2243,15 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1811
2243
|
activeSteps,
|
|
1812
2244
|
parentContext,
|
|
1813
2245
|
requestContext,
|
|
1814
|
-
perStep
|
|
2246
|
+
perStep,
|
|
2247
|
+
state,
|
|
2248
|
+
outputOptions,
|
|
2249
|
+
forEachIndex,
|
|
2250
|
+
nestedRunId
|
|
1815
2251
|
}) {
|
|
2252
|
+
const currentState = parentContext ? state ?? prevResult?.__state ?? stepResults?.__state ?? {} : prevResult?.__state ?? stepResults?.__state ?? state ?? {};
|
|
2253
|
+
const { __state: _removedState, ...cleanPrevResult } = prevResult;
|
|
2254
|
+
prevResult = cleanPrevResult;
|
|
1816
2255
|
let step = workflow.stepGraph[executionPath[0]];
|
|
1817
2256
|
if ((step?.type === "parallel" || step?.type === "conditional") && executionPath.length > 1) {
|
|
1818
2257
|
step = step.steps[executionPath[1]];
|
|
@@ -1844,15 +2283,62 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1844
2283
|
runId
|
|
1845
2284
|
});
|
|
1846
2285
|
const currentIdx = executionPath[1];
|
|
1847
|
-
const
|
|
2286
|
+
const existingStepResult = snapshot?.context?.[step.step.id];
|
|
2287
|
+
const currentResult = existingStepResult?.output;
|
|
2288
|
+
const originalPayload = existingStepResult?.payload;
|
|
1848
2289
|
let newResult = prevResult;
|
|
1849
2290
|
if (currentIdx !== void 0) {
|
|
1850
|
-
if (
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
2291
|
+
if (prevResult.status === "bailed") {
|
|
2292
|
+
const bailedResult = {
|
|
2293
|
+
status: "success",
|
|
2294
|
+
output: prevResult.output,
|
|
2295
|
+
startedAt: existingStepResult?.startedAt ?? Date.now(),
|
|
2296
|
+
endedAt: Date.now(),
|
|
2297
|
+
payload: originalPayload
|
|
2298
|
+
};
|
|
2299
|
+
await workflowsStore?.updateWorkflowResults({
|
|
2300
|
+
workflowName: workflow.id,
|
|
2301
|
+
runId,
|
|
2302
|
+
stepId: step.step.id,
|
|
2303
|
+
result: bailedResult,
|
|
2304
|
+
requestContext
|
|
2305
|
+
});
|
|
2306
|
+
return this.endWorkflow({
|
|
2307
|
+
workflow,
|
|
2308
|
+
parentWorkflow,
|
|
2309
|
+
workflowId,
|
|
2310
|
+
runId,
|
|
2311
|
+
executionPath: [executionPath[0]],
|
|
2312
|
+
resumeSteps,
|
|
2313
|
+
stepResults: { ...stepResults, [step.step.id]: bailedResult },
|
|
2314
|
+
prevResult: bailedResult,
|
|
2315
|
+
activeSteps,
|
|
2316
|
+
requestContext,
|
|
2317
|
+
perStep,
|
|
2318
|
+
state: currentState,
|
|
2319
|
+
outputOptions
|
|
2320
|
+
});
|
|
2321
|
+
}
|
|
2322
|
+
const iterationResult = prevResult.status === "suspended" ? prevResult : prevResult.output;
|
|
2323
|
+
if (currentResult) {
|
|
2324
|
+
currentResult[currentIdx] = iterationResult;
|
|
2325
|
+
newResult = {
|
|
2326
|
+
...existingStepResult,
|
|
2327
|
+
// Preserve step-level properties
|
|
2328
|
+
...prevResult,
|
|
2329
|
+
// Get iteration timing info
|
|
2330
|
+
output: currentResult,
|
|
2331
|
+
payload: originalPayload,
|
|
2332
|
+
// Preserve suspend metadata from first suspension
|
|
2333
|
+
suspendPayload: existingStepResult?.suspendPayload ?? prevResult.suspendPayload,
|
|
2334
|
+
suspendedAt: existingStepResult?.suspendedAt ?? prevResult.suspendedAt,
|
|
2335
|
+
// Update resume metadata to most recent resume (new iteration takes precedence)
|
|
2336
|
+
resumePayload: prevResult.resumePayload ?? existingStepResult?.resumePayload,
|
|
2337
|
+
resumedAt: prevResult.resumedAt ?? existingStepResult?.resumedAt
|
|
2338
|
+
};
|
|
2339
|
+
} else {
|
|
2340
|
+
newResult = { ...prevResult, output: [iterationResult], payload: originalPayload };
|
|
2341
|
+
}
|
|
1856
2342
|
}
|
|
1857
2343
|
const newStepResults = await workflowsStore?.updateWorkflowResults({
|
|
1858
2344
|
workflowName: workflow.id,
|
|
@@ -1865,12 +2351,159 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1865
2351
|
return;
|
|
1866
2352
|
}
|
|
1867
2353
|
stepResults = newStepResults;
|
|
2354
|
+
if (currentIdx !== void 0) {
|
|
2355
|
+
const foreachResult = stepResults[step.step.id];
|
|
2356
|
+
const iterationResults = foreachResult?.output ?? [];
|
|
2357
|
+
const targetLen = foreachResult?.payload?.length ?? 0;
|
|
2358
|
+
const pendingCount = iterationResults.filter((r) => r === null).length;
|
|
2359
|
+
const suspendedCount = iterationResults.filter(
|
|
2360
|
+
(r) => r && typeof r === "object" && r.status === "suspended"
|
|
2361
|
+
).length;
|
|
2362
|
+
const iterationsStarted = iterationResults.length;
|
|
2363
|
+
if (pendingCount > 0) {
|
|
2364
|
+
return;
|
|
2365
|
+
}
|
|
2366
|
+
if (iterationsStarted < targetLen) {
|
|
2367
|
+
await processWorkflowForEach(
|
|
2368
|
+
{
|
|
2369
|
+
workflowId,
|
|
2370
|
+
prevResult: { status: "success", output: foreachResult.payload },
|
|
2371
|
+
runId,
|
|
2372
|
+
executionPath: [executionPath[0]],
|
|
2373
|
+
stepResults,
|
|
2374
|
+
activeSteps,
|
|
2375
|
+
resumeSteps,
|
|
2376
|
+
timeTravel,
|
|
2377
|
+
resumeData: void 0,
|
|
2378
|
+
// Don't pass resumeData when starting new iterations
|
|
2379
|
+
parentWorkflow,
|
|
2380
|
+
requestContext,
|
|
2381
|
+
perStep,
|
|
2382
|
+
state: currentState,
|
|
2383
|
+
outputOptions
|
|
2384
|
+
},
|
|
2385
|
+
{
|
|
2386
|
+
pubsub: this.mastra.pubsub,
|
|
2387
|
+
mastra: this.mastra,
|
|
2388
|
+
step
|
|
2389
|
+
}
|
|
2390
|
+
);
|
|
2391
|
+
return;
|
|
2392
|
+
}
|
|
2393
|
+
if (suspendedCount > 0) {
|
|
2394
|
+
const collectedResumeLabels = {};
|
|
2395
|
+
const suspendedPaths = {
|
|
2396
|
+
[step.step.id]: [executionPath[0]]
|
|
2397
|
+
};
|
|
2398
|
+
for (let i = 0; i < iterationResults.length; i++) {
|
|
2399
|
+
const iterResult = iterationResults[i];
|
|
2400
|
+
if (iterResult && typeof iterResult === "object" && iterResult.status === "suspended") {
|
|
2401
|
+
if (iterResult.suspendPayload?.__workflow_meta?.resumeLabels) {
|
|
2402
|
+
Object.assign(collectedResumeLabels, iterResult.suspendPayload.__workflow_meta.resumeLabels);
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
const foreachSuspendResult = {
|
|
2407
|
+
status: "suspended",
|
|
2408
|
+
output: iterationResults,
|
|
2409
|
+
payload: foreachResult.payload,
|
|
2410
|
+
suspendedAt: Date.now(),
|
|
2411
|
+
startedAt: foreachResult.startedAt,
|
|
2412
|
+
suspendPayload: {
|
|
2413
|
+
__workflow_meta: {
|
|
2414
|
+
path: executionPath,
|
|
2415
|
+
resumeLabels: collectedResumeLabels
|
|
2416
|
+
}
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
await workflowsStore?.updateWorkflowResults({
|
|
2420
|
+
workflowName: workflow.id,
|
|
2421
|
+
runId,
|
|
2422
|
+
stepId: step.step.id,
|
|
2423
|
+
result: foreachSuspendResult,
|
|
2424
|
+
requestContext
|
|
2425
|
+
});
|
|
2426
|
+
const shouldPersist = workflow?.options?.shouldPersistSnapshot?.({
|
|
2427
|
+
stepResults: stepResults ?? {},
|
|
2428
|
+
workflowStatus: "suspended"
|
|
2429
|
+
}) ?? true;
|
|
2430
|
+
if (shouldPersist) {
|
|
2431
|
+
await workflowsStore?.updateWorkflowResults({
|
|
2432
|
+
workflowName: workflow.id,
|
|
2433
|
+
runId,
|
|
2434
|
+
stepId: "__state",
|
|
2435
|
+
result: currentState,
|
|
2436
|
+
requestContext
|
|
2437
|
+
});
|
|
2438
|
+
await workflowsStore?.updateWorkflowState({
|
|
2439
|
+
workflowName: workflowId,
|
|
2440
|
+
runId,
|
|
2441
|
+
opts: {
|
|
2442
|
+
status: "suspended",
|
|
2443
|
+
result: foreachSuspendResult,
|
|
2444
|
+
suspendedPaths,
|
|
2445
|
+
resumeLabels: collectedResumeLabels
|
|
2446
|
+
}
|
|
2447
|
+
});
|
|
2448
|
+
}
|
|
2449
|
+
await this.mastra.pubsub.publish("workflows", {
|
|
2450
|
+
type: "workflow.suspend",
|
|
2451
|
+
runId,
|
|
2452
|
+
data: {
|
|
2453
|
+
workflowId,
|
|
2454
|
+
runId,
|
|
2455
|
+
executionPath: [executionPath[0]],
|
|
2456
|
+
resumeSteps,
|
|
2457
|
+
parentWorkflow,
|
|
2458
|
+
stepResults: { ...stepResults, [step.step.id]: foreachSuspendResult },
|
|
2459
|
+
prevResult: foreachSuspendResult,
|
|
2460
|
+
activeSteps,
|
|
2461
|
+
requestContext,
|
|
2462
|
+
timeTravel,
|
|
2463
|
+
state: currentState,
|
|
2464
|
+
outputOptions
|
|
2465
|
+
}
|
|
2466
|
+
});
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2469
|
+
await processWorkflowForEach(
|
|
2470
|
+
{
|
|
2471
|
+
workflowId,
|
|
2472
|
+
prevResult: { status: "success", output: foreachResult.payload },
|
|
2473
|
+
runId,
|
|
2474
|
+
executionPath: [executionPath[0]],
|
|
2475
|
+
stepResults,
|
|
2476
|
+
activeSteps,
|
|
2477
|
+
resumeSteps,
|
|
2478
|
+
timeTravel,
|
|
2479
|
+
resumeData: void 0,
|
|
2480
|
+
parentWorkflow,
|
|
2481
|
+
requestContext,
|
|
2482
|
+
perStep,
|
|
2483
|
+
state: currentState,
|
|
2484
|
+
outputOptions
|
|
2485
|
+
},
|
|
2486
|
+
{
|
|
2487
|
+
pubsub: this.mastra.pubsub,
|
|
2488
|
+
mastra: this.mastra,
|
|
2489
|
+
step
|
|
2490
|
+
}
|
|
2491
|
+
);
|
|
2492
|
+
return;
|
|
2493
|
+
}
|
|
1868
2494
|
} else if (isExecutableStep(step)) {
|
|
1869
2495
|
delete activeSteps[step.step.id];
|
|
1870
2496
|
if (parentContext) {
|
|
1871
2497
|
prevResult = stepResults[step.step.id] = {
|
|
1872
2498
|
...prevResult,
|
|
1873
|
-
payload: parentContext.input?.output ?? {}
|
|
2499
|
+
payload: parentContext.input?.output ?? {},
|
|
2500
|
+
// Store nestedRunId in metadata for getWorkflowRunById retrieval
|
|
2501
|
+
...nestedRunId && {
|
|
2502
|
+
metadata: {
|
|
2503
|
+
...prevResult.metadata,
|
|
2504
|
+
nestedRunId
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
1874
2507
|
};
|
|
1875
2508
|
}
|
|
1876
2509
|
const newStepResults = await workflowsStore?.updateWorkflowResults({
|
|
@@ -1885,6 +2518,7 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1885
2518
|
}
|
|
1886
2519
|
stepResults = newStepResults;
|
|
1887
2520
|
}
|
|
2521
|
+
stepResults = { ...stepResults, __state: currentState };
|
|
1888
2522
|
if (!prevResult?.status || prevResult.status === "failed") {
|
|
1889
2523
|
await this.mastra.pubsub.publish("workflows", {
|
|
1890
2524
|
type: "workflow.fail",
|
|
@@ -1899,7 +2533,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1899
2533
|
timeTravel,
|
|
1900
2534
|
prevResult,
|
|
1901
2535
|
activeSteps,
|
|
1902
|
-
requestContext
|
|
2536
|
+
requestContext,
|
|
2537
|
+
state: currentState,
|
|
2538
|
+
outputOptions
|
|
1903
2539
|
}
|
|
1904
2540
|
});
|
|
1905
2541
|
return;
|
|
@@ -1909,15 +2545,30 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1909
2545
|
if (suspendedStep) {
|
|
1910
2546
|
suspendedPaths[suspendedStep.id] = executionPath;
|
|
1911
2547
|
}
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
2548
|
+
const resumeLabels = prevResult.suspendPayload?.__workflow_meta?.resumeLabels ?? {};
|
|
2549
|
+
const shouldPersist = workflow?.options?.shouldPersistSnapshot?.({
|
|
2550
|
+
stepResults: stepResults ?? {},
|
|
2551
|
+
workflowStatus: "suspended"
|
|
2552
|
+
}) ?? true;
|
|
2553
|
+
if (shouldPersist) {
|
|
2554
|
+
await workflowsStore?.updateWorkflowResults({
|
|
2555
|
+
workflowName: workflow.id,
|
|
2556
|
+
runId,
|
|
2557
|
+
stepId: "__state",
|
|
2558
|
+
result: currentState,
|
|
2559
|
+
requestContext
|
|
2560
|
+
});
|
|
2561
|
+
await workflowsStore?.updateWorkflowState({
|
|
2562
|
+
workflowName: workflowId,
|
|
2563
|
+
runId,
|
|
2564
|
+
opts: {
|
|
2565
|
+
status: "suspended",
|
|
2566
|
+
result: prevResult,
|
|
2567
|
+
suspendedPaths,
|
|
2568
|
+
resumeLabels
|
|
2569
|
+
}
|
|
2570
|
+
});
|
|
2571
|
+
}
|
|
1921
2572
|
await this.mastra.pubsub.publish("workflows", {
|
|
1922
2573
|
type: "workflow.suspend",
|
|
1923
2574
|
runId,
|
|
@@ -1931,7 +2582,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
1931
2582
|
prevResult,
|
|
1932
2583
|
activeSteps,
|
|
1933
2584
|
requestContext,
|
|
1934
|
-
timeTravel
|
|
2585
|
+
timeTravel,
|
|
2586
|
+
state: currentState,
|
|
2587
|
+
outputOptions
|
|
1935
2588
|
}
|
|
1936
2589
|
});
|
|
1937
2590
|
await this.mastra.pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
@@ -2040,10 +2693,14 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
2040
2693
|
prevResult: { status: "success", output: allResults },
|
|
2041
2694
|
activeSteps,
|
|
2042
2695
|
requestContext,
|
|
2043
|
-
timeTravel
|
|
2696
|
+
timeTravel,
|
|
2697
|
+
state: currentState,
|
|
2698
|
+
outputOptions
|
|
2044
2699
|
}
|
|
2045
2700
|
});
|
|
2046
2701
|
} else if (step?.type === "foreach") {
|
|
2702
|
+
const foreachStepResult = stepResults[step.step.id];
|
|
2703
|
+
const originalArray = foreachStepResult?.payload;
|
|
2047
2704
|
await this.mastra.pubsub.publish("workflows", {
|
|
2048
2705
|
type: "workflow.step.run",
|
|
2049
2706
|
runId,
|
|
@@ -2054,10 +2711,13 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
2054
2711
|
resumeSteps,
|
|
2055
2712
|
parentWorkflow,
|
|
2056
2713
|
stepResults,
|
|
2057
|
-
prevResult: { ...prevResult, output:
|
|
2714
|
+
prevResult: { ...prevResult, output: originalArray },
|
|
2058
2715
|
activeSteps,
|
|
2059
2716
|
requestContext,
|
|
2060
|
-
timeTravel
|
|
2717
|
+
timeTravel,
|
|
2718
|
+
state: currentState,
|
|
2719
|
+
outputOptions,
|
|
2720
|
+
forEachIndex
|
|
2061
2721
|
}
|
|
2062
2722
|
});
|
|
2063
2723
|
} else if (executionPath[0] >= workflow.stepGraph.length - 1) {
|
|
@@ -2071,7 +2731,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
2071
2731
|
stepResults,
|
|
2072
2732
|
prevResult,
|
|
2073
2733
|
activeSteps,
|
|
2074
|
-
requestContext
|
|
2734
|
+
requestContext,
|
|
2735
|
+
state: currentState,
|
|
2736
|
+
outputOptions
|
|
2075
2737
|
});
|
|
2076
2738
|
} else {
|
|
2077
2739
|
await this.mastra.pubsub.publish("workflows", {
|
|
@@ -2087,7 +2749,9 @@ var WorkflowEventProcessor = class extends EventProcessor {
|
|
|
2087
2749
|
prevResult,
|
|
2088
2750
|
activeSteps,
|
|
2089
2751
|
requestContext,
|
|
2090
|
-
timeTravel
|
|
2752
|
+
timeTravel,
|
|
2753
|
+
state: currentState,
|
|
2754
|
+
outputOptions
|
|
2091
2755
|
}
|
|
2092
2756
|
});
|
|
2093
2757
|
}
|
|
@@ -2288,6 +2952,57 @@ function createStepFromParams(params) {
|
|
|
2288
2952
|
execute: params.execute.bind(params)
|
|
2289
2953
|
};
|
|
2290
2954
|
}
|
|
2955
|
+
async function processAgentStream(params) {
|
|
2956
|
+
const { fullStream, isV2Model, pubsub, runId, toolData, logger } = params;
|
|
2957
|
+
try {
|
|
2958
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
2959
|
+
type: "watch",
|
|
2960
|
+
runId,
|
|
2961
|
+
data: { type: "tool-call-streaming-start", ...toolData }
|
|
2962
|
+
});
|
|
2963
|
+
} catch (err) {
|
|
2964
|
+
logger?.debug("Failed to publish stream start event", { runId, error: err });
|
|
2965
|
+
}
|
|
2966
|
+
let tripwireChunk = null;
|
|
2967
|
+
for await (const chunk of fullStream) {
|
|
2968
|
+
if (isTripwireChunk(chunk)) {
|
|
2969
|
+
tripwireChunk = chunk;
|
|
2970
|
+
break;
|
|
2971
|
+
}
|
|
2972
|
+
if (typeof chunk === "object" && chunk !== null && "type" in chunk && chunk.type === "text-delta") {
|
|
2973
|
+
const textDelta = getTextDeltaFromChunk(chunk, isV2Model);
|
|
2974
|
+
if (textDelta) {
|
|
2975
|
+
try {
|
|
2976
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
2977
|
+
type: "watch",
|
|
2978
|
+
runId,
|
|
2979
|
+
data: { type: "tool-call-delta", ...toolData, argsTextDelta: textDelta }
|
|
2980
|
+
});
|
|
2981
|
+
} catch (err) {
|
|
2982
|
+
logger?.debug("Failed to publish stream delta event", { runId, error: err });
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
try {
|
|
2988
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
2989
|
+
type: "watch",
|
|
2990
|
+
runId,
|
|
2991
|
+
data: { type: "tool-call-streaming-finish", ...toolData }
|
|
2992
|
+
});
|
|
2993
|
+
} catch (err) {
|
|
2994
|
+
logger?.debug("Failed to publish stream finish event", { runId, error: err });
|
|
2995
|
+
}
|
|
2996
|
+
return { tripwireChunk };
|
|
2997
|
+
}
|
|
2998
|
+
async function safeOnFinish(callback, result, logger) {
|
|
2999
|
+
if (!callback) return;
|
|
3000
|
+
try {
|
|
3001
|
+
await callback(result);
|
|
3002
|
+
} catch (err) {
|
|
3003
|
+
logger?.warn("User onFinish callback threw an error", { error: err });
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
2291
3006
|
function createStepFromAgent(params, agentOrToolOptions) {
|
|
2292
3007
|
const options = agentOrToolOptions ?? {};
|
|
2293
3008
|
const outputSchema = options?.structuredOutput?.schema ?? z.object({ text: z.string() });
|
|
@@ -2304,54 +3019,80 @@ function createStepFromAgent(params, agentOrToolOptions) {
|
|
|
2304
3019
|
execute: async ({
|
|
2305
3020
|
inputData,
|
|
2306
3021
|
runId,
|
|
3022
|
+
mastra,
|
|
2307
3023
|
[PUBSUB_SYMBOL]: pubsub,
|
|
2308
3024
|
requestContext,
|
|
2309
3025
|
tracingContext,
|
|
2310
3026
|
abortSignal,
|
|
2311
3027
|
abort
|
|
2312
3028
|
}) => {
|
|
2313
|
-
|
|
2314
|
-
streamPromise.promise = new Promise((resolve, reject) => {
|
|
2315
|
-
streamPromise.resolve = resolve;
|
|
2316
|
-
streamPromise.reject = reject;
|
|
2317
|
-
});
|
|
2318
|
-
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
2319
|
-
...agentOptions ?? {},
|
|
2320
|
-
tracingContext,
|
|
2321
|
-
requestContext,
|
|
2322
|
-
onFinish: (result) => {
|
|
2323
|
-
streamPromise.resolve(result.text);
|
|
2324
|
-
},
|
|
2325
|
-
abortSignal
|
|
2326
|
-
});
|
|
2327
|
-
if (abortSignal.aborted) {
|
|
2328
|
-
return abort();
|
|
2329
|
-
}
|
|
3029
|
+
const logger = mastra?.getLogger();
|
|
2330
3030
|
const toolData = {
|
|
2331
3031
|
name: params.name,
|
|
2332
3032
|
args: inputData
|
|
2333
3033
|
};
|
|
2334
|
-
await
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
if (
|
|
2341
|
-
|
|
2342
|
-
type: "watch",
|
|
2343
|
-
runId,
|
|
2344
|
-
data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
|
|
2345
|
-
});
|
|
3034
|
+
const llm = await params.getLLM({ requestContext });
|
|
3035
|
+
const modelInfo = llm.getModel();
|
|
3036
|
+
const isV2Model = isSupportedLanguageModel(modelInfo);
|
|
3037
|
+
let structuredResult = null;
|
|
3038
|
+
const handleFinish = (result) => {
|
|
3039
|
+
const resultWithObject = result;
|
|
3040
|
+
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
3041
|
+
structuredResult = resultWithObject.object;
|
|
2346
3042
|
}
|
|
3043
|
+
};
|
|
3044
|
+
let fullStream;
|
|
3045
|
+
let textPromise;
|
|
3046
|
+
if (isV2Model) {
|
|
3047
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
3048
|
+
...agentOptions ?? {},
|
|
3049
|
+
tracingContext,
|
|
3050
|
+
requestContext,
|
|
3051
|
+
onFinish: (result) => {
|
|
3052
|
+
handleFinish(result);
|
|
3053
|
+
void safeOnFinish(agentOptions?.onFinish, result, logger);
|
|
3054
|
+
},
|
|
3055
|
+
abortSignal
|
|
3056
|
+
});
|
|
3057
|
+
fullStream = modelOutput.fullStream;
|
|
3058
|
+
textPromise = modelOutput.text;
|
|
3059
|
+
} else {
|
|
3060
|
+
let resolveText;
|
|
3061
|
+
textPromise = new Promise((resolve) => {
|
|
3062
|
+
resolveText = resolve;
|
|
3063
|
+
});
|
|
3064
|
+
const legacyResult = await params.streamLegacy(inputData.prompt, {
|
|
3065
|
+
...agentOptions ?? {},
|
|
3066
|
+
tracingContext,
|
|
3067
|
+
requestContext,
|
|
3068
|
+
onFinish: (result) => {
|
|
3069
|
+
handleFinish(result);
|
|
3070
|
+
resolveText(result.text);
|
|
3071
|
+
void safeOnFinish(agentOptions?.onFinish, result, logger);
|
|
3072
|
+
},
|
|
3073
|
+
abortSignal
|
|
3074
|
+
});
|
|
3075
|
+
fullStream = legacyResult.fullStream;
|
|
2347
3076
|
}
|
|
2348
|
-
|
|
2349
|
-
|
|
3077
|
+
if (abortSignal.aborted) {
|
|
3078
|
+
return abort();
|
|
3079
|
+
}
|
|
3080
|
+
const { tripwireChunk } = await processAgentStream({
|
|
3081
|
+
fullStream,
|
|
3082
|
+
isV2Model,
|
|
3083
|
+
pubsub,
|
|
2350
3084
|
runId,
|
|
2351
|
-
|
|
3085
|
+
toolData,
|
|
3086
|
+
logger
|
|
2352
3087
|
});
|
|
3088
|
+
if (tripwireChunk) {
|
|
3089
|
+
throw createTripWireFromChunk(tripwireChunk);
|
|
3090
|
+
}
|
|
3091
|
+
if (structuredResult !== null) {
|
|
3092
|
+
return structuredResult;
|
|
3093
|
+
}
|
|
2353
3094
|
return {
|
|
2354
|
-
text: await
|
|
3095
|
+
text: await textPromise
|
|
2355
3096
|
};
|
|
2356
3097
|
},
|
|
2357
3098
|
component: params.component
|
|
@@ -2879,6 +3620,8 @@ var EventedWorkflow = class extends Workflow {
|
|
|
2879
3620
|
cleanup: () => this.runs.delete(runIdToUse),
|
|
2880
3621
|
workflowSteps: this.steps,
|
|
2881
3622
|
validateInputs: this.options?.validateInputs,
|
|
3623
|
+
inputSchema: this.inputSchema,
|
|
3624
|
+
stateSchema: this.stateSchema,
|
|
2882
3625
|
workflowEngineType: this.engineType
|
|
2883
3626
|
});
|
|
2884
3627
|
this.runs.set(runIdToUse, run);
|
|
@@ -2890,6 +3633,9 @@ var EventedWorkflow = class extends Workflow {
|
|
|
2890
3633
|
withNestedWorkflows: false
|
|
2891
3634
|
});
|
|
2892
3635
|
const existsInStorage = existingRun && !existingRun.isFromInMemory;
|
|
3636
|
+
if (existsInStorage && existingRun.status) {
|
|
3637
|
+
run.workflowRunStatus = existingRun.status;
|
|
3638
|
+
}
|
|
2893
3639
|
if (!existsInStorage && shouldPersistSnapshot) {
|
|
2894
3640
|
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
2895
3641
|
await workflowsStore?.persistWorkflowSnapshot({
|
|
@@ -2944,7 +3690,8 @@ var EventedRun = class extends Run {
|
|
|
2944
3690
|
inputData,
|
|
2945
3691
|
initialState,
|
|
2946
3692
|
requestContext,
|
|
2947
|
-
perStep
|
|
3693
|
+
perStep,
|
|
3694
|
+
outputOptions
|
|
2948
3695
|
}) {
|
|
2949
3696
|
if (this.serializedStepGraph.length === 0) {
|
|
2950
3697
|
throw new Error(
|
|
@@ -2984,6 +3731,7 @@ var EventedRun = class extends Run {
|
|
|
2984
3731
|
const result = await this.executionEngine.execute({
|
|
2985
3732
|
workflowId: this.workflowId,
|
|
2986
3733
|
runId: this.runId,
|
|
3734
|
+
resourceId: this.resourceId,
|
|
2987
3735
|
graph: this.executionGraph,
|
|
2988
3736
|
serializedStepGraph: this.serializedStepGraph,
|
|
2989
3737
|
input: inputDataToUse,
|
|
@@ -2992,7 +3740,8 @@ var EventedRun = class extends Run {
|
|
|
2992
3740
|
retryConfig: this.retryConfig,
|
|
2993
3741
|
requestContext,
|
|
2994
3742
|
abortController: this.abortController,
|
|
2995
|
-
perStep
|
|
3743
|
+
perStep,
|
|
3744
|
+
outputOptions
|
|
2996
3745
|
});
|
|
2997
3746
|
if (result.status !== "suspended") {
|
|
2998
3747
|
this.cleanup?.();
|
|
@@ -3058,19 +3807,147 @@ var EventedRun = class extends Run {
|
|
|
3058
3807
|
});
|
|
3059
3808
|
return { runId: this.runId };
|
|
3060
3809
|
}
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3810
|
+
/**
|
|
3811
|
+
* Starts the workflow execution as a stream, returning a WorkflowRunOutput
|
|
3812
|
+
* with .fullStream for iteration and .result for the final result.
|
|
3813
|
+
*/
|
|
3814
|
+
stream({
|
|
3815
|
+
inputData,
|
|
3816
|
+
requestContext,
|
|
3817
|
+
initialState,
|
|
3818
|
+
closeOnSuspend = true,
|
|
3819
|
+
perStep,
|
|
3820
|
+
outputOptions
|
|
3821
|
+
}) {
|
|
3822
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
3823
|
+
return this.streamOutput;
|
|
3073
3824
|
}
|
|
3825
|
+
this.closeStreamAction = async () => {
|
|
3826
|
+
};
|
|
3827
|
+
const self = this;
|
|
3828
|
+
const stream = new ReadableStream({
|
|
3829
|
+
async start(controller) {
|
|
3830
|
+
const unwatch = self.watch((event) => {
|
|
3831
|
+
const { type, payload } = event;
|
|
3832
|
+
controller.enqueue({
|
|
3833
|
+
type,
|
|
3834
|
+
runId: self.runId,
|
|
3835
|
+
from: "WORKFLOW" /* WORKFLOW */,
|
|
3836
|
+
payload: {
|
|
3837
|
+
stepName: payload?.id,
|
|
3838
|
+
...payload
|
|
3839
|
+
}
|
|
3840
|
+
});
|
|
3841
|
+
});
|
|
3842
|
+
self.closeStreamAction = async () => {
|
|
3843
|
+
unwatch();
|
|
3844
|
+
try {
|
|
3845
|
+
if (controller.desiredSize !== null) {
|
|
3846
|
+
controller.close();
|
|
3847
|
+
}
|
|
3848
|
+
} catch (err) {
|
|
3849
|
+
self.mastra?.getLogger()?.error("Error closing stream:", err);
|
|
3850
|
+
}
|
|
3851
|
+
};
|
|
3852
|
+
try {
|
|
3853
|
+
const executionResults = await self.start({
|
|
3854
|
+
inputData,
|
|
3855
|
+
requestContext,
|
|
3856
|
+
initialState,
|
|
3857
|
+
perStep,
|
|
3858
|
+
outputOptions
|
|
3859
|
+
});
|
|
3860
|
+
if (self.streamOutput) {
|
|
3861
|
+
self.streamOutput.updateResults(executionResults);
|
|
3862
|
+
}
|
|
3863
|
+
if (closeOnSuspend) {
|
|
3864
|
+
self.closeStreamAction?.().catch(() => {
|
|
3865
|
+
});
|
|
3866
|
+
} else if (executionResults.status !== "suspended") {
|
|
3867
|
+
self.closeStreamAction?.().catch(() => {
|
|
3868
|
+
});
|
|
3869
|
+
}
|
|
3870
|
+
} catch (err) {
|
|
3871
|
+
self.streamOutput?.rejectResults(err);
|
|
3872
|
+
self.closeStreamAction?.().catch(() => {
|
|
3873
|
+
});
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
});
|
|
3877
|
+
this.streamOutput = new WorkflowRunOutput({
|
|
3878
|
+
runId: this.runId,
|
|
3879
|
+
workflowId: this.workflowId,
|
|
3880
|
+
stream
|
|
3881
|
+
});
|
|
3882
|
+
return this.streamOutput;
|
|
3883
|
+
}
|
|
3884
|
+
/**
|
|
3885
|
+
* Resumes a suspended workflow as a stream, returning a WorkflowRunOutput
|
|
3886
|
+
* with .fullStream for iteration and .result for the final result.
|
|
3887
|
+
*/
|
|
3888
|
+
resumeStream({
|
|
3889
|
+
step,
|
|
3890
|
+
resumeData,
|
|
3891
|
+
requestContext,
|
|
3892
|
+
perStep,
|
|
3893
|
+
outputOptions
|
|
3894
|
+
} = {}) {
|
|
3895
|
+
this.closeStreamAction = async () => {
|
|
3896
|
+
};
|
|
3897
|
+
const self = this;
|
|
3898
|
+
const stream = new ReadableStream({
|
|
3899
|
+
async start(controller) {
|
|
3900
|
+
const unwatch = self.watch((event) => {
|
|
3901
|
+
const { type, payload } = event;
|
|
3902
|
+
controller.enqueue({
|
|
3903
|
+
type,
|
|
3904
|
+
runId: self.runId,
|
|
3905
|
+
from: "WORKFLOW" /* WORKFLOW */,
|
|
3906
|
+
payload: {
|
|
3907
|
+
stepName: payload?.id,
|
|
3908
|
+
...payload
|
|
3909
|
+
}
|
|
3910
|
+
});
|
|
3911
|
+
});
|
|
3912
|
+
self.closeStreamAction = async () => {
|
|
3913
|
+
unwatch();
|
|
3914
|
+
try {
|
|
3915
|
+
if (controller.desiredSize !== null) {
|
|
3916
|
+
controller.close();
|
|
3917
|
+
}
|
|
3918
|
+
} catch (err) {
|
|
3919
|
+
self.mastra?.getLogger()?.error("Error closing stream:", err);
|
|
3920
|
+
}
|
|
3921
|
+
};
|
|
3922
|
+
try {
|
|
3923
|
+
const executionResults = await self.resume({
|
|
3924
|
+
resumeData,
|
|
3925
|
+
step,
|
|
3926
|
+
requestContext,
|
|
3927
|
+
perStep,
|
|
3928
|
+
outputOptions
|
|
3929
|
+
});
|
|
3930
|
+
if (self.streamOutput) {
|
|
3931
|
+
self.streamOutput.updateResults(executionResults);
|
|
3932
|
+
}
|
|
3933
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
3934
|
+
self.closeStreamAction?.().catch(() => {
|
|
3935
|
+
});
|
|
3936
|
+
} catch (err) {
|
|
3937
|
+
self.streamOutput?.rejectResults(err);
|
|
3938
|
+
self.closeStreamAction?.().catch(() => {
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
}
|
|
3942
|
+
});
|
|
3943
|
+
this.streamOutput = new WorkflowRunOutput({
|
|
3944
|
+
runId: this.runId,
|
|
3945
|
+
workflowId: this.workflowId,
|
|
3946
|
+
stream
|
|
3947
|
+
});
|
|
3948
|
+
return this.streamOutput;
|
|
3949
|
+
}
|
|
3950
|
+
async resume(params) {
|
|
3074
3951
|
const workflowsStore = await this.mastra?.getStorage()?.getStore("workflows");
|
|
3075
3952
|
if (!workflowsStore) {
|
|
3076
3953
|
throw new Error("Cannot resume workflow: workflows store is required");
|
|
@@ -3082,12 +3959,62 @@ var EventedRun = class extends Run {
|
|
|
3082
3959
|
if (!snapshot) {
|
|
3083
3960
|
throw new Error(`Cannot resume workflow: no snapshot found for runId ${this.runId}`);
|
|
3084
3961
|
}
|
|
3085
|
-
|
|
3086
|
-
|
|
3962
|
+
if (snapshot.status !== "suspended") {
|
|
3963
|
+
throw new Error("This workflow run was not suspended");
|
|
3964
|
+
}
|
|
3965
|
+
const snapshotResumeLabel = params.label ? snapshot?.resumeLabels?.[params.label] : void 0;
|
|
3966
|
+
if (params.label && !snapshotResumeLabel) {
|
|
3967
|
+
const availableLabels = Object.keys(snapshot?.resumeLabels ?? {});
|
|
3968
|
+
throw new Error(
|
|
3969
|
+
`Resume label "${params.label}" not found. Available labels: [${availableLabels.join(", ")}]`
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
const stepParam = snapshotResumeLabel?.stepId ?? params.step;
|
|
3973
|
+
let steps;
|
|
3974
|
+
if (stepParam) {
|
|
3975
|
+
if (typeof stepParam === "string") {
|
|
3976
|
+
steps = stepParam.split(".");
|
|
3977
|
+
} else {
|
|
3978
|
+
steps = (Array.isArray(stepParam) ? stepParam : [stepParam]).map(
|
|
3979
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
3980
|
+
);
|
|
3981
|
+
}
|
|
3982
|
+
} else {
|
|
3983
|
+
const suspendedStepPaths = [];
|
|
3984
|
+
Object.entries(snapshot?.suspendedPaths ?? {}).forEach(([stepId, _executionPath]) => {
|
|
3985
|
+
const stepResult = snapshot?.context?.[stepId];
|
|
3986
|
+
if (stepResult && typeof stepResult === "object" && "status" in stepResult) {
|
|
3987
|
+
const stepRes = stepResult;
|
|
3988
|
+
if (stepRes.status === "suspended") {
|
|
3989
|
+
const nestedPath = stepRes.suspendPayload?.__workflow_meta?.path;
|
|
3990
|
+
if (nestedPath && Array.isArray(nestedPath)) {
|
|
3991
|
+
suspendedStepPaths.push([stepId, ...nestedPath]);
|
|
3992
|
+
} else {
|
|
3993
|
+
suspendedStepPaths.push([stepId]);
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
});
|
|
3998
|
+
if (suspendedStepPaths.length === 0) {
|
|
3999
|
+
throw new Error("No suspended steps found in this workflow run");
|
|
4000
|
+
}
|
|
4001
|
+
if (suspendedStepPaths.length === 1) {
|
|
4002
|
+
steps = suspendedStepPaths[0];
|
|
4003
|
+
} else {
|
|
4004
|
+
const pathStrings = suspendedStepPaths.map((path) => `[${path.join(", ")}]`);
|
|
4005
|
+
throw new Error(
|
|
4006
|
+
`Multiple suspended steps found: ${pathStrings.join(", ")}. Please specify which step to resume using the "step" parameter.`
|
|
4007
|
+
);
|
|
4008
|
+
}
|
|
4009
|
+
}
|
|
4010
|
+
const suspendedStepIds = Object.keys(snapshot?.suspendedPaths ?? {});
|
|
4011
|
+
const isStepSuspended = suspendedStepIds.includes(steps?.[0] ?? "");
|
|
4012
|
+
if (!isStepSuspended) {
|
|
3087
4013
|
throw new Error(
|
|
3088
|
-
`
|
|
4014
|
+
`This workflow step "${steps?.[0]}" was not suspended. Available suspended steps: [${suspendedStepIds.join(", ")}]`
|
|
3089
4015
|
);
|
|
3090
4016
|
}
|
|
4017
|
+
const resumePath = snapshot.suspendedPaths?.[steps[0]];
|
|
3091
4018
|
console.dir(
|
|
3092
4019
|
{ resume: { requestContextObj: snapshot.requestContext, requestContext: params.requestContext } },
|
|
3093
4020
|
{ depth: null }
|
|
@@ -3108,22 +4035,26 @@ var EventedRun = class extends Run {
|
|
|
3108
4035
|
throw new Error("Mastra instance with pubsub is required for workflow execution");
|
|
3109
4036
|
}
|
|
3110
4037
|
this.setupAbortHandler();
|
|
4038
|
+
const resumeState = snapshot?.context?.__state ?? snapshot?.value ?? {};
|
|
3111
4039
|
const executionResultPromise = this.executionEngine.execute({
|
|
3112
4040
|
workflowId: this.workflowId,
|
|
3113
4041
|
runId: this.runId,
|
|
3114
4042
|
graph: this.executionGraph,
|
|
3115
4043
|
serializedStepGraph: this.serializedStepGraph,
|
|
3116
4044
|
input: snapshot?.context?.input,
|
|
4045
|
+
initialState: resumeState,
|
|
3117
4046
|
resume: {
|
|
3118
4047
|
steps,
|
|
3119
4048
|
stepResults: snapshot?.context,
|
|
3120
4049
|
resumePayload: resumeDataToUse,
|
|
3121
|
-
resumePath
|
|
4050
|
+
resumePath,
|
|
4051
|
+
forEachIndex: params.forEachIndex ?? snapshotResumeLabel?.foreachIndex
|
|
3122
4052
|
},
|
|
3123
4053
|
pubsub: this.mastra.pubsub,
|
|
3124
4054
|
requestContext,
|
|
3125
4055
|
abortController: this.abortController,
|
|
3126
|
-
perStep: params.perStep
|
|
4056
|
+
perStep: params.perStep,
|
|
4057
|
+
outputOptions: params.outputOptions
|
|
3127
4058
|
}).then((result) => {
|
|
3128
4059
|
if (result.status !== "suspended") {
|
|
3129
4060
|
this.closeStreamAction?.().catch(() => {
|
|
@@ -3178,6 +4109,18 @@ var EventedRun = class extends Run {
|
|
|
3178
4109
|
};
|
|
3179
4110
|
|
|
3180
4111
|
// src/workflows/evented/workflow-event-processor/utils.ts
|
|
4112
|
+
function isWorkflowStep(step) {
|
|
4113
|
+
if (!step || typeof step !== "object") {
|
|
4114
|
+
return false;
|
|
4115
|
+
}
|
|
4116
|
+
if (step instanceof EventedWorkflow) {
|
|
4117
|
+
return true;
|
|
4118
|
+
}
|
|
4119
|
+
if ("component" in step && step.component === "WORKFLOW") {
|
|
4120
|
+
return true;
|
|
4121
|
+
}
|
|
4122
|
+
return false;
|
|
4123
|
+
}
|
|
3181
4124
|
function getNestedWorkflow(mastra, { workflowId, executionPath, parentWorkflow }) {
|
|
3182
4125
|
let workflow = null;
|
|
3183
4126
|
if (parentWorkflow) {
|
|
@@ -3194,7 +4137,16 @@ function getNestedWorkflow(mastra, { workflowId, executionPath, parentWorkflow }
|
|
|
3194
4137
|
parentStep = parentStep.steps[executionPath[1]];
|
|
3195
4138
|
}
|
|
3196
4139
|
if (parentStep?.type === "step" || parentStep?.type === "loop") {
|
|
3197
|
-
|
|
4140
|
+
if (isWorkflowStep(parentStep.step)) {
|
|
4141
|
+
return parentStep.step;
|
|
4142
|
+
}
|
|
4143
|
+
return null;
|
|
4144
|
+
}
|
|
4145
|
+
if (parentStep?.type === "foreach") {
|
|
4146
|
+
if (isWorkflowStep(parentStep.step)) {
|
|
4147
|
+
return parentStep.step;
|
|
4148
|
+
}
|
|
4149
|
+
return null;
|
|
3198
4150
|
}
|
|
3199
4151
|
return null;
|
|
3200
4152
|
}
|
|
@@ -3246,101 +4198,147 @@ var EventedExecutionEngine = class extends ExecutionEngine {
|
|
|
3246
4198
|
if (!pubsub) {
|
|
3247
4199
|
throw new Error("No Pubsub adapter configured on the Mastra instance");
|
|
3248
4200
|
}
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
3264
|
-
|
|
3265
|
-
perStep: params.perStep
|
|
4201
|
+
let resolveResult;
|
|
4202
|
+
let rejectResult;
|
|
4203
|
+
const resultPromise = new Promise((resolve, reject) => {
|
|
4204
|
+
resolveResult = resolve;
|
|
4205
|
+
rejectResult = reject;
|
|
4206
|
+
});
|
|
4207
|
+
const finishCb = async (event, ack) => {
|
|
4208
|
+
if (event.runId !== params.runId) {
|
|
4209
|
+
await ack?.();
|
|
4210
|
+
return;
|
|
4211
|
+
}
|
|
4212
|
+
if (["workflow.end", "workflow.fail", "workflow.suspend"].includes(event.type)) {
|
|
4213
|
+
await ack?.();
|
|
4214
|
+
await pubsub.unsubscribe("workflows-finish", finishCb);
|
|
4215
|
+
if (event.type === "workflow.fail" && event.data.stepResults) {
|
|
4216
|
+
event.data.stepResults = hydrateSerializedStepErrors(event.data.stepResults);
|
|
3266
4217
|
}
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
4218
|
+
resolveResult(event.data);
|
|
4219
|
+
return;
|
|
4220
|
+
}
|
|
4221
|
+
await ack?.();
|
|
4222
|
+
};
|
|
4223
|
+
try {
|
|
4224
|
+
await pubsub.subscribe("workflows-finish", finishCb);
|
|
4225
|
+
} catch (err) {
|
|
4226
|
+
this.mastra?.getLogger()?.error("Failed to subscribe to workflows-finish:", err);
|
|
4227
|
+
throw err;
|
|
4228
|
+
}
|
|
4229
|
+
try {
|
|
4230
|
+
if (params.resume) {
|
|
4231
|
+
const prevStep = getStep(this.mastra.getWorkflow(params.workflowId), params.resume.resumePath);
|
|
4232
|
+
const prevResult = params.resume.stepResults[prevStep?.id ?? "input"];
|
|
4233
|
+
const resumeState = params.resume.stepResults?.__state ?? params.initialState ?? {};
|
|
4234
|
+
await pubsub.publish("workflows", {
|
|
4235
|
+
type: "workflow.resume",
|
|
3276
4236
|
runId: params.runId,
|
|
3277
|
-
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
4237
|
+
data: {
|
|
4238
|
+
workflowId: params.workflowId,
|
|
4239
|
+
runId: params.runId,
|
|
4240
|
+
executionPath: params.resume.resumePath,
|
|
4241
|
+
stepResults: params.resume.stepResults,
|
|
4242
|
+
resumeSteps: params.resume.steps,
|
|
4243
|
+
prevResult: { status: "success", output: prevResult?.payload },
|
|
4244
|
+
resumeData: params.resume.resumePayload,
|
|
4245
|
+
requestContext: Object.fromEntries(params.requestContext.entries()),
|
|
4246
|
+
format: params.format,
|
|
4247
|
+
perStep: params.perStep,
|
|
4248
|
+
initialState: resumeState,
|
|
4249
|
+
state: resumeState,
|
|
4250
|
+
outputOptions: params.outputOptions,
|
|
4251
|
+
forEachIndex: params.resume.forEachIndex
|
|
4252
|
+
}
|
|
4253
|
+
});
|
|
4254
|
+
} else if (params.timeTravel) {
|
|
4255
|
+
const prevStep = getStep(this.mastra.getWorkflow(params.workflowId), params.timeTravel.executionPath);
|
|
4256
|
+
const prevResult = params.timeTravel.stepResults[prevStep?.id ?? "input"];
|
|
4257
|
+
await pubsub.publish("workflows", {
|
|
4258
|
+
type: "workflow.start",
|
|
3292
4259
|
runId: params.runId,
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
await ack?.();
|
|
3304
|
-
return;
|
|
3305
|
-
}
|
|
3306
|
-
if (["workflow.end", "workflow.fail", "workflow.suspend"].includes(event.type)) {
|
|
3307
|
-
await ack?.();
|
|
3308
|
-
await pubsub.unsubscribe("workflows-finish", finishCb);
|
|
3309
|
-
if (event.type === "workflow.fail" && event.data.stepResults) {
|
|
3310
|
-
event.data.stepResults = hydrateSerializedStepErrors(event.data.stepResults);
|
|
4260
|
+
data: {
|
|
4261
|
+
workflowId: params.workflowId,
|
|
4262
|
+
runId: params.runId,
|
|
4263
|
+
executionPath: params.timeTravel.executionPath,
|
|
4264
|
+
stepResults: params.timeTravel.stepResults,
|
|
4265
|
+
timeTravel: params.timeTravel,
|
|
4266
|
+
prevResult: { status: "success", output: prevResult?.payload },
|
|
4267
|
+
requestContext: Object.fromEntries(params.requestContext.entries()),
|
|
4268
|
+
format: params.format,
|
|
4269
|
+
perStep: params.perStep
|
|
3311
4270
|
}
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
4271
|
+
});
|
|
4272
|
+
} else {
|
|
4273
|
+
await pubsub.publish("workflows", {
|
|
4274
|
+
type: "workflow.start",
|
|
4275
|
+
runId: params.runId,
|
|
4276
|
+
data: {
|
|
4277
|
+
workflowId: params.workflowId,
|
|
4278
|
+
runId: params.runId,
|
|
4279
|
+
prevResult: { status: "success", output: params.input },
|
|
4280
|
+
requestContext: Object.fromEntries(params.requestContext.entries()),
|
|
4281
|
+
format: params.format,
|
|
4282
|
+
perStep: params.perStep,
|
|
4283
|
+
initialState: params.initialState,
|
|
4284
|
+
outputOptions: params.outputOptions
|
|
4285
|
+
}
|
|
4286
|
+
});
|
|
4287
|
+
}
|
|
4288
|
+
} catch (err) {
|
|
4289
|
+
await pubsub.unsubscribe("workflows-finish", finishCb);
|
|
4290
|
+
rejectResult(err);
|
|
4291
|
+
throw err;
|
|
4292
|
+
}
|
|
4293
|
+
const resultData = await resultPromise;
|
|
4294
|
+
const finalState = resultData.state ?? resultData.stepResults?.__state ?? params.initialState ?? {};
|
|
4295
|
+
const { __state: _removedState, ...stepResultsWithoutTopLevelState } = resultData.stepResults ?? {};
|
|
4296
|
+
const cleanStepResults = {};
|
|
4297
|
+
for (const [stepId, stepResult] of Object.entries(stepResultsWithoutTopLevelState)) {
|
|
4298
|
+
cleanStepResults[stepId] = cleanStepResult(stepResult);
|
|
4299
|
+
}
|
|
3322
4300
|
let callbackArg;
|
|
3323
4301
|
if (resultData.prevResult.status === "failed") {
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
4302
|
+
let tripwireData;
|
|
4303
|
+
for (const stepResult of Object.values(cleanStepResults)) {
|
|
4304
|
+
if (stepResult?.status === "failed" && stepResult?.tripwire) {
|
|
4305
|
+
tripwireData = stepResult.tripwire;
|
|
4306
|
+
break;
|
|
4307
|
+
}
|
|
4308
|
+
}
|
|
4309
|
+
if (tripwireData && typeof tripwireData === "object" && "reason" in tripwireData) {
|
|
4310
|
+
callbackArg = {
|
|
4311
|
+
status: "tripwire",
|
|
4312
|
+
steps: cleanStepResults,
|
|
4313
|
+
state: finalState,
|
|
4314
|
+
tripwire: tripwireData
|
|
4315
|
+
};
|
|
4316
|
+
} else {
|
|
4317
|
+
callbackArg = {
|
|
4318
|
+
status: "failed",
|
|
4319
|
+
error: resultData.prevResult.error,
|
|
4320
|
+
steps: cleanStepResults,
|
|
4321
|
+
state: finalState
|
|
4322
|
+
};
|
|
4323
|
+
}
|
|
3329
4324
|
} else if (resultData.prevResult.status === "suspended") {
|
|
3330
4325
|
callbackArg = {
|
|
3331
4326
|
status: "suspended",
|
|
3332
|
-
steps:
|
|
4327
|
+
steps: cleanStepResults,
|
|
4328
|
+
state: finalState
|
|
3333
4329
|
};
|
|
3334
4330
|
} else if (resultData.prevResult.status === "paused" || params.perStep) {
|
|
3335
4331
|
callbackArg = {
|
|
3336
4332
|
status: "paused",
|
|
3337
|
-
steps:
|
|
4333
|
+
steps: cleanStepResults,
|
|
4334
|
+
state: finalState
|
|
3338
4335
|
};
|
|
3339
4336
|
} else {
|
|
3340
4337
|
callbackArg = {
|
|
3341
4338
|
status: resultData.prevResult.status,
|
|
3342
4339
|
result: resultData.prevResult?.output,
|
|
3343
|
-
steps:
|
|
4340
|
+
steps: cleanStepResults,
|
|
4341
|
+
state: finalState
|
|
3344
4342
|
};
|
|
3345
4343
|
}
|
|
3346
4344
|
if (callbackArg.status !== "paused") {
|
|
@@ -3349,13 +4347,13 @@ var EventedExecutionEngine = class extends ExecutionEngine {
|
|
|
3349
4347
|
result: callbackArg.result,
|
|
3350
4348
|
error: callbackArg.error,
|
|
3351
4349
|
steps: callbackArg.steps,
|
|
3352
|
-
tripwire:
|
|
4350
|
+
tripwire: callbackArg.tripwire,
|
|
3353
4351
|
runId: params.runId,
|
|
3354
4352
|
workflowId: params.workflowId,
|
|
3355
|
-
resourceId:
|
|
4353
|
+
resourceId: params.resourceId,
|
|
3356
4354
|
input: params.input,
|
|
3357
4355
|
requestContext: params.requestContext,
|
|
3358
|
-
state:
|
|
4356
|
+
state: finalState
|
|
3359
4357
|
});
|
|
3360
4358
|
}
|
|
3361
4359
|
let result;
|
|
@@ -3367,16 +4365,43 @@ var EventedExecutionEngine = class extends ExecutionEngine {
|
|
|
3367
4365
|
return null;
|
|
3368
4366
|
}).filter(Boolean);
|
|
3369
4367
|
result = {
|
|
3370
|
-
|
|
4368
|
+
status: callbackArg.status,
|
|
4369
|
+
steps: callbackArg.steps,
|
|
3371
4370
|
suspended: suspendedSteps
|
|
3372
4371
|
};
|
|
4372
|
+
} else if (resultData.prevResult.status === "failed") {
|
|
4373
|
+
if (callbackArg.status === "tripwire" && callbackArg.tripwire) {
|
|
4374
|
+
result = {
|
|
4375
|
+
status: "tripwire",
|
|
4376
|
+
tripwire: callbackArg.tripwire,
|
|
4377
|
+
steps: callbackArg.steps
|
|
4378
|
+
};
|
|
4379
|
+
} else {
|
|
4380
|
+
result = {
|
|
4381
|
+
status: callbackArg.status,
|
|
4382
|
+
error: callbackArg.error,
|
|
4383
|
+
steps: callbackArg.steps
|
|
4384
|
+
};
|
|
4385
|
+
}
|
|
4386
|
+
} else if (resultData.prevResult.status === "paused" || params.perStep) {
|
|
4387
|
+
result = {
|
|
4388
|
+
status: "paused",
|
|
4389
|
+
steps: callbackArg.steps
|
|
4390
|
+
};
|
|
3373
4391
|
} else {
|
|
3374
|
-
result =
|
|
4392
|
+
result = {
|
|
4393
|
+
status: callbackArg.status,
|
|
4394
|
+
result: callbackArg.result,
|
|
4395
|
+
steps: callbackArg.steps
|
|
4396
|
+
};
|
|
4397
|
+
}
|
|
4398
|
+
if (params.outputOptions?.includeState) {
|
|
4399
|
+
result.state = finalState;
|
|
3375
4400
|
}
|
|
3376
4401
|
return result;
|
|
3377
4402
|
}
|
|
3378
4403
|
};
|
|
3379
4404
|
|
|
3380
4405
|
export { EventedExecutionEngine, EventedRun, EventedWorkflow, StepExecutor, WorkflowEventProcessor, cloneStep, cloneWorkflow, createStep, createWorkflow };
|
|
3381
|
-
//# sourceMappingURL=chunk-
|
|
3382
|
-
//# sourceMappingURL=chunk-
|
|
4406
|
+
//# sourceMappingURL=chunk-FYMM4PKR.js.map
|
|
4407
|
+
//# sourceMappingURL=chunk-FYMM4PKR.js.map
|