@mastra/core 0.10.12 → 0.10.13
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/package.json +1 -1
- package/a2a.d.ts +0 -1
- package/agent.d.ts +0 -1
- package/base.d.ts +0 -1
- package/bundler.d.ts +0 -1
- package/deployer.d.ts +0 -1
- package/di.d.ts +0 -1
- package/dist/a2a/index.cjs +0 -79
- package/dist/a2a/index.d.cts +0 -780
- package/dist/a2a/index.d.ts +0 -780
- package/dist/a2a/index.js +0 -68
- package/dist/agent/index.cjs +0 -15
- package/dist/agent/index.d.cts +0 -29
- package/dist/agent/index.d.ts +0 -29
- package/dist/agent/index.js +0 -2
- package/dist/base-B_y9sMg0.d.cts +0 -162
- package/dist/base-CS5eSXbL.d.cts +0 -4117
- package/dist/base-ClrXcCRx.d.ts +0 -162
- package/dist/base-DBhKcre4.d.ts +0 -4117
- package/dist/base.cjs +0 -10
- package/dist/base.d.cts +0 -6
- package/dist/base.d.ts +0 -6
- package/dist/base.js +0 -1
- package/dist/bundler/index.cjs +0 -10
- package/dist/bundler/index.d.cts +0 -30
- package/dist/bundler/index.d.ts +0 -30
- package/dist/bundler/index.js +0 -1
- package/dist/chunk-2GRYVZ2O.cjs +0 -244
- package/dist/chunk-2HDFKWFU.js +0 -2249
- package/dist/chunk-32C7JDIZ.js +0 -1
- package/dist/chunk-4UBOJFSL.js +0 -989
- package/dist/chunk-4UWPFBC6.js +0 -88
- package/dist/chunk-4Z3OU5RY.cjs +0 -31
- package/dist/chunk-5HTMDAXP.js +0 -359
- package/dist/chunk-5IEKR756.js +0 -53
- package/dist/chunk-5YDTZN2X.js +0 -114
- package/dist/chunk-6UNGH46J.js +0 -75
- package/dist/chunk-6Y4UL5Z6.cjs +0 -94
- package/dist/chunk-7F6BQXE2.cjs +0 -425
- package/dist/chunk-7H2GET5Z.cjs +0 -668
- package/dist/chunk-7HZ6NIAF.cjs +0 -2
- package/dist/chunk-7MZNOW6W.cjs +0 -2263
- package/dist/chunk-7XQIPES3.js +0 -668
- package/dist/chunk-AKYTYALY.js +0 -70
- package/dist/chunk-ATXBSEFT.js +0 -22
- package/dist/chunk-B6TOBUS6.cjs +0 -80
- package/dist/chunk-B7SQOKEC.cjs +0 -91
- package/dist/chunk-BB4KXGBU.js +0 -83
- package/dist/chunk-BB6DPGIV.cjs +0 -6
- package/dist/chunk-C4LMN2IR.js +0 -27
- package/dist/chunk-DFFVEKIG.js +0 -407
- package/dist/chunk-E7AX3U6M.cjs +0 -659
- package/dist/chunk-EWCOOO3H.js +0 -5007
- package/dist/chunk-F2WMR75C.cjs +0 -183
- package/dist/chunk-FBKJ3652.cjs +0 -5034
- package/dist/chunk-FEYYOBBG.cjs +0 -24
- package/dist/chunk-FL5SZ2XU.js +0 -181
- package/dist/chunk-GH2KM66J.js +0 -37
- package/dist/chunk-GWFS5DAR.cjs +0 -37
- package/dist/chunk-HNEE7IF4.js +0 -60
- package/dist/chunk-HSVOEWAM.cjs +0 -2
- package/dist/chunk-J52TXHZV.cjs +0 -73
- package/dist/chunk-JNMQKJH4.js +0 -10
- package/dist/chunk-JQOMTERC.js +0 -89
- package/dist/chunk-LABUWBKX.cjs +0 -71
- package/dist/chunk-LXFZUKP3.cjs +0 -34
- package/dist/chunk-MP2QBLUJ.cjs +0 -70
- package/dist/chunk-MUNFCOMB.cjs +0 -62
- package/dist/chunk-NH5WJNNS.js +0 -1
- package/dist/chunk-P3Q73CAW.cjs +0 -55
- package/dist/chunk-PA2YIVIT.js +0 -61
- package/dist/chunk-QFTBW7ZZ.cjs +0 -2
- package/dist/chunk-QQ5K5TZE.cjs +0 -619
- package/dist/chunk-QUSEDVYI.cjs +0 -991
- package/dist/chunk-R4V75T7J.js +0 -1
- package/dist/chunk-SGGPJWRQ.js +0 -69
- package/dist/chunk-ST5RMVLG.cjs +0 -87
- package/dist/chunk-TC2SCOTE.js +0 -605
- package/dist/chunk-U64IJDC5.cjs +0 -109
- package/dist/chunk-UX3B6S2I.cjs +0 -65
- package/dist/chunk-V5D2LIF5.js +0 -68
- package/dist/chunk-VG4OPO2R.js +0 -240
- package/dist/chunk-WQNOATKB.js +0 -103
- package/dist/chunk-Y7D2JLKS.js +0 -4
- package/dist/chunk-YJEHXYK5.js +0 -657
- package/dist/chunk-YOQP5T77.js +0 -32
- package/dist/chunk-ZIZ3CVHN.cjs +0 -120
- package/dist/chunk-ZPOUMTTH.cjs +0 -362
- package/dist/chunk-ZZLBNB3U.cjs +0 -12
- package/dist/deployer/index.cjs +0 -10
- package/dist/deployer/index.d.cts +0 -19
- package/dist/deployer/index.d.ts +0 -19
- package/dist/deployer/index.js +0 -1
- package/dist/di/index.cjs +0 -10
- package/dist/di/index.d.cts +0 -1
- package/dist/di/index.d.ts +0 -1
- package/dist/di/index.js +0 -1
- package/dist/error/index.cjs +0 -22
- package/dist/error/index.d.cts +0 -86
- package/dist/error/index.d.ts +0 -86
- package/dist/error/index.js +0 -1
- package/dist/eval/index.cjs +0 -14
- package/dist/eval/index.d.cts +0 -43
- package/dist/eval/index.d.ts +0 -43
- package/dist/eval/index.js +0 -1
- package/dist/hooks/index.cjs +0 -18
- package/dist/hooks/index.d.cts +0 -33
- package/dist/hooks/index.d.ts +0 -33
- package/dist/hooks/index.js +0 -1
- package/dist/index.cjs +0 -281
- package/dist/index.d.cts +0 -92
- package/dist/index.d.ts +0 -92
- package/dist/index.js +0 -112
- package/dist/integration/index.cjs +0 -14
- package/dist/integration/index.d.cts +0 -65
- package/dist/integration/index.d.ts +0 -65
- package/dist/integration/index.js +0 -1
- package/dist/llm/index.cjs +0 -10
- package/dist/llm/index.d.cts +0 -29
- package/dist/llm/index.d.ts +0 -29
- package/dist/llm/index.js +0 -1
- package/dist/logger/index.cjs +0 -43
- package/dist/logger/index.d.cts +0 -96
- package/dist/logger/index.d.ts +0 -96
- package/dist/logger/index.js +0 -2
- package/dist/logger-B8XXh6ya.d.cts +0 -159
- package/dist/logger-Bpa2oLL4.d.ts +0 -159
- package/dist/mastra/index.cjs +0 -10
- package/dist/mastra/index.d.cts +0 -29
- package/dist/mastra/index.d.ts +0 -29
- package/dist/mastra/index.js +0 -1
- package/dist/mcp/index.cjs +0 -106
- package/dist/mcp/index.d.cts +0 -29
- package/dist/mcp/index.d.ts +0 -29
- package/dist/mcp/index.js +0 -100
- package/dist/memory/index.cjs +0 -18
- package/dist/memory/index.d.cts +0 -29
- package/dist/memory/index.d.ts +0 -29
- package/dist/memory/index.js +0 -1
- package/dist/network/index.cjs +0 -311
- package/dist/network/index.d.cts +0 -29
- package/dist/network/index.d.ts +0 -29
- package/dist/network/index.js +0 -309
- package/dist/network/vNext/index.cjs +0 -873
- package/dist/network/vNext/index.d.cts +0 -29
- package/dist/network/vNext/index.d.ts +0 -29
- package/dist/network/vNext/index.js +0 -871
- package/dist/relevance/index.cjs +0 -18
- package/dist/relevance/index.d.cts +0 -49
- package/dist/relevance/index.d.ts +0 -49
- package/dist/relevance/index.js +0 -1
- package/dist/runtime-context/index.cjs +0 -10
- package/dist/runtime-context/index.d.cts +0 -52
- package/dist/runtime-context/index.d.ts +0 -52
- package/dist/runtime-context/index.js +0 -1
- package/dist/server/index.cjs +0 -62
- package/dist/server/index.d.cts +0 -52
- package/dist/server/index.d.ts +0 -52
- package/dist/server/index.js +0 -59
- package/dist/storage/index.cjs +0 -336
- package/dist/storage/index.d.cts +0 -149
- package/dist/storage/index.d.ts +0 -149
- package/dist/storage/index.js +0 -303
- package/dist/telemetry/index.cjs +0 -30
- package/dist/telemetry/index.d.cts +0 -75
- package/dist/telemetry/index.d.ts +0 -75
- package/dist/telemetry/index.js +0 -1
- package/dist/telemetry/otel-vendor.cjs +0 -103
- package/dist/telemetry/otel-vendor.d.cts +0 -20
- package/dist/telemetry/otel-vendor.d.ts +0 -20
- package/dist/telemetry/otel-vendor.js +0 -57
- package/dist/tools/index.cjs +0 -18
- package/dist/tools/index.d.cts +0 -41
- package/dist/tools/index.d.ts +0 -41
- package/dist/tools/index.js +0 -1
- package/dist/tts/index.cjs +0 -10
- package/dist/tts/index.d.cts +0 -28
- package/dist/tts/index.d.ts +0 -28
- package/dist/tts/index.js +0 -1
- package/dist/types-Bo1uigWx.d.cts +0 -17
- package/dist/types-Bo1uigWx.d.ts +0 -17
- package/dist/utils.cjs +0 -58
- package/dist/utils.d.cts +0 -149
- package/dist/utils.d.ts +0 -149
- package/dist/utils.js +0 -1
- package/dist/vector/filter/index.cjs +0 -192
- package/dist/vector/filter/index.d.cts +0 -128
- package/dist/vector/filter/index.d.ts +0 -128
- package/dist/vector/filter/index.js +0 -190
- package/dist/vector/index.cjs +0 -10
- package/dist/vector/index.d.cts +0 -77
- package/dist/vector/index.d.ts +0 -77
- package/dist/vector/index.js +0 -1
- package/dist/voice/index.cjs +0 -18
- package/dist/voice/index.d.cts +0 -29
- package/dist/voice/index.d.ts +0 -29
- package/dist/voice/index.js +0 -1
- package/dist/workflows/constants.cjs +0 -10
- package/dist/workflows/constants.d.cts +0 -3
- package/dist/workflows/constants.d.ts +0 -3
- package/dist/workflows/constants.js +0 -1
- package/dist/workflows/index.cjs +0 -42
- package/dist/workflows/index.d.cts +0 -282
- package/dist/workflows/index.d.ts +0 -282
- package/dist/workflows/index.js +0 -1
- package/dist/workflows/legacy/index.cjs +0 -90
- package/dist/workflows/legacy/index.d.cts +0 -91
- package/dist/workflows/legacy/index.d.ts +0 -91
- package/dist/workflows/legacy/index.js +0 -1
- package/error.d.ts +0 -1
- package/eval.d.ts +0 -1
- package/hooks.d.ts +0 -1
- package/integration.d.ts +0 -1
- package/llm.d.ts +0 -1
- package/logger.d.ts +0 -1
- package/mastra.d.ts +0 -1
- package/mcp.d.ts +0 -1
- package/memory.d.ts +0 -1
- package/network/vNext.d.ts +0 -1
- package/network.d.ts +0 -1
- package/relevance.d.ts +0 -1
- package/runtime-context.d.ts +0 -1
- package/server.d.ts +0 -1
- package/storage.d.ts +0 -1
- package/telemetry/otel-vendor.d.ts +0 -1
- package/telemetry.d.ts +0 -1
- package/tools.d.ts +0 -1
- package/tts.d.ts +0 -1
- package/utils.d.ts +0 -1
- package/vector/filter.d.ts +0 -1
- package/vector.d.ts +0 -1
- package/voice.d.ts +0 -1
- package/workflows/_constants.d.ts +0 -1
- package/workflows/legacy.d.ts +0 -1
- package/workflows.d.ts +0 -1
package/dist/chunk-EWCOOO3H.js
DELETED
|
@@ -1,5007 +0,0 @@
|
|
|
1
|
-
import { DefaultVoice } from './chunk-5HTMDAXP.js';
|
|
2
|
-
import { MessageList } from './chunk-4UBOJFSL.js';
|
|
3
|
-
import { executeHook } from './chunk-BB4KXGBU.js';
|
|
4
|
-
import { MastraLLM } from './chunk-YJEHXYK5.js';
|
|
5
|
-
import { InstrumentClass } from './chunk-TC2SCOTE.js';
|
|
6
|
-
import { ensureToolProperties, makeCoreTool, createMastraProxy } from './chunk-DFFVEKIG.js';
|
|
7
|
-
import { MastraError } from './chunk-6UNGH46J.js';
|
|
8
|
-
import { MastraBase } from './chunk-5IEKR756.js';
|
|
9
|
-
import { RegisteredLogger } from './chunk-5YDTZN2X.js';
|
|
10
|
-
import { RuntimeContext } from './chunk-SGGPJWRQ.js';
|
|
11
|
-
import { __commonJS, __toESM, __decoratorStart, __decorateElement, __runInitializers } from './chunk-WQNOATKB.js';
|
|
12
|
-
import { context, trace } from '@opentelemetry/api';
|
|
13
|
-
import { z } from 'zod';
|
|
14
|
-
import { get } from 'radash';
|
|
15
|
-
import { randomUUID } from 'crypto';
|
|
16
|
-
import EventEmitter from 'events';
|
|
17
|
-
import sift from 'sift';
|
|
18
|
-
import { createActor, assign, fromPromise, setup } from 'xstate';
|
|
19
|
-
|
|
20
|
-
// ../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js
|
|
21
|
-
var require_fast_deep_equal = __commonJS({
|
|
22
|
-
"../../node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js"(exports, module) {
|
|
23
|
-
|
|
24
|
-
module.exports = function equal(a, b) {
|
|
25
|
-
if (a === b) return true;
|
|
26
|
-
if (a && b && typeof a == "object" && typeof b == "object") {
|
|
27
|
-
if (a.constructor !== b.constructor) return false;
|
|
28
|
-
var length, i, keys;
|
|
29
|
-
if (Array.isArray(a)) {
|
|
30
|
-
length = a.length;
|
|
31
|
-
if (length != b.length) return false;
|
|
32
|
-
for (i = length; i-- !== 0;) if (!equal(a[i], b[i])) return false;
|
|
33
|
-
return true;
|
|
34
|
-
}
|
|
35
|
-
if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
|
|
36
|
-
if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
|
|
37
|
-
if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
|
|
38
|
-
keys = Object.keys(a);
|
|
39
|
-
length = keys.length;
|
|
40
|
-
if (length !== Object.keys(b).length) return false;
|
|
41
|
-
for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
|
|
42
|
-
for (i = length; i-- !== 0;) {
|
|
43
|
-
var key = keys[i];
|
|
44
|
-
if (!equal(a[key], b[key])) return false;
|
|
45
|
-
}
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
return a !== a && b !== b;
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// src/workflows/legacy/step.ts
|
|
54
|
-
var LegacyStep = class {
|
|
55
|
-
id;
|
|
56
|
-
description;
|
|
57
|
-
inputSchema;
|
|
58
|
-
outputSchema;
|
|
59
|
-
payload;
|
|
60
|
-
execute;
|
|
61
|
-
retryConfig;
|
|
62
|
-
mastra;
|
|
63
|
-
constructor({
|
|
64
|
-
id,
|
|
65
|
-
description,
|
|
66
|
-
execute,
|
|
67
|
-
payload,
|
|
68
|
-
outputSchema,
|
|
69
|
-
inputSchema,
|
|
70
|
-
retryConfig
|
|
71
|
-
}) {
|
|
72
|
-
this.id = id;
|
|
73
|
-
this.description = description ?? "";
|
|
74
|
-
this.inputSchema = inputSchema;
|
|
75
|
-
this.payload = payload;
|
|
76
|
-
this.outputSchema = outputSchema;
|
|
77
|
-
this.execute = execute;
|
|
78
|
-
this.retryConfig = retryConfig;
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
|
|
82
|
-
// src/workflows/legacy/types.ts
|
|
83
|
-
var WhenConditionReturnValue = /* @__PURE__ */(WhenConditionReturnValue2 => {
|
|
84
|
-
WhenConditionReturnValue2["CONTINUE"] = "continue";
|
|
85
|
-
WhenConditionReturnValue2["CONTINUE_FAILED"] = "continue_failed";
|
|
86
|
-
WhenConditionReturnValue2["ABORT"] = "abort";
|
|
87
|
-
WhenConditionReturnValue2["LIMBO"] = "limbo";
|
|
88
|
-
return WhenConditionReturnValue2;
|
|
89
|
-
})(WhenConditionReturnValue || {});
|
|
90
|
-
|
|
91
|
-
// src/agent/index.ts
|
|
92
|
-
var import_fast_deep_equal = __toESM(require_fast_deep_equal(), 1);
|
|
93
|
-
|
|
94
|
-
// src/agent/save-queue/index.ts
|
|
95
|
-
var SaveQueueManager = class _SaveQueueManager {
|
|
96
|
-
logger;
|
|
97
|
-
debounceMs;
|
|
98
|
-
memory;
|
|
99
|
-
static MAX_STALENESS_MS = 1e3;
|
|
100
|
-
constructor({
|
|
101
|
-
logger,
|
|
102
|
-
debounceMs,
|
|
103
|
-
memory
|
|
104
|
-
}) {
|
|
105
|
-
this.logger = logger;
|
|
106
|
-
this.debounceMs = debounceMs || 100;
|
|
107
|
-
this.memory = memory;
|
|
108
|
-
}
|
|
109
|
-
saveQueues = /* @__PURE__ */new Map();
|
|
110
|
-
saveDebounceTimers = /* @__PURE__ */new Map();
|
|
111
|
-
/**
|
|
112
|
-
* Debounces save operations for a thread, ensuring that consecutive save requests
|
|
113
|
-
* are batched and only the latest is executed after a short delay.
|
|
114
|
-
* @param threadId - The ID of the thread to debounce saves for.
|
|
115
|
-
* @param saveFn - The save function to debounce.
|
|
116
|
-
*/
|
|
117
|
-
debounceSave(threadId, messageList, memoryConfig) {
|
|
118
|
-
if (this.saveDebounceTimers.has(threadId)) {
|
|
119
|
-
clearTimeout(this.saveDebounceTimers.get(threadId));
|
|
120
|
-
}
|
|
121
|
-
this.saveDebounceTimers.set(threadId, setTimeout(() => {
|
|
122
|
-
this.enqueueSave(threadId, messageList, memoryConfig).catch(err => {
|
|
123
|
-
this.logger?.error?.("Error in debounceSave", {
|
|
124
|
-
err,
|
|
125
|
-
threadId
|
|
126
|
-
});
|
|
127
|
-
});
|
|
128
|
-
this.saveDebounceTimers.delete(threadId);
|
|
129
|
-
}, this.debounceMs));
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Enqueues a save operation for a thread, ensuring that saves are executed in order and
|
|
133
|
-
* only one save runs at a time per thread. If a save is already in progress for the thread,
|
|
134
|
-
* the new save is queued to run after the previous completes.
|
|
135
|
-
*
|
|
136
|
-
* @param threadId - The ID of the thread whose messages should be saved.
|
|
137
|
-
* @param messageList - The MessageList instance containing unsaved messages.
|
|
138
|
-
* @param memoryConfig - Optional memory configuration to use for saving.
|
|
139
|
-
*/
|
|
140
|
-
enqueueSave(threadId, messageList, memoryConfig) {
|
|
141
|
-
const prev = this.saveQueues.get(threadId) || Promise.resolve();
|
|
142
|
-
const next = prev.then(() => this.persistUnsavedMessages(messageList, memoryConfig)).catch(err => {
|
|
143
|
-
this.logger?.error?.("Error in enqueueSave", {
|
|
144
|
-
err,
|
|
145
|
-
threadId
|
|
146
|
-
});
|
|
147
|
-
}).then(() => {
|
|
148
|
-
if (this.saveQueues.get(threadId) === next) {
|
|
149
|
-
this.saveQueues.delete(threadId);
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
this.saveQueues.set(threadId, next);
|
|
153
|
-
return next;
|
|
154
|
-
}
|
|
155
|
-
/**
|
|
156
|
-
* Clears any pending debounced save for a thread, preventing the scheduled save
|
|
157
|
-
* from executing if it hasn't already fired.
|
|
158
|
-
*
|
|
159
|
-
* @param threadId - The ID of the thread whose debounced save should be cleared.
|
|
160
|
-
*/
|
|
161
|
-
clearDebounce(threadId) {
|
|
162
|
-
if (this.saveDebounceTimers.has(threadId)) {
|
|
163
|
-
clearTimeout(this.saveDebounceTimers.get(threadId));
|
|
164
|
-
this.saveDebounceTimers.delete(threadId);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Persists any unsaved messages from the MessageList to memory storage.
|
|
169
|
-
* Drains the list of unsaved messages and writes them using the memory backend.
|
|
170
|
-
* @param messageList - The MessageList instance for the current thread.
|
|
171
|
-
* @param memoryConfig - The memory configuration for saving.
|
|
172
|
-
*/
|
|
173
|
-
async persistUnsavedMessages(messageList, memoryConfig) {
|
|
174
|
-
const newMessages = messageList.drainUnsavedMessages();
|
|
175
|
-
if (newMessages.length > 0 && this.memory) {
|
|
176
|
-
await this.memory.saveMessages({
|
|
177
|
-
messages: newMessages,
|
|
178
|
-
memoryConfig
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
/**
|
|
183
|
-
* Batches a save of unsaved messages for a thread, using debouncing to batch rapid updates.
|
|
184
|
-
* If the oldest unsaved message is stale (older than MAX_STALENESS_MS), the save is performed immediately.
|
|
185
|
-
* Otherwise, the save is delayed to batch multiple updates and reduce redundant writes.
|
|
186
|
-
*
|
|
187
|
-
* @param messageList - The MessageList instance containing unsaved messages.
|
|
188
|
-
* @param threadId - The ID of the thread whose messages are being saved.
|
|
189
|
-
* @param memoryConfig - Optional memory configuration for saving.
|
|
190
|
-
*/
|
|
191
|
-
async batchMessages(messageList, threadId, memoryConfig) {
|
|
192
|
-
if (!threadId) return;
|
|
193
|
-
const earliest = messageList.getEarliestUnsavedMessageTimestamp();
|
|
194
|
-
const now = Date.now();
|
|
195
|
-
if (earliest && now - earliest > _SaveQueueManager.MAX_STALENESS_MS) {
|
|
196
|
-
return this.flushMessages(messageList, threadId, memoryConfig);
|
|
197
|
-
} else {
|
|
198
|
-
return this.debounceSave(threadId, messageList, memoryConfig);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Forces an immediate save of unsaved messages for a thread, bypassing any debounce delay.
|
|
203
|
-
* This is used when a flush to persistent storage is required (e.g., on shutdown or critical transitions).
|
|
204
|
-
*
|
|
205
|
-
* @param messageList - The MessageList instance containing unsaved messages.
|
|
206
|
-
* @param threadId - The ID of the thread whose messages are being saved.
|
|
207
|
-
* @param memoryConfig - Optional memory configuration for saving.
|
|
208
|
-
*/
|
|
209
|
-
async flushMessages(messageList, threadId, memoryConfig) {
|
|
210
|
-
if (!threadId) return;
|
|
211
|
-
this.clearDebounce(threadId);
|
|
212
|
-
return this.enqueueSave(threadId, messageList, memoryConfig);
|
|
213
|
-
}
|
|
214
|
-
};
|
|
215
|
-
|
|
216
|
-
// src/agent/index.ts
|
|
217
|
-
function resolveMaybePromise(value, cb) {
|
|
218
|
-
if (value instanceof Promise) {
|
|
219
|
-
return value.then(cb);
|
|
220
|
-
}
|
|
221
|
-
return cb(value);
|
|
222
|
-
}
|
|
223
|
-
function resolveThreadIdFromArgs(args) {
|
|
224
|
-
if (args?.memory?.thread) {
|
|
225
|
-
if (typeof args.memory.thread === "string") return {
|
|
226
|
-
id: args.memory.thread
|
|
227
|
-
};
|
|
228
|
-
if (typeof args.memory.thread === "object" && args.memory.thread.id) return args.memory.thread;
|
|
229
|
-
}
|
|
230
|
-
if (args?.threadId) return {
|
|
231
|
-
id: args.threadId
|
|
232
|
-
};
|
|
233
|
-
return void 0;
|
|
234
|
-
}
|
|
235
|
-
var _Agent_decorators, _init, _a;
|
|
236
|
-
_Agent_decorators = [InstrumentClass({
|
|
237
|
-
prefix: "agent",
|
|
238
|
-
excludeMethods: ["hasOwnMemory", "getMemory", "__primitive", "__registerMastra", "__registerPrimitives", "__setTools", "__setLogger", "__setTelemetry", "log", "getModel", "getInstructions", "getTools", "getLLM", "getWorkflows", "getDefaultGenerateOptions", "getDefaultStreamOptions", "getDescription"]
|
|
239
|
-
})];
|
|
240
|
-
var Agent = class extends (_a = MastraBase) {
|
|
241
|
-
id;
|
|
242
|
-
name;
|
|
243
|
-
#instructions;
|
|
244
|
-
#description;
|
|
245
|
-
model;
|
|
246
|
-
#mastra;
|
|
247
|
-
#memory;
|
|
248
|
-
#workflows;
|
|
249
|
-
#defaultGenerateOptions;
|
|
250
|
-
#defaultStreamOptions;
|
|
251
|
-
#tools;
|
|
252
|
-
/** @deprecated This property is deprecated. Use evals instead. */
|
|
253
|
-
metrics;
|
|
254
|
-
evals;
|
|
255
|
-
#voice;
|
|
256
|
-
constructor(config) {
|
|
257
|
-
super({
|
|
258
|
-
component: RegisteredLogger.AGENT
|
|
259
|
-
});
|
|
260
|
-
this.name = config.name;
|
|
261
|
-
this.id = config.name;
|
|
262
|
-
this.#instructions = config.instructions;
|
|
263
|
-
this.#description = config.description;
|
|
264
|
-
if (!config.model) {
|
|
265
|
-
const mastraError = new MastraError({
|
|
266
|
-
id: "AGENT_CONSTRUCTOR_MODEL_REQUIRED",
|
|
267
|
-
domain: "AGENT" /* AGENT */,
|
|
268
|
-
category: "USER" /* USER */,
|
|
269
|
-
details: {
|
|
270
|
-
agentName: config.name
|
|
271
|
-
},
|
|
272
|
-
text: `LanguageModel is required to create an Agent. Please provide the 'model'.`
|
|
273
|
-
});
|
|
274
|
-
this.logger.trackException(mastraError);
|
|
275
|
-
this.logger.error(mastraError.toString());
|
|
276
|
-
throw mastraError;
|
|
277
|
-
}
|
|
278
|
-
this.model = config.model;
|
|
279
|
-
if (config.workflows) {
|
|
280
|
-
this.#workflows = config.workflows;
|
|
281
|
-
}
|
|
282
|
-
this.#defaultGenerateOptions = config.defaultGenerateOptions || {};
|
|
283
|
-
this.#defaultStreamOptions = config.defaultStreamOptions || {};
|
|
284
|
-
this.#tools = config.tools || {};
|
|
285
|
-
this.metrics = {};
|
|
286
|
-
this.evals = {};
|
|
287
|
-
if (config.mastra) {
|
|
288
|
-
this.__registerMastra(config.mastra);
|
|
289
|
-
this.__registerPrimitives({
|
|
290
|
-
telemetry: config.mastra.getTelemetry(),
|
|
291
|
-
logger: config.mastra.getLogger()
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
if (config.metrics) {
|
|
295
|
-
this.logger.warn("The metrics property is deprecated. Please use evals instead to add evaluation metrics.");
|
|
296
|
-
this.metrics = config.metrics;
|
|
297
|
-
this.evals = config.metrics;
|
|
298
|
-
}
|
|
299
|
-
if (config.evals) {
|
|
300
|
-
this.evals = config.evals;
|
|
301
|
-
}
|
|
302
|
-
if (config.memory) {
|
|
303
|
-
this.#memory = config.memory;
|
|
304
|
-
}
|
|
305
|
-
if (config.voice) {
|
|
306
|
-
this.#voice = config.voice;
|
|
307
|
-
if (typeof config.tools !== "function") {
|
|
308
|
-
this.#voice?.addTools(this.tools);
|
|
309
|
-
}
|
|
310
|
-
if (typeof config.instructions === "string") {
|
|
311
|
-
this.#voice?.addInstructions(config.instructions);
|
|
312
|
-
}
|
|
313
|
-
} else {
|
|
314
|
-
this.#voice = new DefaultVoice();
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
hasOwnMemory() {
|
|
318
|
-
return Boolean(this.#memory);
|
|
319
|
-
}
|
|
320
|
-
getMemory() {
|
|
321
|
-
const memory = this.#memory;
|
|
322
|
-
if (memory && !memory.hasOwnStorage && this.#mastra) {
|
|
323
|
-
const storage = this.#mastra.getStorage();
|
|
324
|
-
if (storage) {
|
|
325
|
-
memory.setStorage(storage);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
return memory;
|
|
329
|
-
}
|
|
330
|
-
get voice() {
|
|
331
|
-
if (typeof this.#instructions === "function") {
|
|
332
|
-
const mastraError = new MastraError({
|
|
333
|
-
id: "AGENT_VOICE_INCOMPATIBLE_WITH_FUNCTION_INSTRUCTIONS",
|
|
334
|
-
domain: "AGENT" /* AGENT */,
|
|
335
|
-
category: "USER" /* USER */,
|
|
336
|
-
details: {
|
|
337
|
-
agentName: this.name
|
|
338
|
-
},
|
|
339
|
-
text: "Voice is not compatible when instructions are a function. Please use getVoice() instead."
|
|
340
|
-
});
|
|
341
|
-
this.logger.trackException(mastraError);
|
|
342
|
-
this.logger.error(mastraError.toString());
|
|
343
|
-
throw mastraError;
|
|
344
|
-
}
|
|
345
|
-
return this.#voice;
|
|
346
|
-
}
|
|
347
|
-
async getWorkflows({
|
|
348
|
-
runtimeContext = new RuntimeContext()
|
|
349
|
-
} = {}) {
|
|
350
|
-
let workflowRecord;
|
|
351
|
-
if (typeof this.#workflows === "function") {
|
|
352
|
-
workflowRecord = await Promise.resolve(this.#workflows({
|
|
353
|
-
runtimeContext
|
|
354
|
-
}));
|
|
355
|
-
} else {
|
|
356
|
-
workflowRecord = this.#workflows ?? {};
|
|
357
|
-
}
|
|
358
|
-
Object.entries(workflowRecord || {}).forEach(([_workflowName, workflow]) => {
|
|
359
|
-
if (this.#mastra) {
|
|
360
|
-
workflow.__registerMastra(this.#mastra);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
return workflowRecord;
|
|
364
|
-
}
|
|
365
|
-
async getVoice({
|
|
366
|
-
runtimeContext
|
|
367
|
-
} = {}) {
|
|
368
|
-
if (this.#voice) {
|
|
369
|
-
const voice = this.#voice;
|
|
370
|
-
voice?.addTools(await this.getTools({
|
|
371
|
-
runtimeContext
|
|
372
|
-
}));
|
|
373
|
-
voice?.addInstructions(await this.getInstructions({
|
|
374
|
-
runtimeContext
|
|
375
|
-
}));
|
|
376
|
-
return voice;
|
|
377
|
-
} else {
|
|
378
|
-
return new DefaultVoice();
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
get instructions() {
|
|
382
|
-
this.logger.warn("The instructions property is deprecated. Please use getInstructions() instead.");
|
|
383
|
-
if (typeof this.#instructions === "function") {
|
|
384
|
-
const mastraError = new MastraError({
|
|
385
|
-
id: "AGENT_INSTRUCTIONS_INCOMPATIBLE_WITH_FUNCTION_INSTRUCTIONS",
|
|
386
|
-
domain: "AGENT" /* AGENT */,
|
|
387
|
-
category: "USER" /* USER */,
|
|
388
|
-
details: {
|
|
389
|
-
agentName: this.name
|
|
390
|
-
},
|
|
391
|
-
text: "Instructions are not compatible when instructions are a function. Please use getInstructions() instead."
|
|
392
|
-
});
|
|
393
|
-
this.logger.trackException(mastraError);
|
|
394
|
-
this.logger.error(mastraError.toString());
|
|
395
|
-
throw mastraError;
|
|
396
|
-
}
|
|
397
|
-
return this.#instructions;
|
|
398
|
-
}
|
|
399
|
-
getInstructions({
|
|
400
|
-
runtimeContext = new RuntimeContext()
|
|
401
|
-
} = {}) {
|
|
402
|
-
if (typeof this.#instructions === "string") {
|
|
403
|
-
return this.#instructions;
|
|
404
|
-
}
|
|
405
|
-
const result = this.#instructions({
|
|
406
|
-
runtimeContext
|
|
407
|
-
});
|
|
408
|
-
return resolveMaybePromise(result, instructions => {
|
|
409
|
-
if (!instructions) {
|
|
410
|
-
const mastraError = new MastraError({
|
|
411
|
-
id: "AGENT_GET_INSTRUCTIONS_FUNCTION_EMPTY_RETURN",
|
|
412
|
-
domain: "AGENT" /* AGENT */,
|
|
413
|
-
category: "USER" /* USER */,
|
|
414
|
-
details: {
|
|
415
|
-
agentName: this.name
|
|
416
|
-
},
|
|
417
|
-
text: "Instructions are required to use an Agent. The function-based instructions returned an empty value."
|
|
418
|
-
});
|
|
419
|
-
this.logger.trackException(mastraError);
|
|
420
|
-
this.logger.error(mastraError.toString());
|
|
421
|
-
throw mastraError;
|
|
422
|
-
}
|
|
423
|
-
return instructions;
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
getDescription() {
|
|
427
|
-
return this.#description ?? "";
|
|
428
|
-
}
|
|
429
|
-
getDefaultGenerateOptions({
|
|
430
|
-
runtimeContext = new RuntimeContext()
|
|
431
|
-
} = {}) {
|
|
432
|
-
if (typeof this.#defaultGenerateOptions !== "function") {
|
|
433
|
-
return this.#defaultGenerateOptions;
|
|
434
|
-
}
|
|
435
|
-
const result = this.#defaultGenerateOptions({
|
|
436
|
-
runtimeContext
|
|
437
|
-
});
|
|
438
|
-
return resolveMaybePromise(result, options => {
|
|
439
|
-
if (!options) {
|
|
440
|
-
const mastraError = new MastraError({
|
|
441
|
-
id: "AGENT_GET_DEFAULT_GENERATE_OPTIONS_FUNCTION_EMPTY_RETURN",
|
|
442
|
-
domain: "AGENT" /* AGENT */,
|
|
443
|
-
category: "USER" /* USER */,
|
|
444
|
-
details: {
|
|
445
|
-
agentName: this.name
|
|
446
|
-
},
|
|
447
|
-
text: `[Agent:${this.name}] - Function-based default generate options returned empty value`
|
|
448
|
-
});
|
|
449
|
-
this.logger.trackException(mastraError);
|
|
450
|
-
this.logger.error(mastraError.toString());
|
|
451
|
-
throw mastraError;
|
|
452
|
-
}
|
|
453
|
-
return options;
|
|
454
|
-
});
|
|
455
|
-
}
|
|
456
|
-
getDefaultStreamOptions({
|
|
457
|
-
runtimeContext = new RuntimeContext()
|
|
458
|
-
} = {}) {
|
|
459
|
-
if (typeof this.#defaultStreamOptions !== "function") {
|
|
460
|
-
return this.#defaultStreamOptions;
|
|
461
|
-
}
|
|
462
|
-
const result = this.#defaultStreamOptions({
|
|
463
|
-
runtimeContext
|
|
464
|
-
});
|
|
465
|
-
return resolveMaybePromise(result, options => {
|
|
466
|
-
if (!options) {
|
|
467
|
-
const mastraError = new MastraError({
|
|
468
|
-
id: "AGENT_GET_DEFAULT_STREAM_OPTIONS_FUNCTION_EMPTY_RETURN",
|
|
469
|
-
domain: "AGENT" /* AGENT */,
|
|
470
|
-
category: "USER" /* USER */,
|
|
471
|
-
details: {
|
|
472
|
-
agentName: this.name
|
|
473
|
-
},
|
|
474
|
-
text: `[Agent:${this.name}] - Function-based default stream options returned empty value`
|
|
475
|
-
});
|
|
476
|
-
this.logger.trackException(mastraError);
|
|
477
|
-
this.logger.error(mastraError.toString());
|
|
478
|
-
throw mastraError;
|
|
479
|
-
}
|
|
480
|
-
return options;
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
get tools() {
|
|
484
|
-
this.logger.warn("The tools property is deprecated. Please use getTools() instead.");
|
|
485
|
-
if (typeof this.#tools === "function") {
|
|
486
|
-
const mastraError = new MastraError({
|
|
487
|
-
id: "AGENT_GET_TOOLS_FUNCTION_INCOMPATIBLE_WITH_TOOL_FUNCTION_TYPE",
|
|
488
|
-
domain: "AGENT" /* AGENT */,
|
|
489
|
-
category: "USER" /* USER */,
|
|
490
|
-
details: {
|
|
491
|
-
agentName: this.name
|
|
492
|
-
},
|
|
493
|
-
text: "Tools are not compatible when tools are a function. Please use getTools() instead."
|
|
494
|
-
});
|
|
495
|
-
this.logger.trackException(mastraError);
|
|
496
|
-
this.logger.error(mastraError.toString());
|
|
497
|
-
throw mastraError;
|
|
498
|
-
}
|
|
499
|
-
return ensureToolProperties(this.#tools);
|
|
500
|
-
}
|
|
501
|
-
getTools({
|
|
502
|
-
runtimeContext = new RuntimeContext()
|
|
503
|
-
} = {}) {
|
|
504
|
-
if (typeof this.#tools !== "function") {
|
|
505
|
-
return ensureToolProperties(this.#tools);
|
|
506
|
-
}
|
|
507
|
-
const result = this.#tools({
|
|
508
|
-
runtimeContext
|
|
509
|
-
});
|
|
510
|
-
return resolveMaybePromise(result, tools => {
|
|
511
|
-
if (!tools) {
|
|
512
|
-
const mastraError = new MastraError({
|
|
513
|
-
id: "AGENT_GET_TOOLS_FUNCTION_EMPTY_RETURN",
|
|
514
|
-
domain: "AGENT" /* AGENT */,
|
|
515
|
-
category: "USER" /* USER */,
|
|
516
|
-
details: {
|
|
517
|
-
agentName: this.name
|
|
518
|
-
},
|
|
519
|
-
text: `[Agent:${this.name}] - Function-based tools returned empty value`
|
|
520
|
-
});
|
|
521
|
-
this.logger.trackException(mastraError);
|
|
522
|
-
this.logger.error(mastraError.toString());
|
|
523
|
-
throw mastraError;
|
|
524
|
-
}
|
|
525
|
-
return ensureToolProperties(tools);
|
|
526
|
-
});
|
|
527
|
-
}
|
|
528
|
-
get llm() {
|
|
529
|
-
this.logger.warn("The llm property is deprecated. Please use getLLM() instead.");
|
|
530
|
-
if (typeof this.model === "function") {
|
|
531
|
-
const mastraError = new MastraError({
|
|
532
|
-
id: "AGENT_LLM_GETTER_INCOMPATIBLE_WITH_FUNCTION_MODEL",
|
|
533
|
-
domain: "AGENT" /* AGENT */,
|
|
534
|
-
category: "USER" /* USER */,
|
|
535
|
-
details: {
|
|
536
|
-
agentName: this.name
|
|
537
|
-
},
|
|
538
|
-
text: "LLM is not compatible when model is a function. Please use getLLM() instead."
|
|
539
|
-
});
|
|
540
|
-
this.logger.trackException(mastraError);
|
|
541
|
-
this.logger.error(mastraError.toString());
|
|
542
|
-
throw mastraError;
|
|
543
|
-
}
|
|
544
|
-
return this.getLLM();
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Gets or creates an LLM instance based on the current model
|
|
548
|
-
* @param options Options for getting the LLM
|
|
549
|
-
* @returns A promise that resolves to the LLM instance
|
|
550
|
-
*/
|
|
551
|
-
getLLM({
|
|
552
|
-
runtimeContext = new RuntimeContext(),
|
|
553
|
-
model
|
|
554
|
-
} = {}) {
|
|
555
|
-
const modelToUse = model ? typeof model === "function" ? model({
|
|
556
|
-
runtimeContext
|
|
557
|
-
}) : model : this.getModel({
|
|
558
|
-
runtimeContext
|
|
559
|
-
});
|
|
560
|
-
return resolveMaybePromise(modelToUse, resolvedModel => {
|
|
561
|
-
const llm = new MastraLLM({
|
|
562
|
-
model: resolvedModel,
|
|
563
|
-
mastra: this.#mastra
|
|
564
|
-
});
|
|
565
|
-
if (this.#primitives) {
|
|
566
|
-
llm.__registerPrimitives(this.#primitives);
|
|
567
|
-
}
|
|
568
|
-
if (this.#mastra) {
|
|
569
|
-
llm.__registerMastra(this.#mastra);
|
|
570
|
-
}
|
|
571
|
-
return llm;
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
/**
|
|
575
|
-
* Gets the model, resolving it if it's a function
|
|
576
|
-
* @param options Options for getting the model
|
|
577
|
-
* @returns A promise that resolves to the model
|
|
578
|
-
*/
|
|
579
|
-
getModel({
|
|
580
|
-
runtimeContext = new RuntimeContext()
|
|
581
|
-
} = {}) {
|
|
582
|
-
if (typeof this.model !== "function") {
|
|
583
|
-
if (!this.model) {
|
|
584
|
-
const mastraError = new MastraError({
|
|
585
|
-
id: "AGENT_GET_MODEL_MISSING_MODEL_INSTANCE",
|
|
586
|
-
domain: "AGENT" /* AGENT */,
|
|
587
|
-
category: "USER" /* USER */,
|
|
588
|
-
details: {
|
|
589
|
-
agentName: this.name
|
|
590
|
-
},
|
|
591
|
-
text: `[Agent:${this.name}] - No model provided`
|
|
592
|
-
});
|
|
593
|
-
this.logger.trackException(mastraError);
|
|
594
|
-
this.logger.error(mastraError.toString());
|
|
595
|
-
throw mastraError;
|
|
596
|
-
}
|
|
597
|
-
return this.model;
|
|
598
|
-
}
|
|
599
|
-
const result = this.model({
|
|
600
|
-
runtimeContext
|
|
601
|
-
});
|
|
602
|
-
return resolveMaybePromise(result, model => {
|
|
603
|
-
if (!model) {
|
|
604
|
-
const mastraError = new MastraError({
|
|
605
|
-
id: "AGENT_GET_MODEL_FUNCTION_EMPTY_RETURN",
|
|
606
|
-
domain: "AGENT" /* AGENT */,
|
|
607
|
-
category: "USER" /* USER */,
|
|
608
|
-
details: {
|
|
609
|
-
agentName: this.name
|
|
610
|
-
},
|
|
611
|
-
text: `[Agent:${this.name}] - Function-based model returned empty value`
|
|
612
|
-
});
|
|
613
|
-
this.logger.trackException(mastraError);
|
|
614
|
-
this.logger.error(mastraError.toString());
|
|
615
|
-
throw mastraError;
|
|
616
|
-
}
|
|
617
|
-
return model;
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
__updateInstructions(newInstructions) {
|
|
621
|
-
this.#instructions = newInstructions;
|
|
622
|
-
this.logger.debug(`[Agents:${this.name}] Instructions updated.`, {
|
|
623
|
-
model: this.model,
|
|
624
|
-
name: this.name
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
#primitives;
|
|
628
|
-
__registerPrimitives(p) {
|
|
629
|
-
if (p.telemetry) {
|
|
630
|
-
this.__setTelemetry(p.telemetry);
|
|
631
|
-
}
|
|
632
|
-
if (p.logger) {
|
|
633
|
-
this.__setLogger(p.logger);
|
|
634
|
-
}
|
|
635
|
-
this.#primitives = p;
|
|
636
|
-
this.logger.debug(`[Agents:${this.name}] initialized.`, {
|
|
637
|
-
model: this.model,
|
|
638
|
-
name: this.name
|
|
639
|
-
});
|
|
640
|
-
}
|
|
641
|
-
__registerMastra(mastra) {
|
|
642
|
-
this.#mastra = mastra;
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Set the concrete tools for the agent
|
|
646
|
-
* @param tools
|
|
647
|
-
*/
|
|
648
|
-
__setTools(tools) {
|
|
649
|
-
this.#tools = tools;
|
|
650
|
-
this.logger.debug(`[Agents:${this.name}] Tools set for agent ${this.name}`, {
|
|
651
|
-
model: this.model,
|
|
652
|
-
name: this.name
|
|
653
|
-
});
|
|
654
|
-
}
|
|
655
|
-
async generateTitleFromUserMessage({
|
|
656
|
-
message,
|
|
657
|
-
runtimeContext = new RuntimeContext(),
|
|
658
|
-
model,
|
|
659
|
-
instructions
|
|
660
|
-
}) {
|
|
661
|
-
const llm = await this.getLLM({
|
|
662
|
-
runtimeContext,
|
|
663
|
-
model
|
|
664
|
-
});
|
|
665
|
-
const normMessage = new MessageList().add(message, "user").get.all.ui().at(-1);
|
|
666
|
-
if (!normMessage) {
|
|
667
|
-
throw new Error(`Could not generate title from input ${JSON.stringify(message)}`);
|
|
668
|
-
}
|
|
669
|
-
const partsToGen = [];
|
|
670
|
-
for (const part of normMessage.parts) {
|
|
671
|
-
if (part.type === `text`) {
|
|
672
|
-
partsToGen.push(part);
|
|
673
|
-
} else if (part.type === `source`) {
|
|
674
|
-
partsToGen.push({
|
|
675
|
-
type: "text",
|
|
676
|
-
text: `User added URL: ${part.source.url.substring(0, 100)}`
|
|
677
|
-
});
|
|
678
|
-
} else if (part.type === `file`) {
|
|
679
|
-
partsToGen.push({
|
|
680
|
-
type: "text",
|
|
681
|
-
text: `User added ${part.mimeType} file: ${part.data.substring(0, 100)}`
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
const systemInstructions = await this.resolveTitleInstructions(runtimeContext, instructions);
|
|
686
|
-
const {
|
|
687
|
-
text
|
|
688
|
-
} = await llm.__text({
|
|
689
|
-
runtimeContext,
|
|
690
|
-
messages: [{
|
|
691
|
-
role: "system",
|
|
692
|
-
content: systemInstructions
|
|
693
|
-
}, {
|
|
694
|
-
role: "user",
|
|
695
|
-
content: JSON.stringify(partsToGen)
|
|
696
|
-
}]
|
|
697
|
-
});
|
|
698
|
-
const cleanedText = text.replace(/<think>[\s\S]*?<\/think>/g, "").trim();
|
|
699
|
-
return cleanedText;
|
|
700
|
-
}
|
|
701
|
-
getMostRecentUserMessage(messages) {
|
|
702
|
-
const userMessages = messages.filter(message => message.role === "user");
|
|
703
|
-
return userMessages.at(-1);
|
|
704
|
-
}
|
|
705
|
-
async genTitle(userMessage, runtimeContext, model, instructions) {
|
|
706
|
-
try {
|
|
707
|
-
if (userMessage) {
|
|
708
|
-
const normMessage = new MessageList().add(userMessage, "user").get.all.ui().at(-1);
|
|
709
|
-
if (normMessage) {
|
|
710
|
-
return await this.generateTitleFromUserMessage({
|
|
711
|
-
message: normMessage,
|
|
712
|
-
runtimeContext,
|
|
713
|
-
model,
|
|
714
|
-
instructions
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
return `New Thread ${(/* @__PURE__ */new Date()).toISOString()}`;
|
|
719
|
-
} catch (e) {
|
|
720
|
-
this.logger.error("Error generating title:", e);
|
|
721
|
-
return void 0;
|
|
722
|
-
}
|
|
723
|
-
}
|
|
724
|
-
/* @deprecated use agent.getMemory() and query memory directly */
|
|
725
|
-
async fetchMemory({
|
|
726
|
-
threadId,
|
|
727
|
-
thread: passedThread,
|
|
728
|
-
memoryConfig,
|
|
729
|
-
resourceId,
|
|
730
|
-
runId,
|
|
731
|
-
userMessages,
|
|
732
|
-
systemMessage,
|
|
733
|
-
messageList = new MessageList({
|
|
734
|
-
threadId,
|
|
735
|
-
resourceId
|
|
736
|
-
})
|
|
737
|
-
}) {
|
|
738
|
-
const memory = this.getMemory();
|
|
739
|
-
if (memory) {
|
|
740
|
-
const thread = passedThread ?? (await memory.getThreadById({
|
|
741
|
-
threadId
|
|
742
|
-
}));
|
|
743
|
-
if (!thread) {
|
|
744
|
-
return {
|
|
745
|
-
threadId: threadId || "",
|
|
746
|
-
messages: userMessages || []
|
|
747
|
-
};
|
|
748
|
-
}
|
|
749
|
-
if (userMessages && userMessages.length > 0) {
|
|
750
|
-
messageList.add(userMessages, "memory");
|
|
751
|
-
}
|
|
752
|
-
if (systemMessage?.role === "system") {
|
|
753
|
-
messageList.addSystem(systemMessage, "memory");
|
|
754
|
-
}
|
|
755
|
-
const [memoryMessages, memorySystemMessage] = threadId && memory ? await Promise.all([memory.rememberMessages({
|
|
756
|
-
threadId,
|
|
757
|
-
resourceId,
|
|
758
|
-
config: memoryConfig,
|
|
759
|
-
vectorMessageSearch: messageList.getLatestUserContent() || ""
|
|
760
|
-
}).then(r => r.messagesV2), memory.getSystemMessage({
|
|
761
|
-
threadId,
|
|
762
|
-
memoryConfig
|
|
763
|
-
})]) : [[], null];
|
|
764
|
-
this.logger.debug("Fetched messages from memory", {
|
|
765
|
-
threadId,
|
|
766
|
-
runId,
|
|
767
|
-
fetchedCount: memoryMessages.length
|
|
768
|
-
});
|
|
769
|
-
if (memorySystemMessage) {
|
|
770
|
-
messageList.addSystem(memorySystemMessage, "memory");
|
|
771
|
-
}
|
|
772
|
-
messageList.add(memoryMessages, "memory");
|
|
773
|
-
const systemMessages = messageList.getSystemMessages()?.map(m => m.content)?.join(`
|
|
774
|
-
`) ?? void 0;
|
|
775
|
-
const newMessages = messageList.get.input.v1();
|
|
776
|
-
const processedMemoryMessages = memory.processMessages({
|
|
777
|
-
// these will be processed
|
|
778
|
-
messages: messageList.get.remembered.v1(),
|
|
779
|
-
// these are here for inspecting but shouldn't be returned by the processor
|
|
780
|
-
// - ex TokenLimiter needs to measure all tokens even though it's only processing remembered messages
|
|
781
|
-
newMessages,
|
|
782
|
-
systemMessage: systemMessages,
|
|
783
|
-
memorySystemMessage: memorySystemMessage || void 0
|
|
784
|
-
});
|
|
785
|
-
const returnList = new MessageList().addSystem(systemMessages).add(processedMemoryMessages, "memory").add(newMessages, "user");
|
|
786
|
-
return {
|
|
787
|
-
threadId: thread.id,
|
|
788
|
-
messages: returnList.get.all.prompt()
|
|
789
|
-
};
|
|
790
|
-
}
|
|
791
|
-
return {
|
|
792
|
-
threadId: threadId || "",
|
|
793
|
-
messages: userMessages || []
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
async getMemoryTools({
|
|
797
|
-
runId,
|
|
798
|
-
resourceId,
|
|
799
|
-
threadId,
|
|
800
|
-
runtimeContext,
|
|
801
|
-
mastraProxy
|
|
802
|
-
}) {
|
|
803
|
-
let convertedMemoryTools = {};
|
|
804
|
-
const memory = this.getMemory();
|
|
805
|
-
const memoryTools = memory?.getTools?.();
|
|
806
|
-
if (memoryTools) {
|
|
807
|
-
const memoryToolEntries = await Promise.all(Object.entries(memoryTools).map(async ([k, tool]) => {
|
|
808
|
-
return [k, {
|
|
809
|
-
description: tool.description,
|
|
810
|
-
parameters: tool.parameters,
|
|
811
|
-
execute: typeof tool?.execute === "function" ? async (args, options) => {
|
|
812
|
-
try {
|
|
813
|
-
this.logger.debug(`[Agent:${this.name}] - Executing memory tool ${k}`, {
|
|
814
|
-
name: k,
|
|
815
|
-
description: tool.description,
|
|
816
|
-
args,
|
|
817
|
-
runId,
|
|
818
|
-
threadId,
|
|
819
|
-
resourceId
|
|
820
|
-
});
|
|
821
|
-
return tool?.execute?.({
|
|
822
|
-
context: args,
|
|
823
|
-
mastra: mastraProxy,
|
|
824
|
-
memory,
|
|
825
|
-
runId,
|
|
826
|
-
threadId,
|
|
827
|
-
resourceId,
|
|
828
|
-
logger: this.logger,
|
|
829
|
-
agentName: this.name,
|
|
830
|
-
runtimeContext
|
|
831
|
-
}, options) ?? void 0;
|
|
832
|
-
} catch (err) {
|
|
833
|
-
const mastraError = new MastraError({
|
|
834
|
-
id: "AGENT_MEMORY_TOOL_EXECUTION_FAILED",
|
|
835
|
-
domain: "AGENT" /* AGENT */,
|
|
836
|
-
category: "USER" /* USER */,
|
|
837
|
-
details: {
|
|
838
|
-
agentName: this.name,
|
|
839
|
-
runId: runId || "",
|
|
840
|
-
threadId: threadId || "",
|
|
841
|
-
resourceId: resourceId || ""
|
|
842
|
-
},
|
|
843
|
-
text: `[Agent:${this.name}] - Failed memory tool execution`
|
|
844
|
-
}, err);
|
|
845
|
-
this.logger.trackException(mastraError);
|
|
846
|
-
this.logger.error(mastraError.toString());
|
|
847
|
-
throw mastraError;
|
|
848
|
-
}
|
|
849
|
-
} : void 0
|
|
850
|
-
}];
|
|
851
|
-
}));
|
|
852
|
-
convertedMemoryTools = Object.fromEntries(memoryToolEntries.filter(entry => Boolean(entry)));
|
|
853
|
-
}
|
|
854
|
-
return convertedMemoryTools;
|
|
855
|
-
}
|
|
856
|
-
async getMemoryMessages({
|
|
857
|
-
resourceId,
|
|
858
|
-
threadId,
|
|
859
|
-
vectorMessageSearch,
|
|
860
|
-
memoryConfig
|
|
861
|
-
}) {
|
|
862
|
-
const memory = this.getMemory();
|
|
863
|
-
if (!memory) {
|
|
864
|
-
return [];
|
|
865
|
-
}
|
|
866
|
-
return memory.rememberMessages({
|
|
867
|
-
threadId,
|
|
868
|
-
resourceId,
|
|
869
|
-
config: memoryConfig,
|
|
870
|
-
// The new user messages aren't in the list yet cause we add memory messages first to try to make sure ordering is correct (memory comes before new user messages)
|
|
871
|
-
vectorMessageSearch
|
|
872
|
-
}).then(r => r.messagesV2);
|
|
873
|
-
}
|
|
874
|
-
async getAssignedTools({
|
|
875
|
-
runtimeContext,
|
|
876
|
-
runId,
|
|
877
|
-
resourceId,
|
|
878
|
-
threadId,
|
|
879
|
-
mastraProxy
|
|
880
|
-
}) {
|
|
881
|
-
let toolsForRequest = {};
|
|
882
|
-
this.logger.debug(`[Agents:${this.name}] - Assembling assigned tools`, {
|
|
883
|
-
runId,
|
|
884
|
-
threadId,
|
|
885
|
-
resourceId
|
|
886
|
-
});
|
|
887
|
-
const memory = this.getMemory();
|
|
888
|
-
const assignedTools = await this.getTools({
|
|
889
|
-
runtimeContext
|
|
890
|
-
});
|
|
891
|
-
const assignedToolEntries = Object.entries(assignedTools || {});
|
|
892
|
-
const assignedCoreToolEntries = await Promise.all(assignedToolEntries.map(async ([k, tool]) => {
|
|
893
|
-
if (!tool) {
|
|
894
|
-
return;
|
|
895
|
-
}
|
|
896
|
-
const options = {
|
|
897
|
-
name: k,
|
|
898
|
-
runId,
|
|
899
|
-
threadId,
|
|
900
|
-
resourceId,
|
|
901
|
-
logger: this.logger,
|
|
902
|
-
mastra: mastraProxy,
|
|
903
|
-
memory,
|
|
904
|
-
agentName: this.name,
|
|
905
|
-
runtimeContext,
|
|
906
|
-
model: typeof this.model === "function" ? await this.getModel({
|
|
907
|
-
runtimeContext
|
|
908
|
-
}) : this.model
|
|
909
|
-
};
|
|
910
|
-
return [k, makeCoreTool(tool, options)];
|
|
911
|
-
}));
|
|
912
|
-
const assignedToolEntriesConverted = Object.fromEntries(assignedCoreToolEntries.filter(entry => Boolean(entry)));
|
|
913
|
-
toolsForRequest = {
|
|
914
|
-
...assignedToolEntriesConverted
|
|
915
|
-
};
|
|
916
|
-
return toolsForRequest;
|
|
917
|
-
}
|
|
918
|
-
async getToolsets({
|
|
919
|
-
runId,
|
|
920
|
-
threadId,
|
|
921
|
-
resourceId,
|
|
922
|
-
toolsets,
|
|
923
|
-
runtimeContext,
|
|
924
|
-
mastraProxy
|
|
925
|
-
}) {
|
|
926
|
-
let toolsForRequest = {};
|
|
927
|
-
const memory = this.getMemory();
|
|
928
|
-
const toolsFromToolsets = Object.values(toolsets || {});
|
|
929
|
-
if (toolsFromToolsets.length > 0) {
|
|
930
|
-
this.logger.debug(`[Agent:${this.name}] - Adding tools from toolsets ${Object.keys(toolsets || {}).join(", ")}`, {
|
|
931
|
-
runId
|
|
932
|
-
});
|
|
933
|
-
for (const toolset of toolsFromToolsets) {
|
|
934
|
-
for (const [toolName, tool] of Object.entries(toolset)) {
|
|
935
|
-
const toolObj = tool;
|
|
936
|
-
const options = {
|
|
937
|
-
name: toolName,
|
|
938
|
-
runId,
|
|
939
|
-
threadId,
|
|
940
|
-
resourceId,
|
|
941
|
-
logger: this.logger,
|
|
942
|
-
mastra: mastraProxy,
|
|
943
|
-
memory,
|
|
944
|
-
agentName: this.name,
|
|
945
|
-
runtimeContext,
|
|
946
|
-
model: typeof this.model === "function" ? await this.getModel({
|
|
947
|
-
runtimeContext
|
|
948
|
-
}) : this.model
|
|
949
|
-
};
|
|
950
|
-
const convertedToCoreTool = makeCoreTool(toolObj, options, "toolset");
|
|
951
|
-
toolsForRequest[toolName] = convertedToCoreTool;
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
return toolsForRequest;
|
|
956
|
-
}
|
|
957
|
-
async getClientTools({
|
|
958
|
-
runId,
|
|
959
|
-
threadId,
|
|
960
|
-
resourceId,
|
|
961
|
-
runtimeContext,
|
|
962
|
-
mastraProxy,
|
|
963
|
-
clientTools
|
|
964
|
-
}) {
|
|
965
|
-
let toolsForRequest = {};
|
|
966
|
-
const memory = this.getMemory();
|
|
967
|
-
const clientToolsForInput = Object.entries(clientTools || {});
|
|
968
|
-
if (clientToolsForInput.length > 0) {
|
|
969
|
-
this.logger.debug(`[Agent:${this.name}] - Adding client tools ${Object.keys(clientTools || {}).join(", ")}`, {
|
|
970
|
-
runId
|
|
971
|
-
});
|
|
972
|
-
for (const [toolName, tool] of clientToolsForInput) {
|
|
973
|
-
const {
|
|
974
|
-
execute,
|
|
975
|
-
...rest
|
|
976
|
-
} = tool;
|
|
977
|
-
const options = {
|
|
978
|
-
name: toolName,
|
|
979
|
-
runId,
|
|
980
|
-
threadId,
|
|
981
|
-
resourceId,
|
|
982
|
-
logger: this.logger,
|
|
983
|
-
mastra: mastraProxy,
|
|
984
|
-
memory,
|
|
985
|
-
agentName: this.name,
|
|
986
|
-
runtimeContext,
|
|
987
|
-
model: typeof this.model === "function" ? await this.getModel({
|
|
988
|
-
runtimeContext
|
|
989
|
-
}) : this.model
|
|
990
|
-
};
|
|
991
|
-
const convertedToCoreTool = makeCoreTool(rest, options, "client-tool");
|
|
992
|
-
toolsForRequest[toolName] = convertedToCoreTool;
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
return toolsForRequest;
|
|
996
|
-
}
|
|
997
|
-
async getWorkflowTools({
|
|
998
|
-
runId,
|
|
999
|
-
threadId,
|
|
1000
|
-
resourceId,
|
|
1001
|
-
runtimeContext
|
|
1002
|
-
}) {
|
|
1003
|
-
let convertedWorkflowTools = {};
|
|
1004
|
-
const workflows = await this.getWorkflows({
|
|
1005
|
-
runtimeContext
|
|
1006
|
-
});
|
|
1007
|
-
if (Object.keys(workflows).length > 0) {
|
|
1008
|
-
convertedWorkflowTools = Object.entries(workflows).reduce((memo, [workflowName, workflow]) => {
|
|
1009
|
-
memo[workflowName] = {
|
|
1010
|
-
description: workflow.description || `Workflow: ${workflowName}`,
|
|
1011
|
-
parameters: workflow.inputSchema || {
|
|
1012
|
-
type: "object",
|
|
1013
|
-
properties: {}
|
|
1014
|
-
},
|
|
1015
|
-
execute: async args => {
|
|
1016
|
-
try {
|
|
1017
|
-
this.logger.debug(`[Agent:${this.name}] - Executing workflow as tool ${workflowName}`, {
|
|
1018
|
-
name: workflowName,
|
|
1019
|
-
description: workflow.description,
|
|
1020
|
-
args,
|
|
1021
|
-
runId,
|
|
1022
|
-
threadId,
|
|
1023
|
-
resourceId
|
|
1024
|
-
});
|
|
1025
|
-
const run = workflow.createRun();
|
|
1026
|
-
const result = await run.start({
|
|
1027
|
-
inputData: args,
|
|
1028
|
-
runtimeContext
|
|
1029
|
-
});
|
|
1030
|
-
return result;
|
|
1031
|
-
} catch (err) {
|
|
1032
|
-
const mastraError = new MastraError({
|
|
1033
|
-
id: "AGENT_WORKFLOW_TOOL_EXECUTION_FAILED",
|
|
1034
|
-
domain: "AGENT" /* AGENT */,
|
|
1035
|
-
category: "USER" /* USER */,
|
|
1036
|
-
details: {
|
|
1037
|
-
agentName: this.name,
|
|
1038
|
-
runId: runId || "",
|
|
1039
|
-
threadId: threadId || "",
|
|
1040
|
-
resourceId: resourceId || ""
|
|
1041
|
-
},
|
|
1042
|
-
text: `[Agent:${this.name}] - Failed workflow tool execution`
|
|
1043
|
-
}, err);
|
|
1044
|
-
this.logger.trackException(mastraError);
|
|
1045
|
-
this.logger.error(mastraError.toString());
|
|
1046
|
-
throw mastraError;
|
|
1047
|
-
}
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
|
-
return memo;
|
|
1051
|
-
}, {});
|
|
1052
|
-
}
|
|
1053
|
-
return convertedWorkflowTools;
|
|
1054
|
-
}
|
|
1055
|
-
async convertTools({
|
|
1056
|
-
toolsets,
|
|
1057
|
-
clientTools,
|
|
1058
|
-
threadId,
|
|
1059
|
-
resourceId,
|
|
1060
|
-
runId,
|
|
1061
|
-
runtimeContext
|
|
1062
|
-
}) {
|
|
1063
|
-
let mastraProxy = void 0;
|
|
1064
|
-
const logger = this.logger;
|
|
1065
|
-
if (this.#mastra) {
|
|
1066
|
-
mastraProxy = createMastraProxy({
|
|
1067
|
-
mastra: this.#mastra,
|
|
1068
|
-
logger
|
|
1069
|
-
});
|
|
1070
|
-
}
|
|
1071
|
-
const assignedTools = await this.getAssignedTools({
|
|
1072
|
-
runId,
|
|
1073
|
-
resourceId,
|
|
1074
|
-
threadId,
|
|
1075
|
-
runtimeContext,
|
|
1076
|
-
mastraProxy
|
|
1077
|
-
});
|
|
1078
|
-
const memoryTools = await this.getMemoryTools({
|
|
1079
|
-
runId,
|
|
1080
|
-
resourceId,
|
|
1081
|
-
threadId,
|
|
1082
|
-
runtimeContext,
|
|
1083
|
-
mastraProxy
|
|
1084
|
-
});
|
|
1085
|
-
const toolsetTools = await this.getToolsets({
|
|
1086
|
-
runId,
|
|
1087
|
-
resourceId,
|
|
1088
|
-
threadId,
|
|
1089
|
-
runtimeContext,
|
|
1090
|
-
mastraProxy,
|
|
1091
|
-
toolsets
|
|
1092
|
-
});
|
|
1093
|
-
const clientsideTools = await this.getClientTools({
|
|
1094
|
-
runId,
|
|
1095
|
-
resourceId,
|
|
1096
|
-
threadId,
|
|
1097
|
-
runtimeContext,
|
|
1098
|
-
mastraProxy,
|
|
1099
|
-
clientTools
|
|
1100
|
-
});
|
|
1101
|
-
const workflowTools = await this.getWorkflowTools({
|
|
1102
|
-
runId,
|
|
1103
|
-
resourceId,
|
|
1104
|
-
threadId,
|
|
1105
|
-
runtimeContext
|
|
1106
|
-
});
|
|
1107
|
-
return {
|
|
1108
|
-
...assignedTools,
|
|
1109
|
-
...memoryTools,
|
|
1110
|
-
...toolsetTools,
|
|
1111
|
-
...clientsideTools,
|
|
1112
|
-
...workflowTools
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
|
-
/**
|
|
1116
|
-
* Adds response messages from a step to the MessageList and schedules persistence.
|
|
1117
|
-
* This is used for incremental saving: after each agent step, messages are added to a save queue
|
|
1118
|
-
* and a debounced save operation is triggered to avoid redundant writes.
|
|
1119
|
-
*
|
|
1120
|
-
* @param result - The step result containing response messages.
|
|
1121
|
-
* @param messageList - The MessageList instance for the current thread.
|
|
1122
|
-
* @param threadId - The thread ID.
|
|
1123
|
-
* @param memoryConfig - The memory configuration for saving.
|
|
1124
|
-
* @param runId - (Optional) The run ID for logging.
|
|
1125
|
-
*/
|
|
1126
|
-
async saveStepMessages({
|
|
1127
|
-
saveQueueManager,
|
|
1128
|
-
result,
|
|
1129
|
-
messageList,
|
|
1130
|
-
threadId,
|
|
1131
|
-
memoryConfig,
|
|
1132
|
-
runId
|
|
1133
|
-
}) {
|
|
1134
|
-
try {
|
|
1135
|
-
messageList.add(result.response.messages, "response");
|
|
1136
|
-
await saveQueueManager.batchMessages(messageList, threadId, memoryConfig);
|
|
1137
|
-
} catch (e) {
|
|
1138
|
-
await saveQueueManager.flushMessages(messageList, threadId, memoryConfig);
|
|
1139
|
-
this.logger.error("Error saving memory on step finish", {
|
|
1140
|
-
error: e,
|
|
1141
|
-
runId
|
|
1142
|
-
});
|
|
1143
|
-
throw e;
|
|
1144
|
-
}
|
|
1145
|
-
}
|
|
1146
|
-
__primitive({
|
|
1147
|
-
instructions,
|
|
1148
|
-
messages,
|
|
1149
|
-
context,
|
|
1150
|
-
thread,
|
|
1151
|
-
memoryConfig,
|
|
1152
|
-
resourceId,
|
|
1153
|
-
runId,
|
|
1154
|
-
toolsets,
|
|
1155
|
-
clientTools,
|
|
1156
|
-
runtimeContext,
|
|
1157
|
-
generateMessageId,
|
|
1158
|
-
saveQueueManager
|
|
1159
|
-
}) {
|
|
1160
|
-
return {
|
|
1161
|
-
before: async () => {
|
|
1162
|
-
if (process.env.NODE_ENV !== "test") {
|
|
1163
|
-
this.logger.debug(`[Agents:${this.name}] - Starting generation`, {
|
|
1164
|
-
runId
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
const memory = this.getMemory();
|
|
1168
|
-
const toolEnhancements = [
|
|
1169
|
-
// toolsets
|
|
1170
|
-
toolsets && Object.keys(toolsets || {}).length > 0 ? `toolsets present (${Object.keys(toolsets || {}).length} tools)` : void 0,
|
|
1171
|
-
// memory tools
|
|
1172
|
-
memory && resourceId ? "memory and resourceId available" : void 0].filter(Boolean).join(", ");
|
|
1173
|
-
this.logger.debug(`[Agent:${this.name}] - Enhancing tools: ${toolEnhancements}`, {
|
|
1174
|
-
runId,
|
|
1175
|
-
toolsets: toolsets ? Object.keys(toolsets) : void 0,
|
|
1176
|
-
clientTools: clientTools ? Object.keys(clientTools) : void 0,
|
|
1177
|
-
hasMemory: !!this.getMemory(),
|
|
1178
|
-
hasResourceId: !!resourceId
|
|
1179
|
-
});
|
|
1180
|
-
const threadId = thread?.id;
|
|
1181
|
-
const convertedTools = await this.convertTools({
|
|
1182
|
-
toolsets,
|
|
1183
|
-
clientTools,
|
|
1184
|
-
threadId,
|
|
1185
|
-
resourceId,
|
|
1186
|
-
runId,
|
|
1187
|
-
runtimeContext
|
|
1188
|
-
});
|
|
1189
|
-
const messageList = new MessageList({
|
|
1190
|
-
threadId,
|
|
1191
|
-
resourceId,
|
|
1192
|
-
generateMessageId
|
|
1193
|
-
}).addSystem({
|
|
1194
|
-
role: "system",
|
|
1195
|
-
content: instructions || `${this.instructions}.`
|
|
1196
|
-
}).add(context || [], "context");
|
|
1197
|
-
if (!memory || !threadId && !resourceId) {
|
|
1198
|
-
messageList.add(messages, "user");
|
|
1199
|
-
return {
|
|
1200
|
-
messageObjects: messageList.get.all.prompt(),
|
|
1201
|
-
convertedTools,
|
|
1202
|
-
messageList
|
|
1203
|
-
};
|
|
1204
|
-
}
|
|
1205
|
-
if (!threadId || !resourceId) {
|
|
1206
|
-
const mastraError = new MastraError({
|
|
1207
|
-
id: "AGENT_MEMORY_MISSING_RESOURCE_ID",
|
|
1208
|
-
domain: "AGENT" /* AGENT */,
|
|
1209
|
-
category: "USER" /* USER */,
|
|
1210
|
-
details: {
|
|
1211
|
-
agentName: this.name,
|
|
1212
|
-
threadId: threadId || "",
|
|
1213
|
-
resourceId: resourceId || ""
|
|
1214
|
-
},
|
|
1215
|
-
text: `A resourceId must be provided when passing a threadId and using Memory. Saw threadId ${threadId} but resourceId is ${resourceId}`
|
|
1216
|
-
});
|
|
1217
|
-
this.logger.trackException(mastraError);
|
|
1218
|
-
this.logger.error(mastraError.toString());
|
|
1219
|
-
throw mastraError;
|
|
1220
|
-
}
|
|
1221
|
-
const store = memory.constructor.name;
|
|
1222
|
-
this.logger.debug(`[Agent:${this.name}] - Memory persistence enabled: store=${store}, resourceId=${resourceId}`, {
|
|
1223
|
-
runId,
|
|
1224
|
-
resourceId,
|
|
1225
|
-
threadId,
|
|
1226
|
-
memoryStore: store
|
|
1227
|
-
});
|
|
1228
|
-
let threadObject = void 0;
|
|
1229
|
-
const existingThread = await memory.getThreadById({
|
|
1230
|
-
threadId
|
|
1231
|
-
});
|
|
1232
|
-
if (existingThread) {
|
|
1233
|
-
if (!existingThread.metadata && thread.metadata || thread.metadata && !(0, import_fast_deep_equal.default)(existingThread.metadata, thread.metadata)) {
|
|
1234
|
-
threadObject = await memory.saveThread({
|
|
1235
|
-
thread: {
|
|
1236
|
-
...existingThread,
|
|
1237
|
-
metadata: thread.metadata
|
|
1238
|
-
},
|
|
1239
|
-
memoryConfig
|
|
1240
|
-
});
|
|
1241
|
-
} else {
|
|
1242
|
-
threadObject = existingThread;
|
|
1243
|
-
}
|
|
1244
|
-
} else {
|
|
1245
|
-
threadObject = await memory.createThread({
|
|
1246
|
-
threadId,
|
|
1247
|
-
metadata: thread.metadata,
|
|
1248
|
-
title: thread.title,
|
|
1249
|
-
memoryConfig,
|
|
1250
|
-
resourceId
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
let [memoryMessages, memorySystemMessage] = thread.id && memory ? await Promise.all([this.getMemoryMessages({
|
|
1254
|
-
resourceId,
|
|
1255
|
-
threadId: threadObject.id,
|
|
1256
|
-
vectorMessageSearch: new MessageList().add(messages, `user`).getLatestUserContent() || "",
|
|
1257
|
-
memoryConfig
|
|
1258
|
-
}), memory.getSystemMessage({
|
|
1259
|
-
threadId: threadObject.id,
|
|
1260
|
-
resourceId,
|
|
1261
|
-
memoryConfig
|
|
1262
|
-
})]) : [[], null];
|
|
1263
|
-
this.logger.debug("Fetched messages from memory", {
|
|
1264
|
-
threadId: threadObject.id,
|
|
1265
|
-
runId,
|
|
1266
|
-
fetchedCount: memoryMessages.length
|
|
1267
|
-
});
|
|
1268
|
-
const resultsFromOtherThreads = memoryMessages.filter(m => m.threadId !== threadObject.id);
|
|
1269
|
-
if (resultsFromOtherThreads.length && !memorySystemMessage) {
|
|
1270
|
-
memorySystemMessage = ``;
|
|
1271
|
-
}
|
|
1272
|
-
if (resultsFromOtherThreads.length) {
|
|
1273
|
-
memorySystemMessage += `
|
|
1274
|
-
The following messages were remembered from a different conversation:
|
|
1275
|
-
<remembered_from_other_conversation>
|
|
1276
|
-
${JSON.stringify(
|
|
1277
|
-
// get v1 since they're closer to CoreMessages (which get sent to the LLM) but also include timestamps
|
|
1278
|
-
new MessageList().add(resultsFromOtherThreads, "memory").get.all.v1())}
|
|
1279
|
-
<end_remembered_from_other_conversation>`;
|
|
1280
|
-
}
|
|
1281
|
-
if (memorySystemMessage) {
|
|
1282
|
-
messageList.addSystem(memorySystemMessage, "memory");
|
|
1283
|
-
}
|
|
1284
|
-
messageList.add(memoryMessages.filter(m => m.threadId === threadObject.id),
|
|
1285
|
-
// filter out messages from other threads. those are added to system message above
|
|
1286
|
-
"memory").add(messages, "user");
|
|
1287
|
-
const systemMessage = [...messageList.getSystemMessages(), ...messageList.getSystemMessages("memory")]?.map(m => m.content)?.join(`
|
|
1288
|
-
`) ?? void 0;
|
|
1289
|
-
const processedMemoryMessages = memory.processMessages({
|
|
1290
|
-
// these will be processed
|
|
1291
|
-
messages: messageList.get.remembered.v1(),
|
|
1292
|
-
// these are here for inspecting but shouldn't be returned by the processor
|
|
1293
|
-
// - ex TokenLimiter needs to measure all tokens even though it's only processing remembered messages
|
|
1294
|
-
newMessages: messageList.get.input.v1(),
|
|
1295
|
-
systemMessage,
|
|
1296
|
-
memorySystemMessage: memorySystemMessage || void 0
|
|
1297
|
-
});
|
|
1298
|
-
const processedList = new MessageList({
|
|
1299
|
-
threadId: threadObject.id,
|
|
1300
|
-
resourceId
|
|
1301
|
-
}).addSystem(instructions || `${this.instructions}.`).addSystem(memorySystemMessage).add(context || [], "context").add(processedMemoryMessages, "memory").add(messageList.get.input.v2(), "user").get.all.prompt();
|
|
1302
|
-
return {
|
|
1303
|
-
convertedTools,
|
|
1304
|
-
thread: threadObject,
|
|
1305
|
-
messageList,
|
|
1306
|
-
// add old processed messages + new input messages
|
|
1307
|
-
messageObjects: processedList
|
|
1308
|
-
};
|
|
1309
|
-
},
|
|
1310
|
-
after: async ({
|
|
1311
|
-
result,
|
|
1312
|
-
thread: threadAfter,
|
|
1313
|
-
threadId,
|
|
1314
|
-
memoryConfig: memoryConfig2,
|
|
1315
|
-
outputText,
|
|
1316
|
-
runId: runId2,
|
|
1317
|
-
messageList
|
|
1318
|
-
}) => {
|
|
1319
|
-
const resToLog = {
|
|
1320
|
-
text: result?.text,
|
|
1321
|
-
object: result?.object,
|
|
1322
|
-
toolResults: result?.toolResults,
|
|
1323
|
-
toolCalls: result?.toolCalls,
|
|
1324
|
-
usage: result?.usage,
|
|
1325
|
-
steps: result?.steps?.map(s => {
|
|
1326
|
-
return {
|
|
1327
|
-
stepType: s?.stepType,
|
|
1328
|
-
text: result?.text,
|
|
1329
|
-
object: result?.object,
|
|
1330
|
-
toolResults: result?.toolResults,
|
|
1331
|
-
toolCalls: result?.toolCalls,
|
|
1332
|
-
usage: result?.usage
|
|
1333
|
-
};
|
|
1334
|
-
})
|
|
1335
|
-
};
|
|
1336
|
-
this.logger.debug(`[Agent:${this.name}] - Post processing LLM response`, {
|
|
1337
|
-
runId: runId2,
|
|
1338
|
-
result: resToLog,
|
|
1339
|
-
threadId
|
|
1340
|
-
});
|
|
1341
|
-
const memory = this.getMemory();
|
|
1342
|
-
const messageListResponses = new MessageList({
|
|
1343
|
-
threadId,
|
|
1344
|
-
resourceId
|
|
1345
|
-
}).add(result.response.messages, "response").get.all.core();
|
|
1346
|
-
const usedWorkingMemory = messageListResponses?.some(m => m.role === "tool" && m?.content?.some(c => c?.toolName === "updateWorkingMemory"));
|
|
1347
|
-
const thread2 = usedWorkingMemory ? threadId ? await memory?.getThreadById({
|
|
1348
|
-
threadId
|
|
1349
|
-
}) : void 0 : threadAfter;
|
|
1350
|
-
if (memory && resourceId && thread2) {
|
|
1351
|
-
try {
|
|
1352
|
-
let responseMessages = result.response.messages;
|
|
1353
|
-
if (!responseMessages && result.object) {
|
|
1354
|
-
responseMessages = [{
|
|
1355
|
-
role: "assistant",
|
|
1356
|
-
content: [{
|
|
1357
|
-
type: "text",
|
|
1358
|
-
text: outputText
|
|
1359
|
-
// outputText contains the stringified object
|
|
1360
|
-
}]
|
|
1361
|
-
}];
|
|
1362
|
-
}
|
|
1363
|
-
if (responseMessages) {
|
|
1364
|
-
messageList.add(responseMessages, "response");
|
|
1365
|
-
}
|
|
1366
|
-
const promises = [saveQueueManager.flushMessages(messageList, threadId, memoryConfig2)];
|
|
1367
|
-
if (thread2.title?.startsWith("New Thread")) {
|
|
1368
|
-
const config = memory.getMergedThreadConfig(memoryConfig2);
|
|
1369
|
-
const userMessage = this.getMostRecentUserMessage(messageList.get.all.ui());
|
|
1370
|
-
const {
|
|
1371
|
-
shouldGenerate,
|
|
1372
|
-
model: titleModel,
|
|
1373
|
-
instructions: titleInstructions
|
|
1374
|
-
} = this.resolveTitleGenerationConfig(config?.threads?.generateTitle);
|
|
1375
|
-
if (shouldGenerate && userMessage) {
|
|
1376
|
-
promises.push(this.genTitle(userMessage, runtimeContext, titleModel, titleInstructions).then(title => {
|
|
1377
|
-
if (title) {
|
|
1378
|
-
return memory.createThread({
|
|
1379
|
-
threadId: thread2.id,
|
|
1380
|
-
resourceId,
|
|
1381
|
-
memoryConfig: memoryConfig2,
|
|
1382
|
-
title,
|
|
1383
|
-
metadata: thread2.metadata
|
|
1384
|
-
});
|
|
1385
|
-
}
|
|
1386
|
-
}));
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
await Promise.all(promises);
|
|
1390
|
-
} catch (e) {
|
|
1391
|
-
await saveQueueManager.flushMessages(messageList, threadId, memoryConfig2);
|
|
1392
|
-
if (e instanceof MastraError) {
|
|
1393
|
-
throw e;
|
|
1394
|
-
}
|
|
1395
|
-
const mastraError = new MastraError({
|
|
1396
|
-
id: "AGENT_MEMORY_PERSIST_RESPONSE_MESSAGES_FAILED",
|
|
1397
|
-
domain: "AGENT" /* AGENT */,
|
|
1398
|
-
category: "SYSTEM" /* SYSTEM */,
|
|
1399
|
-
details: {
|
|
1400
|
-
agentName: this.name,
|
|
1401
|
-
runId: runId2 || "",
|
|
1402
|
-
threadId: threadId || "",
|
|
1403
|
-
result: JSON.stringify(resToLog)
|
|
1404
|
-
}
|
|
1405
|
-
}, e);
|
|
1406
|
-
this.logger.trackException(mastraError);
|
|
1407
|
-
this.logger.error(mastraError.toString());
|
|
1408
|
-
throw mastraError;
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
if (Object.keys(this.evals || {}).length > 0) {
|
|
1412
|
-
const userInputMessages = messageList.get.all.ui().filter(m => m.role === "user");
|
|
1413
|
-
const input = userInputMessages.map(message => typeof message.content === "string" ? message.content : "").join("\n");
|
|
1414
|
-
const runIdToUse = runId2 || crypto.randomUUID();
|
|
1415
|
-
for (const metric of Object.values(this.evals || {})) {
|
|
1416
|
-
executeHook("onGeneration" /* ON_GENERATION */, {
|
|
1417
|
-
input,
|
|
1418
|
-
output: outputText,
|
|
1419
|
-
runId: runIdToUse,
|
|
1420
|
-
metric,
|
|
1421
|
-
agentName: this.name,
|
|
1422
|
-
instructions: instructions || this.instructions
|
|
1423
|
-
});
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
};
|
|
1428
|
-
}
|
|
1429
|
-
async generate(messages, generateOptions = {}) {
|
|
1430
|
-
const defaultGenerateOptions = await this.getDefaultGenerateOptions({
|
|
1431
|
-
runtimeContext: generateOptions.runtimeContext
|
|
1432
|
-
});
|
|
1433
|
-
const {
|
|
1434
|
-
context,
|
|
1435
|
-
memoryOptions: memoryConfigFromArgs,
|
|
1436
|
-
resourceId: resourceIdFromArgs,
|
|
1437
|
-
maxSteps,
|
|
1438
|
-
onStepFinish,
|
|
1439
|
-
output,
|
|
1440
|
-
toolsets,
|
|
1441
|
-
clientTools,
|
|
1442
|
-
temperature,
|
|
1443
|
-
toolChoice = "auto",
|
|
1444
|
-
experimental_output,
|
|
1445
|
-
telemetry,
|
|
1446
|
-
runtimeContext = new RuntimeContext(),
|
|
1447
|
-
savePerStep = false,
|
|
1448
|
-
...args
|
|
1449
|
-
} = Object.assign({}, defaultGenerateOptions, generateOptions);
|
|
1450
|
-
const generateMessageId = `experimental_generateMessageId` in args && typeof args.experimental_generateMessageId === `function` ? args.experimental_generateMessageId : void 0;
|
|
1451
|
-
const threadFromArgs = resolveThreadIdFromArgs({
|
|
1452
|
-
...args,
|
|
1453
|
-
...generateOptions
|
|
1454
|
-
});
|
|
1455
|
-
const resourceId = args.memory?.resource || resourceIdFromArgs;
|
|
1456
|
-
const memoryConfig = args.memory?.options || memoryConfigFromArgs;
|
|
1457
|
-
const runId = args.runId || randomUUID();
|
|
1458
|
-
const instructions = args.instructions || (await this.getInstructions({
|
|
1459
|
-
runtimeContext
|
|
1460
|
-
}));
|
|
1461
|
-
const llm = await this.getLLM({
|
|
1462
|
-
runtimeContext
|
|
1463
|
-
});
|
|
1464
|
-
const memory = this.getMemory();
|
|
1465
|
-
const saveQueueManager = new SaveQueueManager({
|
|
1466
|
-
logger: this.logger,
|
|
1467
|
-
memory
|
|
1468
|
-
});
|
|
1469
|
-
const {
|
|
1470
|
-
before,
|
|
1471
|
-
after
|
|
1472
|
-
} = this.__primitive({
|
|
1473
|
-
messages,
|
|
1474
|
-
instructions,
|
|
1475
|
-
context,
|
|
1476
|
-
thread: threadFromArgs,
|
|
1477
|
-
memoryConfig,
|
|
1478
|
-
resourceId,
|
|
1479
|
-
runId,
|
|
1480
|
-
toolsets,
|
|
1481
|
-
clientTools,
|
|
1482
|
-
runtimeContext,
|
|
1483
|
-
generateMessageId,
|
|
1484
|
-
saveQueueManager
|
|
1485
|
-
});
|
|
1486
|
-
const {
|
|
1487
|
-
thread,
|
|
1488
|
-
messageObjects,
|
|
1489
|
-
convertedTools,
|
|
1490
|
-
messageList
|
|
1491
|
-
} = await before();
|
|
1492
|
-
const threadId = thread?.id;
|
|
1493
|
-
if (!output && experimental_output) {
|
|
1494
|
-
const result2 = await llm.__text({
|
|
1495
|
-
messages: messageObjects,
|
|
1496
|
-
tools: convertedTools,
|
|
1497
|
-
onStepFinish: async result3 => {
|
|
1498
|
-
if (savePerStep) {
|
|
1499
|
-
await this.saveStepMessages({
|
|
1500
|
-
saveQueueManager,
|
|
1501
|
-
result: result3,
|
|
1502
|
-
messageList,
|
|
1503
|
-
threadId,
|
|
1504
|
-
memoryConfig,
|
|
1505
|
-
runId
|
|
1506
|
-
});
|
|
1507
|
-
}
|
|
1508
|
-
return onStepFinish?.({
|
|
1509
|
-
...result3,
|
|
1510
|
-
runId
|
|
1511
|
-
});
|
|
1512
|
-
},
|
|
1513
|
-
maxSteps,
|
|
1514
|
-
runId,
|
|
1515
|
-
temperature,
|
|
1516
|
-
toolChoice: toolChoice || "auto",
|
|
1517
|
-
experimental_output,
|
|
1518
|
-
threadId,
|
|
1519
|
-
resourceId,
|
|
1520
|
-
memory: this.getMemory(),
|
|
1521
|
-
runtimeContext,
|
|
1522
|
-
telemetry,
|
|
1523
|
-
...args
|
|
1524
|
-
});
|
|
1525
|
-
const outputText2 = result2.text;
|
|
1526
|
-
await after({
|
|
1527
|
-
result: result2,
|
|
1528
|
-
threadId,
|
|
1529
|
-
thread,
|
|
1530
|
-
memoryConfig,
|
|
1531
|
-
outputText: outputText2,
|
|
1532
|
-
runId,
|
|
1533
|
-
messageList
|
|
1534
|
-
});
|
|
1535
|
-
const newResult = result2;
|
|
1536
|
-
newResult.object = result2.experimental_output;
|
|
1537
|
-
return newResult;
|
|
1538
|
-
}
|
|
1539
|
-
if (!output) {
|
|
1540
|
-
const result2 = await llm.__text({
|
|
1541
|
-
messages: messageObjects,
|
|
1542
|
-
tools: convertedTools,
|
|
1543
|
-
onStepFinish: async result3 => {
|
|
1544
|
-
if (savePerStep) {
|
|
1545
|
-
await this.saveStepMessages({
|
|
1546
|
-
saveQueueManager,
|
|
1547
|
-
result: result3,
|
|
1548
|
-
messageList,
|
|
1549
|
-
threadId,
|
|
1550
|
-
memoryConfig,
|
|
1551
|
-
runId
|
|
1552
|
-
});
|
|
1553
|
-
}
|
|
1554
|
-
return onStepFinish?.({
|
|
1555
|
-
...result3,
|
|
1556
|
-
runId
|
|
1557
|
-
});
|
|
1558
|
-
},
|
|
1559
|
-
maxSteps,
|
|
1560
|
-
runId,
|
|
1561
|
-
temperature,
|
|
1562
|
-
toolChoice,
|
|
1563
|
-
telemetry,
|
|
1564
|
-
threadId,
|
|
1565
|
-
resourceId,
|
|
1566
|
-
memory: this.getMemory(),
|
|
1567
|
-
runtimeContext,
|
|
1568
|
-
...args
|
|
1569
|
-
});
|
|
1570
|
-
const outputText2 = result2.text;
|
|
1571
|
-
await after({
|
|
1572
|
-
result: result2,
|
|
1573
|
-
thread,
|
|
1574
|
-
threadId,
|
|
1575
|
-
memoryConfig,
|
|
1576
|
-
outputText: outputText2,
|
|
1577
|
-
runId,
|
|
1578
|
-
messageList
|
|
1579
|
-
});
|
|
1580
|
-
return result2;
|
|
1581
|
-
}
|
|
1582
|
-
const result = await llm.__textObject({
|
|
1583
|
-
messages: messageObjects,
|
|
1584
|
-
tools: convertedTools,
|
|
1585
|
-
structuredOutput: output,
|
|
1586
|
-
onStepFinish: async result2 => {
|
|
1587
|
-
if (savePerStep) {
|
|
1588
|
-
await this.saveStepMessages({
|
|
1589
|
-
saveQueueManager,
|
|
1590
|
-
result: result2,
|
|
1591
|
-
messageList,
|
|
1592
|
-
threadId,
|
|
1593
|
-
memoryConfig,
|
|
1594
|
-
runId
|
|
1595
|
-
});
|
|
1596
|
-
}
|
|
1597
|
-
return onStepFinish?.({
|
|
1598
|
-
...result2,
|
|
1599
|
-
runId
|
|
1600
|
-
});
|
|
1601
|
-
},
|
|
1602
|
-
maxSteps,
|
|
1603
|
-
runId,
|
|
1604
|
-
temperature,
|
|
1605
|
-
toolChoice,
|
|
1606
|
-
telemetry,
|
|
1607
|
-
memory: this.getMemory(),
|
|
1608
|
-
runtimeContext,
|
|
1609
|
-
...args
|
|
1610
|
-
});
|
|
1611
|
-
const outputText = JSON.stringify(result.object);
|
|
1612
|
-
await after({
|
|
1613
|
-
result,
|
|
1614
|
-
thread,
|
|
1615
|
-
threadId,
|
|
1616
|
-
memoryConfig,
|
|
1617
|
-
outputText,
|
|
1618
|
-
runId,
|
|
1619
|
-
messageList
|
|
1620
|
-
});
|
|
1621
|
-
return result;
|
|
1622
|
-
}
|
|
1623
|
-
async stream(messages, streamOptions = {}) {
|
|
1624
|
-
const defaultStreamOptions = await this.getDefaultStreamOptions({
|
|
1625
|
-
runtimeContext: streamOptions.runtimeContext
|
|
1626
|
-
});
|
|
1627
|
-
const {
|
|
1628
|
-
context,
|
|
1629
|
-
memoryOptions: memoryConfigFromArgs,
|
|
1630
|
-
resourceId: resourceIdFromArgs,
|
|
1631
|
-
maxSteps,
|
|
1632
|
-
onFinish,
|
|
1633
|
-
onStepFinish,
|
|
1634
|
-
toolsets,
|
|
1635
|
-
clientTools,
|
|
1636
|
-
output,
|
|
1637
|
-
temperature,
|
|
1638
|
-
toolChoice = "auto",
|
|
1639
|
-
experimental_output,
|
|
1640
|
-
telemetry,
|
|
1641
|
-
runtimeContext = new RuntimeContext(),
|
|
1642
|
-
savePerStep = false,
|
|
1643
|
-
...args
|
|
1644
|
-
} = Object.assign({}, defaultStreamOptions, streamOptions);
|
|
1645
|
-
const generateMessageId = `experimental_generateMessageId` in args && typeof args.experimental_generateMessageId === `function` ? args.experimental_generateMessageId : void 0;
|
|
1646
|
-
const threadFromArgs = resolveThreadIdFromArgs({
|
|
1647
|
-
...args,
|
|
1648
|
-
...streamOptions
|
|
1649
|
-
});
|
|
1650
|
-
const resourceId = args.memory?.resource || resourceIdFromArgs;
|
|
1651
|
-
const memoryConfig = args.memory?.options || memoryConfigFromArgs;
|
|
1652
|
-
const runId = args.runId || randomUUID();
|
|
1653
|
-
const instructions = args.instructions || (await this.getInstructions({
|
|
1654
|
-
runtimeContext
|
|
1655
|
-
}));
|
|
1656
|
-
const llm = await this.getLLM({
|
|
1657
|
-
runtimeContext
|
|
1658
|
-
});
|
|
1659
|
-
const memory = this.getMemory();
|
|
1660
|
-
const saveQueueManager = new SaveQueueManager({
|
|
1661
|
-
logger: this.logger,
|
|
1662
|
-
memory
|
|
1663
|
-
});
|
|
1664
|
-
const {
|
|
1665
|
-
before,
|
|
1666
|
-
after
|
|
1667
|
-
} = this.__primitive({
|
|
1668
|
-
instructions,
|
|
1669
|
-
messages,
|
|
1670
|
-
context,
|
|
1671
|
-
thread: threadFromArgs,
|
|
1672
|
-
memoryConfig,
|
|
1673
|
-
resourceId,
|
|
1674
|
-
runId,
|
|
1675
|
-
toolsets,
|
|
1676
|
-
clientTools,
|
|
1677
|
-
runtimeContext,
|
|
1678
|
-
generateMessageId,
|
|
1679
|
-
saveQueueManager
|
|
1680
|
-
});
|
|
1681
|
-
const {
|
|
1682
|
-
thread,
|
|
1683
|
-
messageObjects,
|
|
1684
|
-
convertedTools,
|
|
1685
|
-
messageList
|
|
1686
|
-
} = await before();
|
|
1687
|
-
const threadId = thread?.id;
|
|
1688
|
-
if (!output && experimental_output) {
|
|
1689
|
-
this.logger.debug(`Starting agent ${this.name} llm stream call`, {
|
|
1690
|
-
runId
|
|
1691
|
-
});
|
|
1692
|
-
const streamResult = llm.__stream({
|
|
1693
|
-
messages: messageObjects,
|
|
1694
|
-
temperature,
|
|
1695
|
-
tools: convertedTools,
|
|
1696
|
-
onStepFinish: async result => {
|
|
1697
|
-
if (savePerStep) {
|
|
1698
|
-
await this.saveStepMessages({
|
|
1699
|
-
saveQueueManager,
|
|
1700
|
-
result,
|
|
1701
|
-
messageList,
|
|
1702
|
-
threadId,
|
|
1703
|
-
memoryConfig,
|
|
1704
|
-
runId
|
|
1705
|
-
});
|
|
1706
|
-
}
|
|
1707
|
-
return onStepFinish?.({
|
|
1708
|
-
...result,
|
|
1709
|
-
runId
|
|
1710
|
-
});
|
|
1711
|
-
},
|
|
1712
|
-
onFinish: async result => {
|
|
1713
|
-
try {
|
|
1714
|
-
const outputText = result.text;
|
|
1715
|
-
await after({
|
|
1716
|
-
result,
|
|
1717
|
-
thread,
|
|
1718
|
-
threadId,
|
|
1719
|
-
memoryConfig,
|
|
1720
|
-
outputText,
|
|
1721
|
-
runId,
|
|
1722
|
-
messageList
|
|
1723
|
-
});
|
|
1724
|
-
} catch (e) {
|
|
1725
|
-
this.logger.error("Error saving memory on finish", {
|
|
1726
|
-
error: e,
|
|
1727
|
-
runId
|
|
1728
|
-
});
|
|
1729
|
-
}
|
|
1730
|
-
await onFinish?.({
|
|
1731
|
-
...result,
|
|
1732
|
-
runId
|
|
1733
|
-
});
|
|
1734
|
-
},
|
|
1735
|
-
maxSteps,
|
|
1736
|
-
runId,
|
|
1737
|
-
toolChoice,
|
|
1738
|
-
experimental_output,
|
|
1739
|
-
telemetry,
|
|
1740
|
-
memory: this.getMemory(),
|
|
1741
|
-
runtimeContext,
|
|
1742
|
-
threadId: thread?.id,
|
|
1743
|
-
resourceId,
|
|
1744
|
-
...args
|
|
1745
|
-
});
|
|
1746
|
-
const newStreamResult = streamResult;
|
|
1747
|
-
newStreamResult.partialObjectStream = streamResult.experimental_partialOutputStream;
|
|
1748
|
-
return newStreamResult;
|
|
1749
|
-
} else if (!output) {
|
|
1750
|
-
this.logger.debug(`Starting agent ${this.name} llm stream call`, {
|
|
1751
|
-
runId
|
|
1752
|
-
});
|
|
1753
|
-
return llm.__stream({
|
|
1754
|
-
messages: messageObjects,
|
|
1755
|
-
temperature,
|
|
1756
|
-
tools: convertedTools,
|
|
1757
|
-
onStepFinish: async result => {
|
|
1758
|
-
if (savePerStep) {
|
|
1759
|
-
await this.saveStepMessages({
|
|
1760
|
-
saveQueueManager,
|
|
1761
|
-
result,
|
|
1762
|
-
messageList,
|
|
1763
|
-
threadId,
|
|
1764
|
-
memoryConfig,
|
|
1765
|
-
runId
|
|
1766
|
-
});
|
|
1767
|
-
}
|
|
1768
|
-
return onStepFinish?.({
|
|
1769
|
-
...result,
|
|
1770
|
-
runId
|
|
1771
|
-
});
|
|
1772
|
-
},
|
|
1773
|
-
onFinish: async result => {
|
|
1774
|
-
try {
|
|
1775
|
-
const outputText = result.text;
|
|
1776
|
-
await after({
|
|
1777
|
-
result,
|
|
1778
|
-
thread,
|
|
1779
|
-
threadId,
|
|
1780
|
-
memoryConfig,
|
|
1781
|
-
outputText,
|
|
1782
|
-
runId,
|
|
1783
|
-
messageList
|
|
1784
|
-
});
|
|
1785
|
-
} catch (e) {
|
|
1786
|
-
this.logger.error("Error saving memory on finish", {
|
|
1787
|
-
error: e,
|
|
1788
|
-
runId
|
|
1789
|
-
});
|
|
1790
|
-
}
|
|
1791
|
-
await onFinish?.({
|
|
1792
|
-
...result,
|
|
1793
|
-
runId
|
|
1794
|
-
});
|
|
1795
|
-
},
|
|
1796
|
-
maxSteps,
|
|
1797
|
-
runId,
|
|
1798
|
-
toolChoice,
|
|
1799
|
-
telemetry,
|
|
1800
|
-
memory: this.getMemory(),
|
|
1801
|
-
runtimeContext,
|
|
1802
|
-
threadId: thread?.id,
|
|
1803
|
-
resourceId,
|
|
1804
|
-
...args
|
|
1805
|
-
});
|
|
1806
|
-
}
|
|
1807
|
-
this.logger.debug(`Starting agent ${this.name} llm streamObject call`, {
|
|
1808
|
-
runId
|
|
1809
|
-
});
|
|
1810
|
-
return llm.__streamObject({
|
|
1811
|
-
messages: messageObjects,
|
|
1812
|
-
tools: convertedTools,
|
|
1813
|
-
temperature,
|
|
1814
|
-
structuredOutput: output,
|
|
1815
|
-
onStepFinish: async result => {
|
|
1816
|
-
if (savePerStep) {
|
|
1817
|
-
await this.saveStepMessages({
|
|
1818
|
-
saveQueueManager,
|
|
1819
|
-
result,
|
|
1820
|
-
messageList,
|
|
1821
|
-
threadId,
|
|
1822
|
-
memoryConfig,
|
|
1823
|
-
runId
|
|
1824
|
-
});
|
|
1825
|
-
}
|
|
1826
|
-
return onStepFinish?.({
|
|
1827
|
-
...result,
|
|
1828
|
-
runId
|
|
1829
|
-
});
|
|
1830
|
-
},
|
|
1831
|
-
onFinish: async result => {
|
|
1832
|
-
try {
|
|
1833
|
-
const outputText = JSON.stringify(result.object);
|
|
1834
|
-
await after({
|
|
1835
|
-
result,
|
|
1836
|
-
thread,
|
|
1837
|
-
threadId,
|
|
1838
|
-
memoryConfig,
|
|
1839
|
-
outputText,
|
|
1840
|
-
runId,
|
|
1841
|
-
messageList
|
|
1842
|
-
});
|
|
1843
|
-
} catch (e) {
|
|
1844
|
-
this.logger.error("Error saving memory on finish", {
|
|
1845
|
-
error: e,
|
|
1846
|
-
runId
|
|
1847
|
-
});
|
|
1848
|
-
}
|
|
1849
|
-
await onFinish?.({
|
|
1850
|
-
...result,
|
|
1851
|
-
runId
|
|
1852
|
-
});
|
|
1853
|
-
},
|
|
1854
|
-
runId,
|
|
1855
|
-
toolChoice,
|
|
1856
|
-
telemetry,
|
|
1857
|
-
memory: this.getMemory(),
|
|
1858
|
-
runtimeContext,
|
|
1859
|
-
threadId: thread?.id,
|
|
1860
|
-
resourceId,
|
|
1861
|
-
...args
|
|
1862
|
-
});
|
|
1863
|
-
}
|
|
1864
|
-
/**
|
|
1865
|
-
* Convert text to speech using the configured voice provider
|
|
1866
|
-
* @param input Text or text stream to convert to speech
|
|
1867
|
-
* @param options Speech options including speaker and provider-specific options
|
|
1868
|
-
* @returns Audio stream
|
|
1869
|
-
* @deprecated Use agent.voice.speak() instead
|
|
1870
|
-
*/
|
|
1871
|
-
async speak(input, options) {
|
|
1872
|
-
if (!this.voice) {
|
|
1873
|
-
const mastraError = new MastraError({
|
|
1874
|
-
id: "AGENT_SPEAK_METHOD_VOICE_NOT_CONFIGURED",
|
|
1875
|
-
domain: "AGENT" /* AGENT */,
|
|
1876
|
-
category: "USER" /* USER */,
|
|
1877
|
-
details: {
|
|
1878
|
-
agentName: this.name
|
|
1879
|
-
},
|
|
1880
|
-
text: "No voice provider configured"
|
|
1881
|
-
});
|
|
1882
|
-
this.logger.trackException(mastraError);
|
|
1883
|
-
this.logger.error(mastraError.toString());
|
|
1884
|
-
throw mastraError;
|
|
1885
|
-
}
|
|
1886
|
-
this.logger.warn("Warning: agent.speak() is deprecated. Please use agent.voice.speak() instead.");
|
|
1887
|
-
try {
|
|
1888
|
-
return this.voice.speak(input, options);
|
|
1889
|
-
} catch (e) {
|
|
1890
|
-
let err;
|
|
1891
|
-
if (e instanceof MastraError) {
|
|
1892
|
-
err = e;
|
|
1893
|
-
} else {
|
|
1894
|
-
err = new MastraError({
|
|
1895
|
-
id: "AGENT_SPEAK_METHOD_ERROR",
|
|
1896
|
-
domain: "AGENT" /* AGENT */,
|
|
1897
|
-
category: "UNKNOWN" /* UNKNOWN */,
|
|
1898
|
-
details: {
|
|
1899
|
-
agentName: this.name
|
|
1900
|
-
},
|
|
1901
|
-
text: "Error during agent speak"
|
|
1902
|
-
}, e);
|
|
1903
|
-
}
|
|
1904
|
-
this.logger.trackException(err);
|
|
1905
|
-
this.logger.error(err.toString());
|
|
1906
|
-
throw err;
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
/**
|
|
1910
|
-
* Convert speech to text using the configured voice provider
|
|
1911
|
-
* @param audioStream Audio stream to transcribe
|
|
1912
|
-
* @param options Provider-specific transcription options
|
|
1913
|
-
* @returns Text or text stream
|
|
1914
|
-
* @deprecated Use agent.voice.listen() instead
|
|
1915
|
-
*/
|
|
1916
|
-
async listen(audioStream, options) {
|
|
1917
|
-
if (!this.voice) {
|
|
1918
|
-
const mastraError = new MastraError({
|
|
1919
|
-
id: "AGENT_LISTEN_METHOD_VOICE_NOT_CONFIGURED",
|
|
1920
|
-
domain: "AGENT" /* AGENT */,
|
|
1921
|
-
category: "USER" /* USER */,
|
|
1922
|
-
details: {
|
|
1923
|
-
agentName: this.name
|
|
1924
|
-
},
|
|
1925
|
-
text: "No voice provider configured"
|
|
1926
|
-
});
|
|
1927
|
-
this.logger.trackException(mastraError);
|
|
1928
|
-
this.logger.error(mastraError.toString());
|
|
1929
|
-
throw mastraError;
|
|
1930
|
-
}
|
|
1931
|
-
this.logger.warn("Warning: agent.listen() is deprecated. Please use agent.voice.listen() instead");
|
|
1932
|
-
try {
|
|
1933
|
-
return this.voice.listen(audioStream, options);
|
|
1934
|
-
} catch (e) {
|
|
1935
|
-
let err;
|
|
1936
|
-
if (e instanceof MastraError) {
|
|
1937
|
-
err = e;
|
|
1938
|
-
} else {
|
|
1939
|
-
err = new MastraError({
|
|
1940
|
-
id: "AGENT_LISTEN_METHOD_ERROR",
|
|
1941
|
-
domain: "AGENT" /* AGENT */,
|
|
1942
|
-
category: "UNKNOWN" /* UNKNOWN */,
|
|
1943
|
-
details: {
|
|
1944
|
-
agentName: this.name
|
|
1945
|
-
},
|
|
1946
|
-
text: "Error during agent listen"
|
|
1947
|
-
}, e);
|
|
1948
|
-
}
|
|
1949
|
-
this.logger.trackException(err);
|
|
1950
|
-
this.logger.error(err.toString());
|
|
1951
|
-
throw err;
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
/**
|
|
1955
|
-
* Get a list of available speakers from the configured voice provider
|
|
1956
|
-
* @throws {Error} If no voice provider is configured
|
|
1957
|
-
* @returns {Promise<Array<{voiceId: string}>>} List of available speakers
|
|
1958
|
-
* @deprecated Use agent.voice.getSpeakers() instead
|
|
1959
|
-
*/
|
|
1960
|
-
async getSpeakers() {
|
|
1961
|
-
if (!this.voice) {
|
|
1962
|
-
const mastraError = new MastraError({
|
|
1963
|
-
id: "AGENT_SPEAKERS_METHOD_VOICE_NOT_CONFIGURED",
|
|
1964
|
-
domain: "AGENT" /* AGENT */,
|
|
1965
|
-
category: "USER" /* USER */,
|
|
1966
|
-
details: {
|
|
1967
|
-
agentName: this.name
|
|
1968
|
-
},
|
|
1969
|
-
text: "No voice provider configured"
|
|
1970
|
-
});
|
|
1971
|
-
this.logger.trackException(mastraError);
|
|
1972
|
-
this.logger.error(mastraError.toString());
|
|
1973
|
-
throw mastraError;
|
|
1974
|
-
}
|
|
1975
|
-
this.logger.warn("Warning: agent.getSpeakers() is deprecated. Please use agent.voice.getSpeakers() instead.");
|
|
1976
|
-
try {
|
|
1977
|
-
return await this.voice.getSpeakers();
|
|
1978
|
-
} catch (e) {
|
|
1979
|
-
let err;
|
|
1980
|
-
if (e instanceof MastraError) {
|
|
1981
|
-
err = e;
|
|
1982
|
-
} else {
|
|
1983
|
-
err = new MastraError({
|
|
1984
|
-
id: "AGENT_GET_SPEAKERS_METHOD_ERROR",
|
|
1985
|
-
domain: "AGENT" /* AGENT */,
|
|
1986
|
-
category: "UNKNOWN" /* UNKNOWN */,
|
|
1987
|
-
details: {
|
|
1988
|
-
agentName: this.name
|
|
1989
|
-
},
|
|
1990
|
-
text: "Error during agent getSpeakers"
|
|
1991
|
-
}, e);
|
|
1992
|
-
}
|
|
1993
|
-
this.logger.trackException(err);
|
|
1994
|
-
this.logger.error(err.toString());
|
|
1995
|
-
throw err;
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
toStep() {
|
|
1999
|
-
const x = agentToStep(this);
|
|
2000
|
-
return new LegacyStep(x);
|
|
2001
|
-
}
|
|
2002
|
-
/**
|
|
2003
|
-
* Resolves the configuration for title generation.
|
|
2004
|
-
* @private
|
|
2005
|
-
*/
|
|
2006
|
-
resolveTitleGenerationConfig(generateTitleConfig) {
|
|
2007
|
-
if (typeof generateTitleConfig === "boolean") {
|
|
2008
|
-
return {
|
|
2009
|
-
shouldGenerate: generateTitleConfig
|
|
2010
|
-
};
|
|
2011
|
-
}
|
|
2012
|
-
if (typeof generateTitleConfig === "object" && generateTitleConfig !== null) {
|
|
2013
|
-
return {
|
|
2014
|
-
shouldGenerate: true,
|
|
2015
|
-
model: generateTitleConfig.model,
|
|
2016
|
-
instructions: generateTitleConfig.instructions
|
|
2017
|
-
};
|
|
2018
|
-
}
|
|
2019
|
-
return {
|
|
2020
|
-
shouldGenerate: false
|
|
2021
|
-
};
|
|
2022
|
-
}
|
|
2023
|
-
/**
|
|
2024
|
-
* Resolves title generation instructions, handling both static strings and dynamic functions
|
|
2025
|
-
* @private
|
|
2026
|
-
*/
|
|
2027
|
-
async resolveTitleInstructions(runtimeContext, instructions) {
|
|
2028
|
-
const DEFAULT_TITLE_INSTRUCTIONS = `
|
|
2029
|
-
- you will generate a short title based on the first message a user begins a conversation with
|
|
2030
|
-
- ensure it is not more than 80 characters long
|
|
2031
|
-
- the title should be a summary of the user's message
|
|
2032
|
-
- do not use quotes or colons
|
|
2033
|
-
- the entire text you return will be used as the title`;
|
|
2034
|
-
if (!instructions) {
|
|
2035
|
-
return DEFAULT_TITLE_INSTRUCTIONS;
|
|
2036
|
-
}
|
|
2037
|
-
if (typeof instructions === "string") {
|
|
2038
|
-
return instructions;
|
|
2039
|
-
} else {
|
|
2040
|
-
const result = instructions({
|
|
2041
|
-
runtimeContext
|
|
2042
|
-
});
|
|
2043
|
-
return resolveMaybePromise(result, resolvedInstructions => {
|
|
2044
|
-
return resolvedInstructions || DEFAULT_TITLE_INSTRUCTIONS;
|
|
2045
|
-
});
|
|
2046
|
-
}
|
|
2047
|
-
}
|
|
2048
|
-
};
|
|
2049
|
-
Agent = /*@__PURE__*/(_ => {
|
|
2050
|
-
_init = __decoratorStart(_a);
|
|
2051
|
-
Agent = __decorateElement(_init, 0, "Agent", _Agent_decorators, Agent);
|
|
2052
|
-
__runInitializers(_init, 1, Agent);
|
|
2053
|
-
|
|
2054
|
-
// src/workflows/legacy/utils.ts
|
|
2055
|
-
return Agent;
|
|
2056
|
-
})();
|
|
2057
|
-
// src/workflows/legacy/utils.ts
|
|
2058
|
-
function isErrorEvent(stateEvent) {
|
|
2059
|
-
return stateEvent.type.startsWith("xstate.error.actor.");
|
|
2060
|
-
}
|
|
2061
|
-
function isTransitionEvent(stateEvent) {
|
|
2062
|
-
return stateEvent.type.startsWith("xstate.done.actor.");
|
|
2063
|
-
}
|
|
2064
|
-
function isVariableReference(value) {
|
|
2065
|
-
return typeof value === "object" && "step" in value && "path" in value;
|
|
2066
|
-
}
|
|
2067
|
-
function getStepResult(result) {
|
|
2068
|
-
if (result?.status === "success") return result.output;
|
|
2069
|
-
return void 0;
|
|
2070
|
-
}
|
|
2071
|
-
function getSuspendedPaths({
|
|
2072
|
-
value,
|
|
2073
|
-
path,
|
|
2074
|
-
suspendedPaths
|
|
2075
|
-
}) {
|
|
2076
|
-
if (typeof value === "string") {
|
|
2077
|
-
if (value === "suspended") {
|
|
2078
|
-
suspendedPaths.add(path);
|
|
2079
|
-
}
|
|
2080
|
-
} else {
|
|
2081
|
-
Object.keys(value).forEach(key => getSuspendedPaths({
|
|
2082
|
-
value: value[key],
|
|
2083
|
-
path: path ? `${path}.${key}` : key,
|
|
2084
|
-
suspendedPaths
|
|
2085
|
-
}));
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
2088
|
-
function isFinalState(status) {
|
|
2089
|
-
return ["completed", "failed"].includes(status);
|
|
2090
|
-
}
|
|
2091
|
-
function isLimboState(status) {
|
|
2092
|
-
return status === "limbo";
|
|
2093
|
-
}
|
|
2094
|
-
function recursivelyCheckForFinalState({
|
|
2095
|
-
value,
|
|
2096
|
-
suspendedPaths,
|
|
2097
|
-
path
|
|
2098
|
-
}) {
|
|
2099
|
-
if (typeof value === "string") {
|
|
2100
|
-
return isFinalState(value) || isLimboState(value) || suspendedPaths.has(path);
|
|
2101
|
-
}
|
|
2102
|
-
return Object.keys(value).every(key => recursivelyCheckForFinalState({
|
|
2103
|
-
value: value[key],
|
|
2104
|
-
suspendedPaths,
|
|
2105
|
-
path: path ? `${path}.${key}` : key
|
|
2106
|
-
}));
|
|
2107
|
-
}
|
|
2108
|
-
function getActivePathsAndStatus(value) {
|
|
2109
|
-
const paths = [];
|
|
2110
|
-
const traverse = (current, path = []) => {
|
|
2111
|
-
for (const [key, value2] of Object.entries(current)) {
|
|
2112
|
-
const currentPath = [...path, key];
|
|
2113
|
-
if (typeof value2 === "string") {
|
|
2114
|
-
paths.push({
|
|
2115
|
-
stepPath: currentPath,
|
|
2116
|
-
stepId: key,
|
|
2117
|
-
status: value2
|
|
2118
|
-
});
|
|
2119
|
-
} else if (typeof value2 === "object" && value2 !== null) {
|
|
2120
|
-
traverse(value2, currentPath);
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
};
|
|
2124
|
-
traverse(value);
|
|
2125
|
-
return paths;
|
|
2126
|
-
}
|
|
2127
|
-
function mergeChildValue(startStepId, parent, child) {
|
|
2128
|
-
const traverse = current => {
|
|
2129
|
-
const obj = {};
|
|
2130
|
-
for (const [key, value] of Object.entries(current)) {
|
|
2131
|
-
if (key === startStepId) {
|
|
2132
|
-
obj[key] = {
|
|
2133
|
-
...child
|
|
2134
|
-
};
|
|
2135
|
-
} else if (typeof value === "string") {
|
|
2136
|
-
obj[key] = value;
|
|
2137
|
-
} else if (typeof value === "object" && value !== null) {
|
|
2138
|
-
obj[key] = traverse(value);
|
|
2139
|
-
}
|
|
2140
|
-
}
|
|
2141
|
-
return obj;
|
|
2142
|
-
};
|
|
2143
|
-
return traverse(parent);
|
|
2144
|
-
}
|
|
2145
|
-
var updateStepInHierarchy = (value, targetStepId) => {
|
|
2146
|
-
const result = {};
|
|
2147
|
-
for (const key of Object.keys(value)) {
|
|
2148
|
-
const currentValue = value[key];
|
|
2149
|
-
if (key === targetStepId) {
|
|
2150
|
-
result[key] = "pending";
|
|
2151
|
-
} else if (typeof currentValue === "object" && currentValue !== null) {
|
|
2152
|
-
result[key] = updateStepInHierarchy(currentValue, targetStepId);
|
|
2153
|
-
} else {
|
|
2154
|
-
result[key] = currentValue;
|
|
2155
|
-
}
|
|
2156
|
-
}
|
|
2157
|
-
return result;
|
|
2158
|
-
};
|
|
2159
|
-
function getResultActivePaths(state) {
|
|
2160
|
-
const activePaths = getActivePathsAndStatus(state.value);
|
|
2161
|
-
const activePathsAndStatus = activePaths.reduce((acc, curr) => {
|
|
2162
|
-
const entry = {
|
|
2163
|
-
status: curr.status,
|
|
2164
|
-
stepPath: curr.stepPath
|
|
2165
|
-
};
|
|
2166
|
-
if (curr.status === "suspended") {
|
|
2167
|
-
entry.suspendPayload = state.context.steps[curr.stepId].suspendPayload;
|
|
2168
|
-
entry.stepPath = curr.stepPath;
|
|
2169
|
-
}
|
|
2170
|
-
acc.set(curr.stepId, entry);
|
|
2171
|
-
return acc;
|
|
2172
|
-
}, /* @__PURE__ */new Map());
|
|
2173
|
-
return activePathsAndStatus;
|
|
2174
|
-
}
|
|
2175
|
-
function isWorkflow(step) {
|
|
2176
|
-
return step instanceof LegacyWorkflow;
|
|
2177
|
-
}
|
|
2178
|
-
function isAgent(step) {
|
|
2179
|
-
return step instanceof Agent;
|
|
2180
|
-
}
|
|
2181
|
-
function resolveVariables({
|
|
2182
|
-
runId,
|
|
2183
|
-
logger,
|
|
2184
|
-
variables,
|
|
2185
|
-
context
|
|
2186
|
-
}) {
|
|
2187
|
-
const resolvedData = {};
|
|
2188
|
-
for (const [key, variable] of Object.entries(variables)) {
|
|
2189
|
-
const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id ?? variable.step.name]);
|
|
2190
|
-
logger.debug(`Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id ?? variable.step.name}`, {
|
|
2191
|
-
sourceData,
|
|
2192
|
-
path: variable.path,
|
|
2193
|
-
runId
|
|
2194
|
-
});
|
|
2195
|
-
if (!sourceData && variable.step !== "trigger") {
|
|
2196
|
-
resolvedData[key] = void 0;
|
|
2197
|
-
continue;
|
|
2198
|
-
}
|
|
2199
|
-
const value = variable.path === "" || variable.path === "." ? sourceData : get(sourceData, variable.path);
|
|
2200
|
-
logger.debug(`Resolved variable ${key}`, {
|
|
2201
|
-
value,
|
|
2202
|
-
runId
|
|
2203
|
-
});
|
|
2204
|
-
resolvedData[key] = value;
|
|
2205
|
-
}
|
|
2206
|
-
return resolvedData;
|
|
2207
|
-
}
|
|
2208
|
-
function agentToStep(agent, {
|
|
2209
|
-
mastra
|
|
2210
|
-
} = {}) {
|
|
2211
|
-
return {
|
|
2212
|
-
id: agent.name,
|
|
2213
|
-
inputSchema: z.object({
|
|
2214
|
-
prompt: z.string(),
|
|
2215
|
-
resourceId: z.string().optional(),
|
|
2216
|
-
threadId: z.string().optional()
|
|
2217
|
-
}),
|
|
2218
|
-
outputSchema: z.object({
|
|
2219
|
-
text: z.string()
|
|
2220
|
-
}),
|
|
2221
|
-
execute: async ({
|
|
2222
|
-
context,
|
|
2223
|
-
runId,
|
|
2224
|
-
mastra: mastraFromExecute
|
|
2225
|
-
}) => {
|
|
2226
|
-
const realMastra = mastraFromExecute ?? mastra;
|
|
2227
|
-
if (!realMastra) {
|
|
2228
|
-
throw new Error("Mastra instance not found");
|
|
2229
|
-
}
|
|
2230
|
-
agent.__registerMastra(realMastra);
|
|
2231
|
-
agent.__registerPrimitives({
|
|
2232
|
-
logger: realMastra.getLogger(),
|
|
2233
|
-
telemetry: realMastra.getTelemetry()
|
|
2234
|
-
});
|
|
2235
|
-
const result = await agent.generate(context.inputData.prompt, {
|
|
2236
|
-
runId,
|
|
2237
|
-
resourceId: context.inputData.resourceId,
|
|
2238
|
-
threadId: context.inputData.threadId
|
|
2239
|
-
});
|
|
2240
|
-
return {
|
|
2241
|
-
text: result.text
|
|
2242
|
-
};
|
|
2243
|
-
}
|
|
2244
|
-
};
|
|
2245
|
-
}
|
|
2246
|
-
function workflowToStep(workflow, {
|
|
2247
|
-
mastra
|
|
2248
|
-
}) {
|
|
2249
|
-
workflow.setNested(true);
|
|
2250
|
-
return {
|
|
2251
|
-
id: workflow.name,
|
|
2252
|
-
workflow,
|
|
2253
|
-
workflowId: toCamelCaseWithRandomSuffix(workflow.name),
|
|
2254
|
-
execute: async ({
|
|
2255
|
-
context,
|
|
2256
|
-
suspend,
|
|
2257
|
-
emit,
|
|
2258
|
-
mastra: mastraFromExecute,
|
|
2259
|
-
runtimeContext
|
|
2260
|
-
}) => {
|
|
2261
|
-
const realMastra = mastraFromExecute ?? mastra;
|
|
2262
|
-
if (realMastra) {
|
|
2263
|
-
workflow.__registerMastra(realMastra);
|
|
2264
|
-
workflow.__registerPrimitives({
|
|
2265
|
-
logger: realMastra.getLogger(),
|
|
2266
|
-
telemetry: realMastra.getTelemetry()
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
const run = context.isResume ? workflow.createRun({
|
|
2270
|
-
runId: context.isResume.runId
|
|
2271
|
-
}) : workflow.createRun();
|
|
2272
|
-
const unwatch = run.watch(state => {
|
|
2273
|
-
emit("state-update", workflow.name, state.results, {
|
|
2274
|
-
...context,
|
|
2275
|
-
...{
|
|
2276
|
-
[workflow.name]: state.results
|
|
2277
|
-
}
|
|
2278
|
-
});
|
|
2279
|
-
});
|
|
2280
|
-
const awaitedResult = context.isResume && context.isResume.stepId.includes(".") ? await run.resume({
|
|
2281
|
-
stepId: context.isResume.stepId.split(".").slice(1).join("."),
|
|
2282
|
-
context: context.inputData,
|
|
2283
|
-
runtimeContext
|
|
2284
|
-
}) : await run.start({
|
|
2285
|
-
triggerData: context.inputData,
|
|
2286
|
-
runtimeContext
|
|
2287
|
-
});
|
|
2288
|
-
unwatch();
|
|
2289
|
-
if (!awaitedResult) {
|
|
2290
|
-
throw new Error("LegacyWorkflow run failed");
|
|
2291
|
-
}
|
|
2292
|
-
if (awaitedResult.activePaths?.size > 0) {
|
|
2293
|
-
const suspendedStep = [...awaitedResult.activePaths.entries()].find(([, {
|
|
2294
|
-
status
|
|
2295
|
-
}]) => {
|
|
2296
|
-
return status === "suspended";
|
|
2297
|
-
});
|
|
2298
|
-
if (suspendedStep) {
|
|
2299
|
-
await suspend(suspendedStep[1].suspendPayload, {
|
|
2300
|
-
...awaitedResult,
|
|
2301
|
-
runId: run.runId
|
|
2302
|
-
});
|
|
2303
|
-
}
|
|
2304
|
-
}
|
|
2305
|
-
return {
|
|
2306
|
-
...awaitedResult,
|
|
2307
|
-
runId: run.runId
|
|
2308
|
-
};
|
|
2309
|
-
}
|
|
2310
|
-
};
|
|
2311
|
-
}
|
|
2312
|
-
function toCamelCaseWithRandomSuffix(str) {
|
|
2313
|
-
if (!str) return "";
|
|
2314
|
-
const normalizedStr = str.replace(/[-_]/g, " ");
|
|
2315
|
-
const words = normalizedStr.split(" ").filter(word => word.length > 0);
|
|
2316
|
-
const camelCase = words.map((word, index) => {
|
|
2317
|
-
word = word.replace(/[^a-zA-Z0-9]/g, "");
|
|
2318
|
-
if (index === 0) {
|
|
2319
|
-
return word.toLowerCase();
|
|
2320
|
-
}
|
|
2321
|
-
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
2322
|
-
}).join("");
|
|
2323
|
-
const randomString = generateRandomLetters(3);
|
|
2324
|
-
return camelCase + randomString;
|
|
2325
|
-
}
|
|
2326
|
-
function generateRandomLetters(length) {
|
|
2327
|
-
const characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
2328
|
-
let result = "";
|
|
2329
|
-
for (let i = 0; i < length; i++) {
|
|
2330
|
-
const randomIndex = Math.floor(Math.random() * characters.length);
|
|
2331
|
-
result += characters.charAt(randomIndex);
|
|
2332
|
-
}
|
|
2333
|
-
return result;
|
|
2334
|
-
}
|
|
2335
|
-
function isConditionalKey(key) {
|
|
2336
|
-
return key.startsWith("__") && (key.includes("_if") || key.includes("_else"));
|
|
2337
|
-
}
|
|
2338
|
-
var Machine = class extends EventEmitter {
|
|
2339
|
-
logger;
|
|
2340
|
-
#mastra;
|
|
2341
|
-
#runtimeContext;
|
|
2342
|
-
#workflowInstance;
|
|
2343
|
-
#executionSpan;
|
|
2344
|
-
#stepGraph;
|
|
2345
|
-
#machine;
|
|
2346
|
-
#runId;
|
|
2347
|
-
#startStepId;
|
|
2348
|
-
name;
|
|
2349
|
-
#actor = null;
|
|
2350
|
-
#steps = {};
|
|
2351
|
-
#retryConfig;
|
|
2352
|
-
constructor({
|
|
2353
|
-
logger,
|
|
2354
|
-
mastra,
|
|
2355
|
-
runtimeContext,
|
|
2356
|
-
workflowInstance,
|
|
2357
|
-
executionSpan,
|
|
2358
|
-
name,
|
|
2359
|
-
runId,
|
|
2360
|
-
steps,
|
|
2361
|
-
stepGraph,
|
|
2362
|
-
retryConfig,
|
|
2363
|
-
startStepId
|
|
2364
|
-
}) {
|
|
2365
|
-
super();
|
|
2366
|
-
this.#mastra = mastra;
|
|
2367
|
-
this.#workflowInstance = workflowInstance;
|
|
2368
|
-
this.#runtimeContext = runtimeContext;
|
|
2369
|
-
this.#executionSpan = executionSpan;
|
|
2370
|
-
this.logger = logger;
|
|
2371
|
-
this.#runId = runId;
|
|
2372
|
-
this.#startStepId = startStepId;
|
|
2373
|
-
this.name = name;
|
|
2374
|
-
this.#stepGraph = stepGraph;
|
|
2375
|
-
this.#steps = steps;
|
|
2376
|
-
this.#retryConfig = retryConfig;
|
|
2377
|
-
this.initializeMachine();
|
|
2378
|
-
}
|
|
2379
|
-
get startStepId() {
|
|
2380
|
-
return this.#startStepId;
|
|
2381
|
-
}
|
|
2382
|
-
async execute({
|
|
2383
|
-
stepId,
|
|
2384
|
-
input,
|
|
2385
|
-
snapshot,
|
|
2386
|
-
resumeData
|
|
2387
|
-
} = {}) {
|
|
2388
|
-
if (snapshot) {
|
|
2389
|
-
this.logger.debug(`Workflow snapshot received`, {
|
|
2390
|
-
runId: this.#runId,
|
|
2391
|
-
snapshot
|
|
2392
|
-
});
|
|
2393
|
-
}
|
|
2394
|
-
const origSteps = input.steps;
|
|
2395
|
-
const isResumedInitialStep = this.#stepGraph?.initial[0]?.step?.id === stepId;
|
|
2396
|
-
if (isResumedInitialStep) {
|
|
2397
|
-
snapshot = void 0;
|
|
2398
|
-
input.steps = {};
|
|
2399
|
-
}
|
|
2400
|
-
this.logger.debug(`Machine input prepared`, {
|
|
2401
|
-
runId: this.#runId,
|
|
2402
|
-
input
|
|
2403
|
-
});
|
|
2404
|
-
const actorSnapshot = snapshot ? {
|
|
2405
|
-
...snapshot,
|
|
2406
|
-
context: {
|
|
2407
|
-
...input,
|
|
2408
|
-
inputData: {
|
|
2409
|
-
...(snapshot?.context?.inputData || {}),
|
|
2410
|
-
...resumeData
|
|
2411
|
-
},
|
|
2412
|
-
// ts-ignore is needed here because our snapshot types don't really match xstate snapshot types right now. We should fix this in general.
|
|
2413
|
-
// @ts-ignore
|
|
2414
|
-
isResume: {
|
|
2415
|
-
runId: snapshot?.context?.steps[stepId.split(".")?.[0]]?.output?.runId || this.#runId,
|
|
2416
|
-
stepId
|
|
2417
|
-
}
|
|
2418
|
-
}
|
|
2419
|
-
} : void 0;
|
|
2420
|
-
this.logger.debug(`Creating actor with configuration`, {
|
|
2421
|
-
input,
|
|
2422
|
-
actorSnapshot,
|
|
2423
|
-
runId: this.#runId,
|
|
2424
|
-
machineStates: this.#machine.config.states
|
|
2425
|
-
});
|
|
2426
|
-
this.#actor = createActor(this.#machine, {
|
|
2427
|
-
inspect: inspectionEvent => {
|
|
2428
|
-
this.logger.debug("XState inspection event", {
|
|
2429
|
-
type: inspectionEvent.type,
|
|
2430
|
-
event: inspectionEvent.event,
|
|
2431
|
-
runId: this.#runId
|
|
2432
|
-
});
|
|
2433
|
-
},
|
|
2434
|
-
input: {
|
|
2435
|
-
...input,
|
|
2436
|
-
inputData: {
|
|
2437
|
-
...(snapshot?.context?.inputData || {}),
|
|
2438
|
-
...resumeData
|
|
2439
|
-
}
|
|
2440
|
-
},
|
|
2441
|
-
snapshot: actorSnapshot
|
|
2442
|
-
});
|
|
2443
|
-
this.#actor.start();
|
|
2444
|
-
if (stepId) {
|
|
2445
|
-
this.#actor.send({
|
|
2446
|
-
type: "RESET_TO_PENDING",
|
|
2447
|
-
stepId
|
|
2448
|
-
});
|
|
2449
|
-
}
|
|
2450
|
-
this.logger.debug("Actor started", {
|
|
2451
|
-
runId: this.#runId
|
|
2452
|
-
});
|
|
2453
|
-
return new Promise((resolve, reject) => {
|
|
2454
|
-
if (!this.#actor) {
|
|
2455
|
-
this.logger.error("Actor not initialized", {
|
|
2456
|
-
runId: this.#runId
|
|
2457
|
-
});
|
|
2458
|
-
const e = new Error("Actor not initialized");
|
|
2459
|
-
this.#executionSpan?.recordException(e);
|
|
2460
|
-
this.#executionSpan?.end();
|
|
2461
|
-
reject(e);
|
|
2462
|
-
return;
|
|
2463
|
-
}
|
|
2464
|
-
const suspendedPaths = /* @__PURE__ */new Set();
|
|
2465
|
-
this.#actor.subscribe(async state => {
|
|
2466
|
-
this.emit("state-update", this.#startStepId, state);
|
|
2467
|
-
getSuspendedPaths({
|
|
2468
|
-
value: state.value,
|
|
2469
|
-
path: "",
|
|
2470
|
-
suspendedPaths
|
|
2471
|
-
});
|
|
2472
|
-
const allStatesValue = state.value;
|
|
2473
|
-
const allStatesComplete = recursivelyCheckForFinalState({
|
|
2474
|
-
value: allStatesValue,
|
|
2475
|
-
suspendedPaths,
|
|
2476
|
-
path: ""
|
|
2477
|
-
});
|
|
2478
|
-
this.logger.debug("State completion check", {
|
|
2479
|
-
allStatesComplete,
|
|
2480
|
-
suspendedPaths: Array.from(suspendedPaths),
|
|
2481
|
-
runId: this.#runId
|
|
2482
|
-
});
|
|
2483
|
-
if (!allStatesComplete) {
|
|
2484
|
-
this.logger.debug("Not all states complete", {
|
|
2485
|
-
allStatesComplete,
|
|
2486
|
-
suspendedPaths: Array.from(suspendedPaths),
|
|
2487
|
-
runId: this.#runId
|
|
2488
|
-
});
|
|
2489
|
-
return;
|
|
2490
|
-
}
|
|
2491
|
-
try {
|
|
2492
|
-
this.logger.debug("All states complete", {
|
|
2493
|
-
runId: this.#runId
|
|
2494
|
-
});
|
|
2495
|
-
await this.#workflowInstance.persistWorkflowSnapshot();
|
|
2496
|
-
this.#cleanup();
|
|
2497
|
-
this.#executionSpan?.end();
|
|
2498
|
-
resolve({
|
|
2499
|
-
runId: this.#runId,
|
|
2500
|
-
results: isResumedInitialStep ? {
|
|
2501
|
-
...origSteps,
|
|
2502
|
-
...state.context.steps
|
|
2503
|
-
} : state.context.steps,
|
|
2504
|
-
activePaths: getResultActivePaths(state),
|
|
2505
|
-
timestamp: Date.now()
|
|
2506
|
-
});
|
|
2507
|
-
} catch (error) {
|
|
2508
|
-
this.logger.debug("Failed to persist final snapshot", {
|
|
2509
|
-
error
|
|
2510
|
-
});
|
|
2511
|
-
this.#cleanup();
|
|
2512
|
-
this.#executionSpan?.end();
|
|
2513
|
-
resolve({
|
|
2514
|
-
runId: this.#runId,
|
|
2515
|
-
results: isResumedInitialStep ? {
|
|
2516
|
-
...origSteps,
|
|
2517
|
-
...state.context.steps
|
|
2518
|
-
} : state.context.steps,
|
|
2519
|
-
activePaths: getResultActivePaths(state),
|
|
2520
|
-
timestamp: Date.now()
|
|
2521
|
-
});
|
|
2522
|
-
}
|
|
2523
|
-
});
|
|
2524
|
-
});
|
|
2525
|
-
}
|
|
2526
|
-
#cleanup() {
|
|
2527
|
-
if (this.#actor) {
|
|
2528
|
-
this.#actor.stop();
|
|
2529
|
-
this.#actor = null;
|
|
2530
|
-
}
|
|
2531
|
-
this.removeAllListeners();
|
|
2532
|
-
}
|
|
2533
|
-
#makeDelayMap() {
|
|
2534
|
-
const delayMap = {};
|
|
2535
|
-
Object.keys(this.#steps).forEach(stepId => {
|
|
2536
|
-
delayMap[stepId] = this.#steps[stepId]?.step?.retryConfig?.delay || this.#retryConfig?.delay || 1e3;
|
|
2537
|
-
});
|
|
2538
|
-
return delayMap;
|
|
2539
|
-
}
|
|
2540
|
-
#getDefaultActions() {
|
|
2541
|
-
return {
|
|
2542
|
-
updateStepResult: assign({
|
|
2543
|
-
steps: ({
|
|
2544
|
-
context,
|
|
2545
|
-
event
|
|
2546
|
-
}) => {
|
|
2547
|
-
if (!isTransitionEvent(event)) return context.steps;
|
|
2548
|
-
const {
|
|
2549
|
-
stepId,
|
|
2550
|
-
result
|
|
2551
|
-
} = event.output;
|
|
2552
|
-
return {
|
|
2553
|
-
...context.steps,
|
|
2554
|
-
[stepId]: {
|
|
2555
|
-
status: "success",
|
|
2556
|
-
output: result
|
|
2557
|
-
}
|
|
2558
|
-
};
|
|
2559
|
-
}
|
|
2560
|
-
}),
|
|
2561
|
-
setStepError: assign({
|
|
2562
|
-
steps: ({
|
|
2563
|
-
context,
|
|
2564
|
-
event
|
|
2565
|
-
}, params) => {
|
|
2566
|
-
if (!isErrorEvent(event)) return context.steps;
|
|
2567
|
-
const {
|
|
2568
|
-
stepId
|
|
2569
|
-
} = params;
|
|
2570
|
-
if (!stepId) return context.steps;
|
|
2571
|
-
return {
|
|
2572
|
-
...context.steps,
|
|
2573
|
-
[stepId]: {
|
|
2574
|
-
status: "failed",
|
|
2575
|
-
error: event.error.message
|
|
2576
|
-
}
|
|
2577
|
-
};
|
|
2578
|
-
}
|
|
2579
|
-
}),
|
|
2580
|
-
notifyStepCompletion: async (_, params) => {
|
|
2581
|
-
const {
|
|
2582
|
-
stepId
|
|
2583
|
-
} = params;
|
|
2584
|
-
this.logger.debug(`Step ${stepId} completed`);
|
|
2585
|
-
},
|
|
2586
|
-
snapshotStep: assign({
|
|
2587
|
-
_snapshot: ({}, params) => {
|
|
2588
|
-
const {
|
|
2589
|
-
stepId
|
|
2590
|
-
} = params;
|
|
2591
|
-
return {
|
|
2592
|
-
stepId
|
|
2593
|
-
};
|
|
2594
|
-
}
|
|
2595
|
-
}),
|
|
2596
|
-
persistSnapshot: async ({
|
|
2597
|
-
context
|
|
2598
|
-
}) => {
|
|
2599
|
-
if (context._snapshot) {
|
|
2600
|
-
await this.#workflowInstance.persistWorkflowSnapshot();
|
|
2601
|
-
}
|
|
2602
|
-
return;
|
|
2603
|
-
},
|
|
2604
|
-
decrementAttemptCount: assign({
|
|
2605
|
-
attempts: ({
|
|
2606
|
-
context,
|
|
2607
|
-
event
|
|
2608
|
-
}, params) => {
|
|
2609
|
-
if (!isTransitionEvent(event)) return context.attempts;
|
|
2610
|
-
const {
|
|
2611
|
-
stepId
|
|
2612
|
-
} = params;
|
|
2613
|
-
const attemptCount = context.attempts[stepId];
|
|
2614
|
-
if (attemptCount === void 0) return context.attempts;
|
|
2615
|
-
return {
|
|
2616
|
-
...context.attempts,
|
|
2617
|
-
[stepId]: attemptCount - 1
|
|
2618
|
-
};
|
|
2619
|
-
}
|
|
2620
|
-
})
|
|
2621
|
-
};
|
|
2622
|
-
}
|
|
2623
|
-
#getDefaultActors() {
|
|
2624
|
-
return {
|
|
2625
|
-
resolverFunction: fromPromise(async ({
|
|
2626
|
-
input
|
|
2627
|
-
}) => {
|
|
2628
|
-
const {
|
|
2629
|
-
stepNode,
|
|
2630
|
-
context
|
|
2631
|
-
} = input;
|
|
2632
|
-
const attemptCount = context.attempts[stepNode.id];
|
|
2633
|
-
const resolvedData = this.#resolveVariables({
|
|
2634
|
-
stepConfig: stepNode.config,
|
|
2635
|
-
context,
|
|
2636
|
-
stepId: stepNode.id
|
|
2637
|
-
});
|
|
2638
|
-
this.logger.debug(`Resolved variables for ${stepNode.id}`, {
|
|
2639
|
-
resolvedData,
|
|
2640
|
-
runId: this.#runId
|
|
2641
|
-
});
|
|
2642
|
-
const logger = this.logger;
|
|
2643
|
-
let mastraProxy = void 0;
|
|
2644
|
-
if (this.#mastra) {
|
|
2645
|
-
mastraProxy = createMastraProxy({
|
|
2646
|
-
mastra: this.#mastra,
|
|
2647
|
-
logger
|
|
2648
|
-
});
|
|
2649
|
-
}
|
|
2650
|
-
let result = void 0;
|
|
2651
|
-
try {
|
|
2652
|
-
result = await stepNode.config.handler({
|
|
2653
|
-
context: {
|
|
2654
|
-
...context,
|
|
2655
|
-
inputData: {
|
|
2656
|
-
...(context?.inputData || {}),
|
|
2657
|
-
...resolvedData
|
|
2658
|
-
},
|
|
2659
|
-
getStepResult: stepId => {
|
|
2660
|
-
const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id;
|
|
2661
|
-
if (resolvedStepId === "trigger") {
|
|
2662
|
-
return context.triggerData;
|
|
2663
|
-
}
|
|
2664
|
-
const result2 = context.steps[resolvedStepId];
|
|
2665
|
-
if (result2 && result2.status === "success") {
|
|
2666
|
-
return result2.output;
|
|
2667
|
-
}
|
|
2668
|
-
return void 0;
|
|
2669
|
-
}
|
|
2670
|
-
},
|
|
2671
|
-
emit: (event, ...args) => {
|
|
2672
|
-
this.emit(event, ...args);
|
|
2673
|
-
},
|
|
2674
|
-
suspend: async (payload, softSuspend) => {
|
|
2675
|
-
await this.#workflowInstance.suspend(stepNode.id, this);
|
|
2676
|
-
if (this.#actor) {
|
|
2677
|
-
context.steps[stepNode.id] = {
|
|
2678
|
-
status: "suspended",
|
|
2679
|
-
suspendPayload: payload,
|
|
2680
|
-
output: softSuspend
|
|
2681
|
-
};
|
|
2682
|
-
this.logger.debug(`Sending SUSPENDED event for step ${stepNode.id}`);
|
|
2683
|
-
this.#actor?.send({
|
|
2684
|
-
type: "SUSPENDED",
|
|
2685
|
-
suspendPayload: payload,
|
|
2686
|
-
stepId: stepNode.id,
|
|
2687
|
-
softSuspend
|
|
2688
|
-
});
|
|
2689
|
-
} else {
|
|
2690
|
-
this.logger.debug(`Actor not available for step ${stepNode.id}`);
|
|
2691
|
-
}
|
|
2692
|
-
},
|
|
2693
|
-
runId: this.#runId,
|
|
2694
|
-
mastra: mastraProxy,
|
|
2695
|
-
runtimeContext: this.#runtimeContext
|
|
2696
|
-
});
|
|
2697
|
-
} catch (error) {
|
|
2698
|
-
this.logger.debug(`Step ${stepNode.id} failed`, {
|
|
2699
|
-
stepId: stepNode.id,
|
|
2700
|
-
error,
|
|
2701
|
-
runId: this.#runId
|
|
2702
|
-
});
|
|
2703
|
-
this.logger.debug(`Attempt count for step ${stepNode.id}`, {
|
|
2704
|
-
attemptCount,
|
|
2705
|
-
attempts: context.attempts,
|
|
2706
|
-
runId: this.#runId,
|
|
2707
|
-
stepId: stepNode.id
|
|
2708
|
-
});
|
|
2709
|
-
if (!attemptCount || attemptCount < 0) {
|
|
2710
|
-
return {
|
|
2711
|
-
type: "STEP_FAILED",
|
|
2712
|
-
error: error instanceof Error ? error.message : `Step:${stepNode.id} failed with error: ${error}`,
|
|
2713
|
-
stepId: stepNode.id
|
|
2714
|
-
};
|
|
2715
|
-
}
|
|
2716
|
-
return {
|
|
2717
|
-
type: "STEP_WAITING",
|
|
2718
|
-
stepId: stepNode.id
|
|
2719
|
-
};
|
|
2720
|
-
}
|
|
2721
|
-
this.logger.debug(`Step ${stepNode.id} result`, {
|
|
2722
|
-
stepId: stepNode.id,
|
|
2723
|
-
result,
|
|
2724
|
-
runId: this.#runId
|
|
2725
|
-
});
|
|
2726
|
-
return {
|
|
2727
|
-
type: "STEP_SUCCESS",
|
|
2728
|
-
result,
|
|
2729
|
-
stepId: stepNode.id
|
|
2730
|
-
};
|
|
2731
|
-
}),
|
|
2732
|
-
conditionCheck: fromPromise(async ({
|
|
2733
|
-
input
|
|
2734
|
-
}) => {
|
|
2735
|
-
const {
|
|
2736
|
-
context,
|
|
2737
|
-
stepNode
|
|
2738
|
-
} = input;
|
|
2739
|
-
const stepConfig = stepNode.config;
|
|
2740
|
-
this.logger.debug(`Checking conditions for step ${stepNode.id}`, {
|
|
2741
|
-
stepId: stepNode.id,
|
|
2742
|
-
runId: this.#runId
|
|
2743
|
-
});
|
|
2744
|
-
if (!stepConfig?.when) {
|
|
2745
|
-
return {
|
|
2746
|
-
type: "CONDITIONS_MET"
|
|
2747
|
-
};
|
|
2748
|
-
}
|
|
2749
|
-
this.logger.debug(`Checking conditions for step ${stepNode.id}`, {
|
|
2750
|
-
stepId: stepNode.id,
|
|
2751
|
-
runId: this.#runId
|
|
2752
|
-
});
|
|
2753
|
-
if (typeof stepConfig?.when === "function") {
|
|
2754
|
-
let conditionMet = await stepConfig.when({
|
|
2755
|
-
context: {
|
|
2756
|
-
...context,
|
|
2757
|
-
getStepResult: stepId => {
|
|
2758
|
-
const resolvedStepId = typeof stepId === "string" ? stepId : stepId.id;
|
|
2759
|
-
if (resolvedStepId === "trigger") {
|
|
2760
|
-
return context.triggerData;
|
|
2761
|
-
}
|
|
2762
|
-
const result = context.steps[resolvedStepId];
|
|
2763
|
-
if (result && result.status === "success") {
|
|
2764
|
-
return result.output;
|
|
2765
|
-
}
|
|
2766
|
-
return void 0;
|
|
2767
|
-
}
|
|
2768
|
-
},
|
|
2769
|
-
mastra: this.#mastra
|
|
2770
|
-
});
|
|
2771
|
-
if (conditionMet === "abort" /* ABORT */) {
|
|
2772
|
-
conditionMet = false;
|
|
2773
|
-
} else if (conditionMet === "continue_failed" /* CONTINUE_FAILED */) {
|
|
2774
|
-
return {
|
|
2775
|
-
type: "CONDITIONS_SKIP_TO_COMPLETED"
|
|
2776
|
-
};
|
|
2777
|
-
} else if (conditionMet === "limbo" /* LIMBO */) {
|
|
2778
|
-
return {
|
|
2779
|
-
type: "CONDITIONS_LIMBO"
|
|
2780
|
-
};
|
|
2781
|
-
} else if (conditionMet) {
|
|
2782
|
-
this.logger.debug(`Condition met for step ${stepNode.id}`, {
|
|
2783
|
-
stepId: stepNode.id,
|
|
2784
|
-
runId: this.#runId
|
|
2785
|
-
});
|
|
2786
|
-
return {
|
|
2787
|
-
type: "CONDITIONS_MET"
|
|
2788
|
-
};
|
|
2789
|
-
}
|
|
2790
|
-
if (isConditionalKey(stepNode.id)) {
|
|
2791
|
-
return {
|
|
2792
|
-
type: "CONDITIONS_LIMBO"
|
|
2793
|
-
};
|
|
2794
|
-
}
|
|
2795
|
-
return this.#workflowInstance.hasSubscribers(stepNode.id) ? {
|
|
2796
|
-
type: "CONDITIONS_SKIPPED"
|
|
2797
|
-
} : {
|
|
2798
|
-
type: "CONDITIONS_LIMBO"
|
|
2799
|
-
};
|
|
2800
|
-
} else {
|
|
2801
|
-
const conditionMet = this.#evaluateCondition(stepConfig.when, context);
|
|
2802
|
-
if (!conditionMet) {
|
|
2803
|
-
return {
|
|
2804
|
-
type: "CONDITION_FAILED",
|
|
2805
|
-
error: `Step:${stepNode.id} condition check failed`
|
|
2806
|
-
};
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
return {
|
|
2810
|
-
type: "CONDITIONS_MET"
|
|
2811
|
-
};
|
|
2812
|
-
}),
|
|
2813
|
-
spawnSubscriberFunction: fromPromise(async ({
|
|
2814
|
-
input
|
|
2815
|
-
}) => {
|
|
2816
|
-
const {
|
|
2817
|
-
parentStepId,
|
|
2818
|
-
context
|
|
2819
|
-
} = input;
|
|
2820
|
-
const result = await this.#workflowInstance.runMachine(parentStepId, context, this.#runtimeContext);
|
|
2821
|
-
return Promise.resolve({
|
|
2822
|
-
steps: result.reduce((acc, r) => {
|
|
2823
|
-
return {
|
|
2824
|
-
...acc,
|
|
2825
|
-
...r?.results
|
|
2826
|
-
};
|
|
2827
|
-
}, {})
|
|
2828
|
-
});
|
|
2829
|
-
})
|
|
2830
|
-
};
|
|
2831
|
-
}
|
|
2832
|
-
#resolveVariables({
|
|
2833
|
-
stepConfig,
|
|
2834
|
-
context,
|
|
2835
|
-
stepId
|
|
2836
|
-
}) {
|
|
2837
|
-
this.logger.debug(`Resolving variables for step ${stepId}`, {
|
|
2838
|
-
stepId,
|
|
2839
|
-
runId: this.#runId
|
|
2840
|
-
});
|
|
2841
|
-
const resolvedData = {};
|
|
2842
|
-
for (const [key, variable] of Object.entries(stepConfig.data)) {
|
|
2843
|
-
const sourceData = variable.step === "trigger" ? context.triggerData : getStepResult(context.steps[variable.step.id]);
|
|
2844
|
-
this.logger.debug(`Got source data for ${key} variable from ${variable.step === "trigger" ? "trigger" : variable.step.id}`, {
|
|
2845
|
-
sourceData,
|
|
2846
|
-
path: variable.path,
|
|
2847
|
-
runId: this.#runId
|
|
2848
|
-
});
|
|
2849
|
-
if (!sourceData && variable.step !== "trigger") {
|
|
2850
|
-
resolvedData[key] = void 0;
|
|
2851
|
-
continue;
|
|
2852
|
-
}
|
|
2853
|
-
const value = variable.path === "" || variable.path === "." ? sourceData : get(sourceData, variable.path);
|
|
2854
|
-
this.logger.debug(`Resolved variable ${key}`, {
|
|
2855
|
-
value,
|
|
2856
|
-
runId: this.#runId
|
|
2857
|
-
});
|
|
2858
|
-
resolvedData[key] = value;
|
|
2859
|
-
}
|
|
2860
|
-
return resolvedData;
|
|
2861
|
-
}
|
|
2862
|
-
initializeMachine() {
|
|
2863
|
-
const machine = setup({
|
|
2864
|
-
types: {},
|
|
2865
|
-
delays: this.#makeDelayMap(),
|
|
2866
|
-
actions: this.#getDefaultActions(),
|
|
2867
|
-
actors: this.#getDefaultActors()
|
|
2868
|
-
}).createMachine({
|
|
2869
|
-
id: this.name,
|
|
2870
|
-
type: "parallel",
|
|
2871
|
-
context: ({
|
|
2872
|
-
input
|
|
2873
|
-
}) => ({
|
|
2874
|
-
...input
|
|
2875
|
-
}),
|
|
2876
|
-
states: this.#buildStateHierarchy(this.#stepGraph)
|
|
2877
|
-
});
|
|
2878
|
-
this.#machine = machine;
|
|
2879
|
-
return machine;
|
|
2880
|
-
}
|
|
2881
|
-
#buildStateHierarchy(stepGraph) {
|
|
2882
|
-
const states = {};
|
|
2883
|
-
stepGraph.initial.forEach(stepNode => {
|
|
2884
|
-
const nextSteps = [...(stepGraph[stepNode.id] || [])];
|
|
2885
|
-
states[stepNode.id] = {
|
|
2886
|
-
...this.#buildBaseState(stepNode, nextSteps)
|
|
2887
|
-
};
|
|
2888
|
-
});
|
|
2889
|
-
return states;
|
|
2890
|
-
}
|
|
2891
|
-
#buildBaseState(stepNode, nextSteps = []) {
|
|
2892
|
-
const nextStep = nextSteps.shift();
|
|
2893
|
-
return {
|
|
2894
|
-
initial: "pending",
|
|
2895
|
-
on: {
|
|
2896
|
-
RESET_TO_PENDING: {
|
|
2897
|
-
target: ".pending"
|
|
2898
|
-
// Note the dot to target child state
|
|
2899
|
-
}
|
|
2900
|
-
},
|
|
2901
|
-
states: {
|
|
2902
|
-
pending: {
|
|
2903
|
-
entry: () => {
|
|
2904
|
-
this.logger.debug(`Step ${stepNode.id} pending`, {
|
|
2905
|
-
stepId: stepNode.id,
|
|
2906
|
-
runId: this.#runId
|
|
2907
|
-
});
|
|
2908
|
-
},
|
|
2909
|
-
exit: () => {
|
|
2910
|
-
this.logger.debug(`Step ${stepNode.id} finished pending`, {
|
|
2911
|
-
stepId: stepNode.id,
|
|
2912
|
-
runId: this.#runId
|
|
2913
|
-
});
|
|
2914
|
-
},
|
|
2915
|
-
invoke: {
|
|
2916
|
-
src: "conditionCheck",
|
|
2917
|
-
input: ({
|
|
2918
|
-
context
|
|
2919
|
-
}) => {
|
|
2920
|
-
return {
|
|
2921
|
-
context,
|
|
2922
|
-
stepNode
|
|
2923
|
-
};
|
|
2924
|
-
},
|
|
2925
|
-
onDone: [{
|
|
2926
|
-
guard: ({
|
|
2927
|
-
event
|
|
2928
|
-
}) => {
|
|
2929
|
-
return event.output.type === "SUSPENDED";
|
|
2930
|
-
},
|
|
2931
|
-
target: "suspended",
|
|
2932
|
-
actions: [assign({
|
|
2933
|
-
steps: ({
|
|
2934
|
-
context,
|
|
2935
|
-
event
|
|
2936
|
-
}) => {
|
|
2937
|
-
if (event.output.type !== "SUSPENDED") return context.steps;
|
|
2938
|
-
if (event.output.softSuspend) {
|
|
2939
|
-
return {
|
|
2940
|
-
...context.steps,
|
|
2941
|
-
[stepNode.id]: {
|
|
2942
|
-
status: "suspended",
|
|
2943
|
-
...(context.steps?.[stepNode.id] || {}),
|
|
2944
|
-
output: event.output.softSuspend
|
|
2945
|
-
}
|
|
2946
|
-
};
|
|
2947
|
-
}
|
|
2948
|
-
return {
|
|
2949
|
-
...context.steps,
|
|
2950
|
-
[stepNode.id]: {
|
|
2951
|
-
status: "suspended",
|
|
2952
|
-
...(context.steps?.[stepNode.id] || {})
|
|
2953
|
-
}
|
|
2954
|
-
};
|
|
2955
|
-
},
|
|
2956
|
-
attempts: ({
|
|
2957
|
-
context,
|
|
2958
|
-
event
|
|
2959
|
-
}) => {
|
|
2960
|
-
if (event.output.type !== "SUSPENDED") return context.attempts;
|
|
2961
|
-
return {
|
|
2962
|
-
...context.attempts,
|
|
2963
|
-
[stepNode.id]: stepNode.step.retryConfig?.attempts || 0
|
|
2964
|
-
};
|
|
2965
|
-
}
|
|
2966
|
-
})]
|
|
2967
|
-
}, {
|
|
2968
|
-
guard: ({
|
|
2969
|
-
event
|
|
2970
|
-
}) => {
|
|
2971
|
-
return event.output.type === "WAITING";
|
|
2972
|
-
},
|
|
2973
|
-
target: "waiting",
|
|
2974
|
-
actions: [{
|
|
2975
|
-
type: "decrementAttemptCount",
|
|
2976
|
-
params: {
|
|
2977
|
-
stepId: stepNode.id
|
|
2978
|
-
}
|
|
2979
|
-
}, assign({
|
|
2980
|
-
steps: ({
|
|
2981
|
-
context,
|
|
2982
|
-
event
|
|
2983
|
-
}) => {
|
|
2984
|
-
if (event.output.type !== "WAITING") return context.steps;
|
|
2985
|
-
return {
|
|
2986
|
-
...context.steps,
|
|
2987
|
-
[stepNode.id]: {
|
|
2988
|
-
status: "waiting"
|
|
2989
|
-
}
|
|
2990
|
-
};
|
|
2991
|
-
}
|
|
2992
|
-
})]
|
|
2993
|
-
}, {
|
|
2994
|
-
guard: ({
|
|
2995
|
-
event
|
|
2996
|
-
}) => {
|
|
2997
|
-
return event.output.type === "CONDITIONS_MET";
|
|
2998
|
-
},
|
|
2999
|
-
target: "executing"
|
|
3000
|
-
}, {
|
|
3001
|
-
guard: ({
|
|
3002
|
-
event
|
|
3003
|
-
}) => {
|
|
3004
|
-
return event.output.type === "CONDITIONS_SKIP_TO_COMPLETED";
|
|
3005
|
-
},
|
|
3006
|
-
target: "completed"
|
|
3007
|
-
}, {
|
|
3008
|
-
guard: ({
|
|
3009
|
-
event
|
|
3010
|
-
}) => {
|
|
3011
|
-
return event.output.type === "CONDITIONS_SKIPPED";
|
|
3012
|
-
},
|
|
3013
|
-
actions: assign({
|
|
3014
|
-
steps: ({
|
|
3015
|
-
context
|
|
3016
|
-
}) => {
|
|
3017
|
-
const newStep = {
|
|
3018
|
-
...context.steps,
|
|
3019
|
-
[stepNode.id]: {
|
|
3020
|
-
status: "skipped"
|
|
3021
|
-
}
|
|
3022
|
-
};
|
|
3023
|
-
this.logger.debug(`Step ${stepNode.id} skipped`, {
|
|
3024
|
-
stepId: stepNode.id,
|
|
3025
|
-
runId: this.#runId
|
|
3026
|
-
});
|
|
3027
|
-
return newStep;
|
|
3028
|
-
}
|
|
3029
|
-
}),
|
|
3030
|
-
target: "runningSubscribers"
|
|
3031
|
-
}, {
|
|
3032
|
-
guard: ({
|
|
3033
|
-
event
|
|
3034
|
-
}) => {
|
|
3035
|
-
return event.output.type === "CONDITIONS_LIMBO";
|
|
3036
|
-
},
|
|
3037
|
-
target: "limbo",
|
|
3038
|
-
actions: assign({
|
|
3039
|
-
steps: ({
|
|
3040
|
-
context
|
|
3041
|
-
}) => {
|
|
3042
|
-
const newStep = {
|
|
3043
|
-
...context.steps,
|
|
3044
|
-
[stepNode.id]: {
|
|
3045
|
-
status: "skipped"
|
|
3046
|
-
}
|
|
3047
|
-
};
|
|
3048
|
-
this.logger.debug(`Step ${stepNode.id} skipped`, {
|
|
3049
|
-
stepId: stepNode.id,
|
|
3050
|
-
runId: this.#runId
|
|
3051
|
-
});
|
|
3052
|
-
return newStep;
|
|
3053
|
-
}
|
|
3054
|
-
})
|
|
3055
|
-
}, {
|
|
3056
|
-
guard: ({
|
|
3057
|
-
event
|
|
3058
|
-
}) => {
|
|
3059
|
-
return event.output.type === "CONDITION_FAILED";
|
|
3060
|
-
},
|
|
3061
|
-
target: "failed",
|
|
3062
|
-
actions: assign({
|
|
3063
|
-
steps: ({
|
|
3064
|
-
context,
|
|
3065
|
-
event
|
|
3066
|
-
}) => {
|
|
3067
|
-
if (event.output.type !== "CONDITION_FAILED") return context.steps;
|
|
3068
|
-
this.logger.debug(`Workflow condition check failed`, {
|
|
3069
|
-
error: event.output.error,
|
|
3070
|
-
stepId: stepNode.id
|
|
3071
|
-
});
|
|
3072
|
-
return {
|
|
3073
|
-
...context.steps,
|
|
3074
|
-
[stepNode.id]: {
|
|
3075
|
-
status: "failed",
|
|
3076
|
-
error: event.output.error
|
|
3077
|
-
}
|
|
3078
|
-
};
|
|
3079
|
-
}
|
|
3080
|
-
})
|
|
3081
|
-
}]
|
|
3082
|
-
}
|
|
3083
|
-
},
|
|
3084
|
-
waiting: {
|
|
3085
|
-
entry: () => {
|
|
3086
|
-
this.logger.debug(`Step ${stepNode.id} waiting`, {
|
|
3087
|
-
stepId: stepNode.id,
|
|
3088
|
-
timestamp: (/* @__PURE__ */new Date()).toISOString(),
|
|
3089
|
-
runId: this.#runId
|
|
3090
|
-
});
|
|
3091
|
-
},
|
|
3092
|
-
exit: () => {
|
|
3093
|
-
this.logger.debug(`Step ${stepNode.id} finished waiting`, {
|
|
3094
|
-
stepId: stepNode.id,
|
|
3095
|
-
timestamp: (/* @__PURE__ */new Date()).toISOString(),
|
|
3096
|
-
runId: this.#runId
|
|
3097
|
-
});
|
|
3098
|
-
},
|
|
3099
|
-
after: {
|
|
3100
|
-
[stepNode.id]: {
|
|
3101
|
-
target: "pending"
|
|
3102
|
-
}
|
|
3103
|
-
}
|
|
3104
|
-
},
|
|
3105
|
-
limbo: {
|
|
3106
|
-
// no target, will stay in limbo indefinitely
|
|
3107
|
-
entry: () => {
|
|
3108
|
-
this.logger.debug(`Step ${stepNode.id} limbo`, {
|
|
3109
|
-
stepId: stepNode.id,
|
|
3110
|
-
timestamp: (/* @__PURE__ */new Date()).toISOString(),
|
|
3111
|
-
runId: this.#runId
|
|
3112
|
-
});
|
|
3113
|
-
},
|
|
3114
|
-
exit: () => {
|
|
3115
|
-
this.logger.debug(`Step ${stepNode.id} finished limbo`, {
|
|
3116
|
-
stepId: stepNode.id,
|
|
3117
|
-
timestamp: (/* @__PURE__ */new Date()).toISOString(),
|
|
3118
|
-
runId: this.#runId
|
|
3119
|
-
});
|
|
3120
|
-
}
|
|
3121
|
-
},
|
|
3122
|
-
suspended: {
|
|
3123
|
-
type: "final",
|
|
3124
|
-
entry: [() => {
|
|
3125
|
-
this.logger.debug(`Step ${stepNode.id} suspended`, {
|
|
3126
|
-
stepId: stepNode.id,
|
|
3127
|
-
runId: this.#runId
|
|
3128
|
-
});
|
|
3129
|
-
}, assign({
|
|
3130
|
-
steps: ({
|
|
3131
|
-
context,
|
|
3132
|
-
event
|
|
3133
|
-
}) => {
|
|
3134
|
-
return {
|
|
3135
|
-
...context.steps,
|
|
3136
|
-
[stepNode.id]: {
|
|
3137
|
-
...(context?.steps?.[stepNode.id] || {}),
|
|
3138
|
-
status: "suspended",
|
|
3139
|
-
suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0,
|
|
3140
|
-
output: event.type === "SUSPENDED" ? event.softSuspend : void 0
|
|
3141
|
-
}
|
|
3142
|
-
};
|
|
3143
|
-
}
|
|
3144
|
-
})]
|
|
3145
|
-
},
|
|
3146
|
-
executing: {
|
|
3147
|
-
entry: () => {
|
|
3148
|
-
this.logger.debug(`Step ${stepNode.id} executing`, {
|
|
3149
|
-
stepId: stepNode.id,
|
|
3150
|
-
runId: this.#runId
|
|
3151
|
-
});
|
|
3152
|
-
},
|
|
3153
|
-
on: {
|
|
3154
|
-
SUSPENDED: {
|
|
3155
|
-
target: "suspended",
|
|
3156
|
-
actions: [assign({
|
|
3157
|
-
steps: ({
|
|
3158
|
-
context,
|
|
3159
|
-
event
|
|
3160
|
-
}) => {
|
|
3161
|
-
return {
|
|
3162
|
-
...context.steps,
|
|
3163
|
-
[stepNode.id]: {
|
|
3164
|
-
status: "suspended",
|
|
3165
|
-
suspendPayload: event.type === "SUSPENDED" ? event.suspendPayload : void 0,
|
|
3166
|
-
output: event.type === "SUSPENDED" ? event.softSuspend : void 0
|
|
3167
|
-
}
|
|
3168
|
-
};
|
|
3169
|
-
}
|
|
3170
|
-
})]
|
|
3171
|
-
}
|
|
3172
|
-
},
|
|
3173
|
-
invoke: {
|
|
3174
|
-
src: "resolverFunction",
|
|
3175
|
-
input: ({
|
|
3176
|
-
context
|
|
3177
|
-
}) => ({
|
|
3178
|
-
context,
|
|
3179
|
-
stepNode
|
|
3180
|
-
}),
|
|
3181
|
-
onDone: [{
|
|
3182
|
-
guard: ({
|
|
3183
|
-
event
|
|
3184
|
-
}) => {
|
|
3185
|
-
return event.output.type === "STEP_FAILED";
|
|
3186
|
-
},
|
|
3187
|
-
target: "failed",
|
|
3188
|
-
actions: assign({
|
|
3189
|
-
steps: ({
|
|
3190
|
-
context,
|
|
3191
|
-
event
|
|
3192
|
-
}) => {
|
|
3193
|
-
if (event.output.type !== "STEP_FAILED") return context.steps;
|
|
3194
|
-
const newStep = {
|
|
3195
|
-
...context.steps,
|
|
3196
|
-
[stepNode.id]: {
|
|
3197
|
-
status: "failed",
|
|
3198
|
-
error: event.output.error
|
|
3199
|
-
}
|
|
3200
|
-
};
|
|
3201
|
-
this.logger.debug(`Step ${stepNode.id} failed`, {
|
|
3202
|
-
error: event.output.error,
|
|
3203
|
-
stepId: stepNode.id
|
|
3204
|
-
});
|
|
3205
|
-
return newStep;
|
|
3206
|
-
}
|
|
3207
|
-
})
|
|
3208
|
-
}, {
|
|
3209
|
-
guard: ({
|
|
3210
|
-
event
|
|
3211
|
-
}) => {
|
|
3212
|
-
return event.output.type === "STEP_SUCCESS";
|
|
3213
|
-
},
|
|
3214
|
-
actions: [({
|
|
3215
|
-
event
|
|
3216
|
-
}) => {
|
|
3217
|
-
this.logger.debug(`Step ${stepNode.id} finished executing`, {
|
|
3218
|
-
stepId: stepNode.id,
|
|
3219
|
-
output: event.output,
|
|
3220
|
-
runId: this.#runId
|
|
3221
|
-
});
|
|
3222
|
-
}, {
|
|
3223
|
-
type: "updateStepResult",
|
|
3224
|
-
params: {
|
|
3225
|
-
stepId: stepNode.id
|
|
3226
|
-
}
|
|
3227
|
-
}, {
|
|
3228
|
-
type: "spawnSubscribers",
|
|
3229
|
-
params: {
|
|
3230
|
-
stepId: stepNode.id
|
|
3231
|
-
}
|
|
3232
|
-
}],
|
|
3233
|
-
target: "runningSubscribers"
|
|
3234
|
-
}, {
|
|
3235
|
-
guard: ({
|
|
3236
|
-
event
|
|
3237
|
-
}) => {
|
|
3238
|
-
return event.output.type === "STEP_WAITING";
|
|
3239
|
-
},
|
|
3240
|
-
target: "waiting",
|
|
3241
|
-
actions: [{
|
|
3242
|
-
type: "decrementAttemptCount",
|
|
3243
|
-
params: {
|
|
3244
|
-
stepId: stepNode.id
|
|
3245
|
-
}
|
|
3246
|
-
}, assign({
|
|
3247
|
-
steps: ({
|
|
3248
|
-
context,
|
|
3249
|
-
event
|
|
3250
|
-
}) => {
|
|
3251
|
-
if (event.output.type !== "STEP_WAITING") return context.steps;
|
|
3252
|
-
return {
|
|
3253
|
-
...context.steps,
|
|
3254
|
-
[stepNode.id]: {
|
|
3255
|
-
status: "waiting"
|
|
3256
|
-
}
|
|
3257
|
-
};
|
|
3258
|
-
}
|
|
3259
|
-
})]
|
|
3260
|
-
}],
|
|
3261
|
-
onError: {
|
|
3262
|
-
target: "failed",
|
|
3263
|
-
actions: [{
|
|
3264
|
-
type: "setStepError",
|
|
3265
|
-
params: {
|
|
3266
|
-
stepId: stepNode.id
|
|
3267
|
-
}
|
|
3268
|
-
}]
|
|
3269
|
-
}
|
|
3270
|
-
}
|
|
3271
|
-
},
|
|
3272
|
-
runningSubscribers: {
|
|
3273
|
-
entry: () => {
|
|
3274
|
-
this.logger.debug(`Step ${stepNode.id} running subscribers`, {
|
|
3275
|
-
stepId: stepNode.id,
|
|
3276
|
-
runId: this.#runId
|
|
3277
|
-
});
|
|
3278
|
-
},
|
|
3279
|
-
exit: () => {
|
|
3280
|
-
this.logger.debug(`Step ${stepNode.id} finished running subscribers`, {
|
|
3281
|
-
stepId: stepNode.id,
|
|
3282
|
-
runId: this.#runId
|
|
3283
|
-
});
|
|
3284
|
-
},
|
|
3285
|
-
invoke: {
|
|
3286
|
-
src: "spawnSubscriberFunction",
|
|
3287
|
-
input: ({
|
|
3288
|
-
context
|
|
3289
|
-
}) => ({
|
|
3290
|
-
parentStepId: stepNode.id,
|
|
3291
|
-
context
|
|
3292
|
-
}),
|
|
3293
|
-
onDone: {
|
|
3294
|
-
target: nextStep ? nextStep.id : "completed",
|
|
3295
|
-
actions: [assign({
|
|
3296
|
-
steps: ({
|
|
3297
|
-
context,
|
|
3298
|
-
event
|
|
3299
|
-
}) => ({
|
|
3300
|
-
...context.steps,
|
|
3301
|
-
...event.output.steps
|
|
3302
|
-
})
|
|
3303
|
-
}), () => this.logger.debug(`Subscriber execution completed`, {
|
|
3304
|
-
stepId: stepNode.id
|
|
3305
|
-
})]
|
|
3306
|
-
},
|
|
3307
|
-
onError: {
|
|
3308
|
-
target: nextStep ? nextStep.id : "completed",
|
|
3309
|
-
actions: ({
|
|
3310
|
-
event
|
|
3311
|
-
}) => {
|
|
3312
|
-
this.logger.debug(`Subscriber execution failed`, {
|
|
3313
|
-
error: event.error,
|
|
3314
|
-
stepId: stepNode.id
|
|
3315
|
-
});
|
|
3316
|
-
}
|
|
3317
|
-
}
|
|
3318
|
-
}
|
|
3319
|
-
},
|
|
3320
|
-
completed: {
|
|
3321
|
-
type: "final",
|
|
3322
|
-
entry: [{
|
|
3323
|
-
type: "notifyStepCompletion",
|
|
3324
|
-
params: {
|
|
3325
|
-
stepId: stepNode.id
|
|
3326
|
-
}
|
|
3327
|
-
}, {
|
|
3328
|
-
type: "snapshotStep",
|
|
3329
|
-
params: {
|
|
3330
|
-
stepId: stepNode.id
|
|
3331
|
-
}
|
|
3332
|
-
}, {
|
|
3333
|
-
type: "persistSnapshot"
|
|
3334
|
-
}]
|
|
3335
|
-
},
|
|
3336
|
-
failed: {
|
|
3337
|
-
type: "final",
|
|
3338
|
-
entry: [{
|
|
3339
|
-
type: "notifyStepCompletion",
|
|
3340
|
-
params: {
|
|
3341
|
-
stepId: stepNode.id
|
|
3342
|
-
}
|
|
3343
|
-
}, {
|
|
3344
|
-
type: "snapshotStep",
|
|
3345
|
-
params: {
|
|
3346
|
-
stepId: stepNode.id
|
|
3347
|
-
}
|
|
3348
|
-
}, {
|
|
3349
|
-
type: "persistSnapshot"
|
|
3350
|
-
}]
|
|
3351
|
-
},
|
|
3352
|
-
// build chain of next steps recursively
|
|
3353
|
-
...(nextStep ? {
|
|
3354
|
-
[nextStep.id]: {
|
|
3355
|
-
...this.#buildBaseState(nextStep, nextSteps)
|
|
3356
|
-
}
|
|
3357
|
-
} : {})
|
|
3358
|
-
}
|
|
3359
|
-
};
|
|
3360
|
-
}
|
|
3361
|
-
#evaluateCondition(condition, context) {
|
|
3362
|
-
let andBranchResult = true;
|
|
3363
|
-
let baseResult = true;
|
|
3364
|
-
let orBranchResult = true;
|
|
3365
|
-
const simpleCondition = Object.entries(condition).find(([key]) => key.includes("."));
|
|
3366
|
-
if (simpleCondition) {
|
|
3367
|
-
const [key, queryValue] = simpleCondition;
|
|
3368
|
-
const [stepId, ...pathParts] = key.split(".");
|
|
3369
|
-
const path = pathParts.join(".");
|
|
3370
|
-
const sourceData = stepId === "trigger" ? context.triggerData : getStepResult(context.steps[stepId]);
|
|
3371
|
-
this.logger.debug(`Got condition data from step ${stepId}`, {
|
|
3372
|
-
stepId,
|
|
3373
|
-
sourceData,
|
|
3374
|
-
runId: this.#runId
|
|
3375
|
-
});
|
|
3376
|
-
if (!sourceData) {
|
|
3377
|
-
return false;
|
|
3378
|
-
}
|
|
3379
|
-
let value = get(sourceData, path);
|
|
3380
|
-
if (stepId !== "trigger" && path === "status" && !value) {
|
|
3381
|
-
value = "success";
|
|
3382
|
-
}
|
|
3383
|
-
if (typeof queryValue === "object" && queryValue !== null) {
|
|
3384
|
-
baseResult = sift(queryValue)(value);
|
|
3385
|
-
} else {
|
|
3386
|
-
baseResult = value === queryValue;
|
|
3387
|
-
}
|
|
3388
|
-
}
|
|
3389
|
-
if ("ref" in condition) {
|
|
3390
|
-
const {
|
|
3391
|
-
ref,
|
|
3392
|
-
query
|
|
3393
|
-
} = condition;
|
|
3394
|
-
const sourceData = ref.step === "trigger" ? context.triggerData : getStepResult(context.steps[ref.step.id]);
|
|
3395
|
-
this.logger.debug(`Got condition data from ${ref.step === "trigger" ? "trigger" : ref.step.id}`, {
|
|
3396
|
-
sourceData,
|
|
3397
|
-
runId: this.#runId
|
|
3398
|
-
});
|
|
3399
|
-
if (!sourceData) {
|
|
3400
|
-
return false;
|
|
3401
|
-
}
|
|
3402
|
-
let value = get(sourceData, ref.path);
|
|
3403
|
-
if (ref.step !== "trigger" && ref.path === "status" && !value) {
|
|
3404
|
-
value = "success";
|
|
3405
|
-
}
|
|
3406
|
-
baseResult = sift(query)(value);
|
|
3407
|
-
}
|
|
3408
|
-
if ("and" in condition) {
|
|
3409
|
-
andBranchResult = condition.and.every(cond => this.#evaluateCondition(cond, context));
|
|
3410
|
-
this.logger.debug(`Evaluated AND condition`, {
|
|
3411
|
-
andBranchResult,
|
|
3412
|
-
runId: this.#runId
|
|
3413
|
-
});
|
|
3414
|
-
}
|
|
3415
|
-
if ("or" in condition) {
|
|
3416
|
-
orBranchResult = condition.or.some(cond => this.#evaluateCondition(cond, context));
|
|
3417
|
-
this.logger.debug(`Evaluated OR condition`, {
|
|
3418
|
-
orBranchResult,
|
|
3419
|
-
runId: this.#runId
|
|
3420
|
-
});
|
|
3421
|
-
}
|
|
3422
|
-
if ("not" in condition) {
|
|
3423
|
-
baseResult = !this.#evaluateCondition(condition.not, context);
|
|
3424
|
-
this.logger.debug(`Evaluated NOT condition`, {
|
|
3425
|
-
baseResult,
|
|
3426
|
-
runId: this.#runId
|
|
3427
|
-
});
|
|
3428
|
-
}
|
|
3429
|
-
const finalResult = baseResult && andBranchResult && orBranchResult;
|
|
3430
|
-
this.logger.debug(`Evaluated condition`, {
|
|
3431
|
-
finalResult,
|
|
3432
|
-
runId: this.#runId
|
|
3433
|
-
});
|
|
3434
|
-
return finalResult;
|
|
3435
|
-
}
|
|
3436
|
-
getSnapshot() {
|
|
3437
|
-
const snapshot = this.#actor?.getSnapshot();
|
|
3438
|
-
return snapshot;
|
|
3439
|
-
}
|
|
3440
|
-
};
|
|
3441
|
-
|
|
3442
|
-
// src/workflows/legacy/workflow-instance.ts
|
|
3443
|
-
var WorkflowInstance = class {
|
|
3444
|
-
name;
|
|
3445
|
-
#mastra;
|
|
3446
|
-
#machines = {};
|
|
3447
|
-
logger;
|
|
3448
|
-
#steps = {};
|
|
3449
|
-
#stepGraph;
|
|
3450
|
-
#stepSubscriberGraph = {};
|
|
3451
|
-
#retryConfig;
|
|
3452
|
-
events;
|
|
3453
|
-
#runId;
|
|
3454
|
-
#state = null;
|
|
3455
|
-
#executionSpan;
|
|
3456
|
-
#onStepTransition = /* @__PURE__ */new Set();
|
|
3457
|
-
#onFinish;
|
|
3458
|
-
#resultMapping;
|
|
3459
|
-
// indexed by stepId
|
|
3460
|
-
#suspendedMachines = {};
|
|
3461
|
-
// {step1&&step2: {step1: true, step2: true}}
|
|
3462
|
-
#compoundDependencies = {};
|
|
3463
|
-
constructor({
|
|
3464
|
-
name,
|
|
3465
|
-
logger,
|
|
3466
|
-
steps,
|
|
3467
|
-
runId,
|
|
3468
|
-
retryConfig,
|
|
3469
|
-
mastra,
|
|
3470
|
-
stepGraph,
|
|
3471
|
-
stepSubscriberGraph,
|
|
3472
|
-
onFinish,
|
|
3473
|
-
onStepTransition,
|
|
3474
|
-
resultMapping,
|
|
3475
|
-
events
|
|
3476
|
-
}) {
|
|
3477
|
-
this.name = name;
|
|
3478
|
-
this.logger = logger;
|
|
3479
|
-
this.#steps = steps;
|
|
3480
|
-
this.#stepGraph = stepGraph;
|
|
3481
|
-
this.#stepSubscriberGraph = stepSubscriberGraph;
|
|
3482
|
-
this.#retryConfig = retryConfig;
|
|
3483
|
-
this.#mastra = mastra;
|
|
3484
|
-
this.#runId = runId ?? crypto.randomUUID();
|
|
3485
|
-
this.#onFinish = onFinish;
|
|
3486
|
-
this.#resultMapping = resultMapping;
|
|
3487
|
-
this.events = events;
|
|
3488
|
-
onStepTransition?.forEach(handler => this.#onStepTransition.add(handler));
|
|
3489
|
-
this.#initializeCompoundDependencies();
|
|
3490
|
-
}
|
|
3491
|
-
setState(state) {
|
|
3492
|
-
this.#state = state;
|
|
3493
|
-
}
|
|
3494
|
-
get runId() {
|
|
3495
|
-
return this.#runId;
|
|
3496
|
-
}
|
|
3497
|
-
get executionSpan() {
|
|
3498
|
-
return this.#executionSpan;
|
|
3499
|
-
}
|
|
3500
|
-
watch(onTransition) {
|
|
3501
|
-
this.#onStepTransition.add(onTransition);
|
|
3502
|
-
return () => {
|
|
3503
|
-
this.#onStepTransition.delete(onTransition);
|
|
3504
|
-
};
|
|
3505
|
-
}
|
|
3506
|
-
async start({
|
|
3507
|
-
triggerData,
|
|
3508
|
-
runtimeContext
|
|
3509
|
-
} = {}) {
|
|
3510
|
-
const results = await this.execute({
|
|
3511
|
-
triggerData,
|
|
3512
|
-
runtimeContext: runtimeContext ?? new RuntimeContext()
|
|
3513
|
-
});
|
|
3514
|
-
if (this.#onFinish) {
|
|
3515
|
-
const activePathsObj = Object.fromEntries(results.activePaths);
|
|
3516
|
-
const hasSuspendedActivePaths = Object.values(activePathsObj).some(value => value.status === "suspended");
|
|
3517
|
-
if (!hasSuspendedActivePaths) {
|
|
3518
|
-
this.#onFinish();
|
|
3519
|
-
}
|
|
3520
|
-
}
|
|
3521
|
-
return {
|
|
3522
|
-
...results,
|
|
3523
|
-
runId: this.runId
|
|
3524
|
-
};
|
|
3525
|
-
}
|
|
3526
|
-
isCompoundDependencyMet(stepKey) {
|
|
3527
|
-
if (!this.#isCompoundKey(stepKey)) return true;
|
|
3528
|
-
const dependencies = this.#compoundDependencies[stepKey];
|
|
3529
|
-
return dependencies ? Object.values(dependencies).every(status => status === true) : true;
|
|
3530
|
-
}
|
|
3531
|
-
async execute({
|
|
3532
|
-
triggerData,
|
|
3533
|
-
snapshot,
|
|
3534
|
-
stepId,
|
|
3535
|
-
resumeData,
|
|
3536
|
-
runtimeContext
|
|
3537
|
-
} = {
|
|
3538
|
-
runtimeContext: new RuntimeContext()
|
|
3539
|
-
}) {
|
|
3540
|
-
this.#executionSpan = this.#mastra?.getTelemetry()?.tracer.startSpan(`workflow.${this.name}.execute`, {
|
|
3541
|
-
attributes: {
|
|
3542
|
-
componentName: this.name,
|
|
3543
|
-
runId: this.runId
|
|
3544
|
-
}
|
|
3545
|
-
});
|
|
3546
|
-
let machineInput = {
|
|
3547
|
-
// Maintain the original step results and their output
|
|
3548
|
-
steps: {},
|
|
3549
|
-
triggerData: triggerData || {},
|
|
3550
|
-
attempts: Object.keys(this.#steps).reduce((acc, stepKey) => {
|
|
3551
|
-
acc[stepKey] = this.#steps[stepKey]?.step?.retryConfig?.attempts || this.#retryConfig?.attempts || 0;
|
|
3552
|
-
return acc;
|
|
3553
|
-
}, {})
|
|
3554
|
-
};
|
|
3555
|
-
let stepGraph = this.#stepGraph;
|
|
3556
|
-
let startStepId = "trigger";
|
|
3557
|
-
if (snapshot) {
|
|
3558
|
-
const runState = snapshot;
|
|
3559
|
-
if (stepId && runState?.suspendedSteps?.[stepId]) {
|
|
3560
|
-
startStepId = runState.suspendedSteps[stepId];
|
|
3561
|
-
stepGraph = this.#stepSubscriberGraph[startStepId] ?? this.#stepGraph;
|
|
3562
|
-
machineInput = runState.context;
|
|
3563
|
-
}
|
|
3564
|
-
}
|
|
3565
|
-
const defaultMachine = new Machine({
|
|
3566
|
-
logger: this.logger,
|
|
3567
|
-
mastra: this.#mastra,
|
|
3568
|
-
runtimeContext,
|
|
3569
|
-
workflowInstance: this,
|
|
3570
|
-
name: this.name,
|
|
3571
|
-
runId: this.runId,
|
|
3572
|
-
steps: this.#steps,
|
|
3573
|
-
stepGraph,
|
|
3574
|
-
executionSpan: this.#executionSpan,
|
|
3575
|
-
startStepId,
|
|
3576
|
-
retryConfig: this.#retryConfig
|
|
3577
|
-
});
|
|
3578
|
-
this.#machines[startStepId] = defaultMachine;
|
|
3579
|
-
const stateUpdateHandler = (startStepId2, state, ctx) => {
|
|
3580
|
-
let fullState = {
|
|
3581
|
-
value: {},
|
|
3582
|
-
context: {}
|
|
3583
|
-
};
|
|
3584
|
-
if (ctx) {
|
|
3585
|
-
fullState["value"] = state;
|
|
3586
|
-
fullState["context"] = ctx;
|
|
3587
|
-
} else {
|
|
3588
|
-
fullState = state;
|
|
3589
|
-
}
|
|
3590
|
-
if (startStepId2 === "trigger") {
|
|
3591
|
-
this.#state = fullState.value;
|
|
3592
|
-
} else {
|
|
3593
|
-
this.#state = mergeChildValue(startStepId2, this.#state, fullState.value);
|
|
3594
|
-
}
|
|
3595
|
-
const now = Date.now();
|
|
3596
|
-
if (this.#onStepTransition) {
|
|
3597
|
-
this.#onStepTransition.forEach(onTransition => {
|
|
3598
|
-
void onTransition({
|
|
3599
|
-
runId: this.#runId,
|
|
3600
|
-
results: fullState.context.steps,
|
|
3601
|
-
activePaths: getResultActivePaths(fullState),
|
|
3602
|
-
timestamp: now
|
|
3603
|
-
});
|
|
3604
|
-
});
|
|
3605
|
-
}
|
|
3606
|
-
};
|
|
3607
|
-
defaultMachine.on("state-update", stateUpdateHandler);
|
|
3608
|
-
const {
|
|
3609
|
-
results,
|
|
3610
|
-
activePaths
|
|
3611
|
-
} = await defaultMachine.execute({
|
|
3612
|
-
snapshot,
|
|
3613
|
-
stepId,
|
|
3614
|
-
input: machineInput,
|
|
3615
|
-
resumeData
|
|
3616
|
-
});
|
|
3617
|
-
await this.persistWorkflowSnapshot();
|
|
3618
|
-
const result = {
|
|
3619
|
-
results,
|
|
3620
|
-
activePaths,
|
|
3621
|
-
timestamp: Date.now()
|
|
3622
|
-
};
|
|
3623
|
-
if (this.#resultMapping) {
|
|
3624
|
-
result.result = resolveVariables({
|
|
3625
|
-
runId: this.#runId,
|
|
3626
|
-
logger: this.logger,
|
|
3627
|
-
variables: this.#resultMapping,
|
|
3628
|
-
context: {
|
|
3629
|
-
steps: results,
|
|
3630
|
-
triggerData}
|
|
3631
|
-
});
|
|
3632
|
-
}
|
|
3633
|
-
return result;
|
|
3634
|
-
}
|
|
3635
|
-
hasSubscribers(stepId) {
|
|
3636
|
-
return Object.keys(this.#stepSubscriberGraph).some(key => key.split("&&").includes(stepId));
|
|
3637
|
-
}
|
|
3638
|
-
async runMachine(parentStepId, input, runtimeContext = new RuntimeContext()) {
|
|
3639
|
-
const stepStatus = input.steps[parentStepId]?.status;
|
|
3640
|
-
const subscriberKeys = Object.keys(this.#stepSubscriberGraph).filter(key => key.split("&&").includes(parentStepId));
|
|
3641
|
-
subscriberKeys.forEach(key => {
|
|
3642
|
-
if (["success", "failure", "skipped"].includes(stepStatus) && this.#isCompoundKey(key)) {
|
|
3643
|
-
this.#compoundDependencies[key][parentStepId] = true;
|
|
3644
|
-
}
|
|
3645
|
-
});
|
|
3646
|
-
const stateUpdateHandler = (startStepId, state, ctx) => {
|
|
3647
|
-
let fullState = {
|
|
3648
|
-
value: {},
|
|
3649
|
-
context: {}
|
|
3650
|
-
};
|
|
3651
|
-
if (ctx) {
|
|
3652
|
-
fullState["value"] = state;
|
|
3653
|
-
fullState["context"] = ctx;
|
|
3654
|
-
} else {
|
|
3655
|
-
fullState = state;
|
|
3656
|
-
}
|
|
3657
|
-
if (startStepId === "trigger") {
|
|
3658
|
-
this.#state = fullState.value;
|
|
3659
|
-
} else {
|
|
3660
|
-
this.#state = mergeChildValue(startStepId, this.#state, fullState.value);
|
|
3661
|
-
}
|
|
3662
|
-
const now = Date.now();
|
|
3663
|
-
if (this.#onStepTransition) {
|
|
3664
|
-
this.#onStepTransition.forEach(onTransition => {
|
|
3665
|
-
void onTransition({
|
|
3666
|
-
runId: this.#runId,
|
|
3667
|
-
results: fullState.context.steps,
|
|
3668
|
-
activePaths: getResultActivePaths(fullState),
|
|
3669
|
-
timestamp: now
|
|
3670
|
-
});
|
|
3671
|
-
});
|
|
3672
|
-
}
|
|
3673
|
-
};
|
|
3674
|
-
const results = await Promise.all(subscriberKeys.map(async key => {
|
|
3675
|
-
if (!this.#stepSubscriberGraph[key] || !this.isCompoundDependencyMet(key)) {
|
|
3676
|
-
return;
|
|
3677
|
-
}
|
|
3678
|
-
this.#resetCompoundDependency(key);
|
|
3679
|
-
const machine = new Machine({
|
|
3680
|
-
logger: this.logger,
|
|
3681
|
-
mastra: this.#mastra,
|
|
3682
|
-
runtimeContext,
|
|
3683
|
-
workflowInstance: this,
|
|
3684
|
-
name: parentStepId === "trigger" ? this.name : `${this.name}-${parentStepId}`,
|
|
3685
|
-
runId: this.runId,
|
|
3686
|
-
steps: this.#steps,
|
|
3687
|
-
stepGraph: this.#stepSubscriberGraph[key],
|
|
3688
|
-
executionSpan: this.#executionSpan,
|
|
3689
|
-
startStepId: parentStepId
|
|
3690
|
-
});
|
|
3691
|
-
machine.on("state-update", stateUpdateHandler);
|
|
3692
|
-
this.#machines[parentStepId] = machine;
|
|
3693
|
-
return machine.execute({
|
|
3694
|
-
input
|
|
3695
|
-
});
|
|
3696
|
-
}));
|
|
3697
|
-
return results;
|
|
3698
|
-
}
|
|
3699
|
-
async suspend(stepId, machine) {
|
|
3700
|
-
this.#suspendedMachines[stepId] = machine;
|
|
3701
|
-
}
|
|
3702
|
-
/**
|
|
3703
|
-
* Persists the workflow state to the database
|
|
3704
|
-
*/
|
|
3705
|
-
async persistWorkflowSnapshot() {
|
|
3706
|
-
const storage = this.#mastra?.getStorage();
|
|
3707
|
-
if (!storage) {
|
|
3708
|
-
this.logger.debug("Snapshot cannot be persisted. Mastra engine is not initialized", {
|
|
3709
|
-
runId: this.#runId
|
|
3710
|
-
});
|
|
3711
|
-
return;
|
|
3712
|
-
}
|
|
3713
|
-
const existingSnapshot = await storage.loadWorkflowSnapshot({
|
|
3714
|
-
workflowName: this.name,
|
|
3715
|
-
runId: this.#runId
|
|
3716
|
-
});
|
|
3717
|
-
const machineSnapshots = {};
|
|
3718
|
-
for (const [stepId, machine] of Object.entries(this.#machines)) {
|
|
3719
|
-
const machineSnapshot = machine?.getSnapshot();
|
|
3720
|
-
if (machineSnapshot) {
|
|
3721
|
-
machineSnapshots[stepId] = {
|
|
3722
|
-
...machineSnapshot
|
|
3723
|
-
};
|
|
3724
|
-
}
|
|
3725
|
-
}
|
|
3726
|
-
let snapshot = machineSnapshots["trigger"];
|
|
3727
|
-
delete machineSnapshots["trigger"];
|
|
3728
|
-
const suspendedSteps = Object.entries(this.#suspendedMachines).reduce((acc, [stepId, machine]) => {
|
|
3729
|
-
acc[stepId] = machine.startStepId;
|
|
3730
|
-
return acc;
|
|
3731
|
-
}, {});
|
|
3732
|
-
if (!snapshot && existingSnapshot) {
|
|
3733
|
-
existingSnapshot.childStates = {
|
|
3734
|
-
...existingSnapshot.childStates,
|
|
3735
|
-
...machineSnapshots
|
|
3736
|
-
};
|
|
3737
|
-
existingSnapshot.suspendedSteps = {
|
|
3738
|
-
...existingSnapshot.suspendedSteps,
|
|
3739
|
-
...suspendedSteps
|
|
3740
|
-
};
|
|
3741
|
-
await storage.persistWorkflowSnapshot({
|
|
3742
|
-
workflowName: this.name,
|
|
3743
|
-
runId: this.#runId,
|
|
3744
|
-
snapshot: existingSnapshot
|
|
3745
|
-
});
|
|
3746
|
-
return;
|
|
3747
|
-
} else if (snapshot && !existingSnapshot) {
|
|
3748
|
-
snapshot.suspendedSteps = suspendedSteps;
|
|
3749
|
-
snapshot.childStates = {
|
|
3750
|
-
...machineSnapshots
|
|
3751
|
-
};
|
|
3752
|
-
await storage.persistWorkflowSnapshot({
|
|
3753
|
-
workflowName: this.name,
|
|
3754
|
-
runId: this.#runId,
|
|
3755
|
-
snapshot
|
|
3756
|
-
});
|
|
3757
|
-
return;
|
|
3758
|
-
} else if (!snapshot) {
|
|
3759
|
-
this.logger.debug("Snapshot cannot be persisted. No snapshot received.", {
|
|
3760
|
-
runId: this.#runId
|
|
3761
|
-
});
|
|
3762
|
-
return;
|
|
3763
|
-
}
|
|
3764
|
-
snapshot.suspendedSteps = {
|
|
3765
|
-
...existingSnapshot.suspendedSteps,
|
|
3766
|
-
...suspendedSteps
|
|
3767
|
-
};
|
|
3768
|
-
if (!existingSnapshot || snapshot === existingSnapshot) {
|
|
3769
|
-
await storage.persistWorkflowSnapshot({
|
|
3770
|
-
workflowName: this.name,
|
|
3771
|
-
runId: this.#runId,
|
|
3772
|
-
snapshot
|
|
3773
|
-
});
|
|
3774
|
-
return;
|
|
3775
|
-
}
|
|
3776
|
-
if (existingSnapshot?.childStates) {
|
|
3777
|
-
snapshot.childStates = {
|
|
3778
|
-
...existingSnapshot.childStates,
|
|
3779
|
-
...machineSnapshots
|
|
3780
|
-
};
|
|
3781
|
-
} else {
|
|
3782
|
-
snapshot.childStates = machineSnapshots;
|
|
3783
|
-
}
|
|
3784
|
-
await storage.persistWorkflowSnapshot({
|
|
3785
|
-
workflowName: this.name,
|
|
3786
|
-
runId: this.#runId,
|
|
3787
|
-
snapshot
|
|
3788
|
-
});
|
|
3789
|
-
}
|
|
3790
|
-
async getState() {
|
|
3791
|
-
const storedSnapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
3792
|
-
workflowName: this.name,
|
|
3793
|
-
runId: this.runId
|
|
3794
|
-
});
|
|
3795
|
-
const prevSnapshot = storedSnapshot ? {
|
|
3796
|
-
trigger: storedSnapshot,
|
|
3797
|
-
...Object.entries(storedSnapshot?.childStates ?? {}).reduce((acc, [stepId, snapshot2]) => ({
|
|
3798
|
-
...acc,
|
|
3799
|
-
[stepId]: snapshot2
|
|
3800
|
-
}), {})
|
|
3801
|
-
} : {};
|
|
3802
|
-
const currentSnapshot = Object.entries(this.#machines).reduce((acc, [stepId, machine]) => {
|
|
3803
|
-
const snapshot2 = machine.getSnapshot();
|
|
3804
|
-
if (!snapshot2) {
|
|
3805
|
-
return acc;
|
|
3806
|
-
}
|
|
3807
|
-
return {
|
|
3808
|
-
...acc,
|
|
3809
|
-
[stepId]: snapshot2
|
|
3810
|
-
};
|
|
3811
|
-
}, {});
|
|
3812
|
-
Object.assign(prevSnapshot, currentSnapshot);
|
|
3813
|
-
const trigger = prevSnapshot.trigger;
|
|
3814
|
-
delete prevSnapshot.trigger;
|
|
3815
|
-
const snapshot = {
|
|
3816
|
-
...trigger};
|
|
3817
|
-
const m = getActivePathsAndStatus(prevSnapshot.value);
|
|
3818
|
-
return {
|
|
3819
|
-
runId: this.runId,
|
|
3820
|
-
value: snapshot.value,
|
|
3821
|
-
context: snapshot.context,
|
|
3822
|
-
activePaths: m,
|
|
3823
|
-
timestamp: Date.now()
|
|
3824
|
-
};
|
|
3825
|
-
}
|
|
3826
|
-
async resumeWithEvent(eventName, data, runtimeContext = new RuntimeContext()) {
|
|
3827
|
-
const event = this.events?.[eventName];
|
|
3828
|
-
if (!event) {
|
|
3829
|
-
throw new Error(`Event ${eventName} not found`);
|
|
3830
|
-
}
|
|
3831
|
-
const results = await this.resume({
|
|
3832
|
-
stepId: `__${eventName}_event`,
|
|
3833
|
-
context: {
|
|
3834
|
-
resumedEvent: data
|
|
3835
|
-
},
|
|
3836
|
-
runtimeContext
|
|
3837
|
-
});
|
|
3838
|
-
return results;
|
|
3839
|
-
}
|
|
3840
|
-
async resume({
|
|
3841
|
-
stepId,
|
|
3842
|
-
context: resumeContext,
|
|
3843
|
-
runtimeContext = new RuntimeContext()
|
|
3844
|
-
}) {
|
|
3845
|
-
await new Promise(resolve => setTimeout(resolve, 0));
|
|
3846
|
-
return this._resume({
|
|
3847
|
-
stepId,
|
|
3848
|
-
context: resumeContext,
|
|
3849
|
-
runtimeContext
|
|
3850
|
-
});
|
|
3851
|
-
}
|
|
3852
|
-
async #loadWorkflowSnapshot(runId) {
|
|
3853
|
-
const storage = this.#mastra?.getStorage();
|
|
3854
|
-
if (!storage) {
|
|
3855
|
-
this.logger.debug("Snapshot cannot be loaded. Mastra engine is not initialized", {
|
|
3856
|
-
runId
|
|
3857
|
-
});
|
|
3858
|
-
return;
|
|
3859
|
-
}
|
|
3860
|
-
await this.persistWorkflowSnapshot();
|
|
3861
|
-
return storage.loadWorkflowSnapshot({
|
|
3862
|
-
runId,
|
|
3863
|
-
workflowName: this.name
|
|
3864
|
-
});
|
|
3865
|
-
}
|
|
3866
|
-
async _resume({
|
|
3867
|
-
stepId,
|
|
3868
|
-
context: resumeContext,
|
|
3869
|
-
runtimeContext
|
|
3870
|
-
}) {
|
|
3871
|
-
const snapshot = await this.#loadWorkflowSnapshot(this.runId);
|
|
3872
|
-
if (!snapshot) {
|
|
3873
|
-
throw new Error(`No snapshot found for workflow run ${this.runId}`);
|
|
3874
|
-
}
|
|
3875
|
-
const stepParts = stepId.split(".");
|
|
3876
|
-
const stepPath = stepParts.join(".");
|
|
3877
|
-
if (stepParts.length > 1) {
|
|
3878
|
-
stepId = stepParts[0] ?? stepId;
|
|
3879
|
-
}
|
|
3880
|
-
let parsedSnapshot;
|
|
3881
|
-
try {
|
|
3882
|
-
parsedSnapshot = typeof snapshot === "string" ? JSON.parse(snapshot) : snapshot;
|
|
3883
|
-
} catch (error) {
|
|
3884
|
-
this.logger.debug("Failed to parse workflow snapshot for resume", {
|
|
3885
|
-
error,
|
|
3886
|
-
runId: this.runId
|
|
3887
|
-
});
|
|
3888
|
-
throw new Error("Failed to parse workflow snapshot");
|
|
3889
|
-
}
|
|
3890
|
-
const startStepId = parsedSnapshot.suspendedSteps?.[stepId];
|
|
3891
|
-
if (!startStepId) {
|
|
3892
|
-
return;
|
|
3893
|
-
}
|
|
3894
|
-
parsedSnapshot = startStepId === "trigger" ? parsedSnapshot : {
|
|
3895
|
-
...parsedSnapshot?.childStates?.[startStepId],
|
|
3896
|
-
...{
|
|
3897
|
-
suspendedSteps: parsedSnapshot.suspendedSteps
|
|
3898
|
-
}
|
|
3899
|
-
};
|
|
3900
|
-
if (!parsedSnapshot) {
|
|
3901
|
-
throw new Error(`No snapshot found for step: ${stepId} starting at ${startStepId}`);
|
|
3902
|
-
}
|
|
3903
|
-
if (resumeContext) {
|
|
3904
|
-
parsedSnapshot.context.steps[stepId] = {
|
|
3905
|
-
status: "success",
|
|
3906
|
-
output: {
|
|
3907
|
-
...(parsedSnapshot?.context?.steps?.[stepId]?.output || {}),
|
|
3908
|
-
...resumeContext
|
|
3909
|
-
}
|
|
3910
|
-
};
|
|
3911
|
-
}
|
|
3912
|
-
if (parsedSnapshot.children) {
|
|
3913
|
-
Object.entries(parsedSnapshot.children).forEach(([, child]) => {
|
|
3914
|
-
if (child.snapshot?.input?.stepNode) {
|
|
3915
|
-
const stepDef = this.#makeStepDef(child.snapshot.input.stepNode.step.id);
|
|
3916
|
-
child.snapshot.input.stepNode.config = {
|
|
3917
|
-
...child.snapshot.input.stepNode.config,
|
|
3918
|
-
...stepDef
|
|
3919
|
-
};
|
|
3920
|
-
child.snapshot.input.context = parsedSnapshot.context;
|
|
3921
|
-
}
|
|
3922
|
-
});
|
|
3923
|
-
}
|
|
3924
|
-
parsedSnapshot.value = updateStepInHierarchy(parsedSnapshot.value, stepId);
|
|
3925
|
-
if (parsedSnapshot.context?.attempts) {
|
|
3926
|
-
parsedSnapshot.context.attempts[stepId] = this.#steps[stepId]?.step?.retryConfig?.attempts || this.#retryConfig?.attempts || 0;
|
|
3927
|
-
}
|
|
3928
|
-
this.logger.debug("Resuming workflow with updated snapshot", {
|
|
3929
|
-
updatedSnapshot: parsedSnapshot,
|
|
3930
|
-
runId: this.runId,
|
|
3931
|
-
stepId
|
|
3932
|
-
});
|
|
3933
|
-
return this.execute({
|
|
3934
|
-
snapshot: parsedSnapshot,
|
|
3935
|
-
stepId: stepPath,
|
|
3936
|
-
resumeData: resumeContext,
|
|
3937
|
-
runtimeContext
|
|
3938
|
-
});
|
|
3939
|
-
}
|
|
3940
|
-
#initializeCompoundDependencies() {
|
|
3941
|
-
Object.keys(this.#stepSubscriberGraph).forEach(stepKey => {
|
|
3942
|
-
if (this.#isCompoundKey(stepKey)) {
|
|
3943
|
-
const requiredSteps = stepKey.split("&&");
|
|
3944
|
-
this.#compoundDependencies[stepKey] = requiredSteps.reduce((acc, step) => {
|
|
3945
|
-
acc[step] = false;
|
|
3946
|
-
return acc;
|
|
3947
|
-
}, {});
|
|
3948
|
-
}
|
|
3949
|
-
});
|
|
3950
|
-
}
|
|
3951
|
-
#resetCompoundDependency(key) {
|
|
3952
|
-
if (this.#isCompoundKey(key)) {
|
|
3953
|
-
const requiredSteps = key.split("&&");
|
|
3954
|
-
this.#compoundDependencies[key] = requiredSteps.reduce((acc, step) => {
|
|
3955
|
-
acc[step] = false;
|
|
3956
|
-
return acc;
|
|
3957
|
-
}, {});
|
|
3958
|
-
}
|
|
3959
|
-
}
|
|
3960
|
-
#makeStepDef(stepId) {
|
|
3961
|
-
const executeStep = (handler2, spanName, attributes) => {
|
|
3962
|
-
return async data => {
|
|
3963
|
-
return await context.with(trace.setSpan(context.active(), this.#executionSpan), async () => {
|
|
3964
|
-
if (this.#mastra?.getTelemetry()) {
|
|
3965
|
-
return this.#mastra.getTelemetry()?.traceMethod(handler2, {
|
|
3966
|
-
spanName,
|
|
3967
|
-
attributes
|
|
3968
|
-
})(data);
|
|
3969
|
-
} else {
|
|
3970
|
-
return handler2(data);
|
|
3971
|
-
}
|
|
3972
|
-
});
|
|
3973
|
-
};
|
|
3974
|
-
};
|
|
3975
|
-
const handler = async ({
|
|
3976
|
-
context,
|
|
3977
|
-
...rest
|
|
3978
|
-
}) => {
|
|
3979
|
-
const targetStep = this.#steps[stepId];
|
|
3980
|
-
if (!targetStep) throw new Error(`Step not found`);
|
|
3981
|
-
const {
|
|
3982
|
-
payload = {},
|
|
3983
|
-
execute = async () => {}
|
|
3984
|
-
} = targetStep.step;
|
|
3985
|
-
const mergedData = {
|
|
3986
|
-
...payload,
|
|
3987
|
-
...context
|
|
3988
|
-
};
|
|
3989
|
-
const finalAction = this.#mastra?.getTelemetry() ? executeStep(execute, `workflow.${this.name}.action.${stepId}`, {
|
|
3990
|
-
componentName: this.name,
|
|
3991
|
-
runId: rest.runId
|
|
3992
|
-
}) : execute;
|
|
3993
|
-
return finalAction ? await finalAction({
|
|
3994
|
-
context: mergedData,
|
|
3995
|
-
...rest
|
|
3996
|
-
}) : {};
|
|
3997
|
-
};
|
|
3998
|
-
const finalHandler = ({
|
|
3999
|
-
context,
|
|
4000
|
-
...rest
|
|
4001
|
-
}) => {
|
|
4002
|
-
if (this.#executionSpan) {
|
|
4003
|
-
return executeStep(handler, `workflow.${this.name}.step.${stepId}`, {
|
|
4004
|
-
componentName: this.name,
|
|
4005
|
-
runId: rest?.runId
|
|
4006
|
-
})({
|
|
4007
|
-
context,
|
|
4008
|
-
...rest
|
|
4009
|
-
});
|
|
4010
|
-
}
|
|
4011
|
-
return handler({
|
|
4012
|
-
context,
|
|
4013
|
-
...rest
|
|
4014
|
-
});
|
|
4015
|
-
};
|
|
4016
|
-
return {
|
|
4017
|
-
handler: finalHandler,
|
|
4018
|
-
data: {}
|
|
4019
|
-
};
|
|
4020
|
-
}
|
|
4021
|
-
#isCompoundKey(key) {
|
|
4022
|
-
return key.includes("&&");
|
|
4023
|
-
}
|
|
4024
|
-
};
|
|
4025
|
-
|
|
4026
|
-
// src/workflows/legacy/workflow.ts
|
|
4027
|
-
var LegacyWorkflow = class extends MastraBase {
|
|
4028
|
-
name;
|
|
4029
|
-
triggerSchema;
|
|
4030
|
-
resultSchema;
|
|
4031
|
-
resultMapping;
|
|
4032
|
-
events;
|
|
4033
|
-
#retryConfig;
|
|
4034
|
-
#mastra;
|
|
4035
|
-
#runs = /* @__PURE__ */new Map();
|
|
4036
|
-
isNested = false;
|
|
4037
|
-
#onStepTransition = /* @__PURE__ */new Set();
|
|
4038
|
-
// registers stepIds on `after` calls
|
|
4039
|
-
#afterStepStack = [];
|
|
4040
|
-
#lastStepStack = [];
|
|
4041
|
-
#lastBuilderType = null;
|
|
4042
|
-
#ifStack = [];
|
|
4043
|
-
#stepGraph = {
|
|
4044
|
-
initial: []
|
|
4045
|
-
};
|
|
4046
|
-
#serializedStepGraph = {
|
|
4047
|
-
initial: []
|
|
4048
|
-
};
|
|
4049
|
-
#stepSubscriberGraph = {};
|
|
4050
|
-
#serializedStepSubscriberGraph = {};
|
|
4051
|
-
#steps = {};
|
|
4052
|
-
#ifCount = 0;
|
|
4053
|
-
/**
|
|
4054
|
-
* Creates a new LegacyWorkflow instance
|
|
4055
|
-
* @param name - Identifier for the workflow (not necessarily unique)
|
|
4056
|
-
* @param logger - Optional logger instance
|
|
4057
|
-
*/
|
|
4058
|
-
constructor({
|
|
4059
|
-
name,
|
|
4060
|
-
triggerSchema,
|
|
4061
|
-
result,
|
|
4062
|
-
retryConfig,
|
|
4063
|
-
mastra,
|
|
4064
|
-
events
|
|
4065
|
-
}) {
|
|
4066
|
-
super({
|
|
4067
|
-
component: "WORKFLOW",
|
|
4068
|
-
name
|
|
4069
|
-
});
|
|
4070
|
-
this.name = name;
|
|
4071
|
-
this.#retryConfig = retryConfig;
|
|
4072
|
-
this.triggerSchema = triggerSchema;
|
|
4073
|
-
this.resultSchema = result?.schema;
|
|
4074
|
-
this.resultMapping = result?.mapping;
|
|
4075
|
-
this.events = events;
|
|
4076
|
-
if (mastra) {
|
|
4077
|
-
this.__registerPrimitives({
|
|
4078
|
-
telemetry: mastra.getTelemetry(),
|
|
4079
|
-
logger: mastra.getLogger()
|
|
4080
|
-
});
|
|
4081
|
-
this.#mastra = mastra;
|
|
4082
|
-
}
|
|
4083
|
-
}
|
|
4084
|
-
step(next, config) {
|
|
4085
|
-
const that = this;
|
|
4086
|
-
if (Array.isArray(next)) {
|
|
4087
|
-
const nextSteps = next.map(step2 => {
|
|
4088
|
-
if (isWorkflow(step2)) {
|
|
4089
|
-
const asStep = step2.toStep();
|
|
4090
|
-
return asStep;
|
|
4091
|
-
} else if (isAgent(step2)) {
|
|
4092
|
-
return agentToStep(step2);
|
|
4093
|
-
} else {
|
|
4094
|
-
return step2;
|
|
4095
|
-
}
|
|
4096
|
-
});
|
|
4097
|
-
nextSteps.forEach(step2 => this.step(step2, config));
|
|
4098
|
-
this.after(nextSteps);
|
|
4099
|
-
this.step(new LegacyStep({
|
|
4100
|
-
id: `__after_${next.map(step2 => config?.id ?? step2?.id ?? step2?.name).join("_")}`,
|
|
4101
|
-
execute: async () => {
|
|
4102
|
-
return {
|
|
4103
|
-
success: true
|
|
4104
|
-
};
|
|
4105
|
-
}
|
|
4106
|
-
}));
|
|
4107
|
-
return this;
|
|
4108
|
-
}
|
|
4109
|
-
const {
|
|
4110
|
-
variables = {}
|
|
4111
|
-
} = config || {};
|
|
4112
|
-
const requiredData = {};
|
|
4113
|
-
for (const [key, variable] of Object.entries(variables)) {
|
|
4114
|
-
if (variable && isVariableReference(variable)) {
|
|
4115
|
-
requiredData[key] = variable;
|
|
4116
|
-
}
|
|
4117
|
-
}
|
|
4118
|
-
const step = isWorkflow(next) ?
|
|
4119
|
-
// @ts-ignore
|
|
4120
|
-
workflowToStep(next, {
|
|
4121
|
-
mastra: this.#mastra
|
|
4122
|
-
}) : isAgent(next) ?
|
|
4123
|
-
// @ts-ignore
|
|
4124
|
-
agentToStep(next, {
|
|
4125
|
-
mastra: this.#mastra
|
|
4126
|
-
}) : next;
|
|
4127
|
-
const stepKey = this.#makeStepKey(step, config);
|
|
4128
|
-
const when = config?.["#internal"]?.when || config?.when;
|
|
4129
|
-
const graphEntry = {
|
|
4130
|
-
step,
|
|
4131
|
-
config: {
|
|
4132
|
-
...this.#makeStepDef(stepKey),
|
|
4133
|
-
...config,
|
|
4134
|
-
loopLabel: config?.["#internal"]?.loopLabel,
|
|
4135
|
-
loopType: config?.["#internal"]?.loopType,
|
|
4136
|
-
serializedWhen: typeof when === "function" ? when.toString() : when,
|
|
4137
|
-
data: requiredData
|
|
4138
|
-
},
|
|
4139
|
-
get id() {
|
|
4140
|
-
return that.#makeStepKey(this.step, this.config);
|
|
4141
|
-
}
|
|
4142
|
-
};
|
|
4143
|
-
this.#steps[stepKey] = graphEntry;
|
|
4144
|
-
const parentStepKey = this.#getParentStepKey({
|
|
4145
|
-
loop_check: true
|
|
4146
|
-
});
|
|
4147
|
-
const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
|
|
4148
|
-
const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
|
|
4149
|
-
if (parentStepKey && stepGraph) {
|
|
4150
|
-
if (!stepGraph.initial.some(step2 => step2.config.id === stepKey || step2.step.id === stepKey)) {
|
|
4151
|
-
stepGraph.initial.push(graphEntry);
|
|
4152
|
-
if (serializedStepGraph) serializedStepGraph.initial.push(graphEntry);
|
|
4153
|
-
}
|
|
4154
|
-
stepGraph[stepKey] = [];
|
|
4155
|
-
if (serializedStepGraph) serializedStepGraph[stepKey] = [];
|
|
4156
|
-
} else {
|
|
4157
|
-
if (!this.#stepGraph[stepKey]) this.#stepGraph[stepKey] = [];
|
|
4158
|
-
this.#stepGraph.initial.push(graphEntry);
|
|
4159
|
-
this.#serializedStepGraph.initial.push(graphEntry);
|
|
4160
|
-
}
|
|
4161
|
-
this.#lastStepStack.push(stepKey);
|
|
4162
|
-
this.#lastBuilderType = "step";
|
|
4163
|
-
return this;
|
|
4164
|
-
}
|
|
4165
|
-
#__internalStep(next, config, internalUse) {
|
|
4166
|
-
const that = this;
|
|
4167
|
-
if (Array.isArray(next)) {
|
|
4168
|
-
const nextSteps = next.map(step2 => {
|
|
4169
|
-
if (isWorkflow(step2)) {
|
|
4170
|
-
const asStep = step2.toStep();
|
|
4171
|
-
return asStep;
|
|
4172
|
-
} else {
|
|
4173
|
-
return step2;
|
|
4174
|
-
}
|
|
4175
|
-
});
|
|
4176
|
-
nextSteps.forEach(step2 => this.#__internalStep(step2, config, internalUse));
|
|
4177
|
-
this.after(nextSteps);
|
|
4178
|
-
this.#__internalStep(new LegacyStep({
|
|
4179
|
-
id: `__after_${next.map(step2 => step2?.id ?? step2?.name).join("_")}`,
|
|
4180
|
-
execute: async () => {
|
|
4181
|
-
return {
|
|
4182
|
-
success: true
|
|
4183
|
-
};
|
|
4184
|
-
}
|
|
4185
|
-
}), void 0, internalUse);
|
|
4186
|
-
return this;
|
|
4187
|
-
}
|
|
4188
|
-
const {
|
|
4189
|
-
variables = {}
|
|
4190
|
-
} = config || {};
|
|
4191
|
-
const requiredData = {};
|
|
4192
|
-
for (const [key, variable] of Object.entries(variables)) {
|
|
4193
|
-
if (variable && isVariableReference(variable)) {
|
|
4194
|
-
requiredData[key] = variable;
|
|
4195
|
-
}
|
|
4196
|
-
}
|
|
4197
|
-
const step = isWorkflow(next) ?
|
|
4198
|
-
// @ts-ignore
|
|
4199
|
-
workflowToStep(next, {
|
|
4200
|
-
mastra: this.#mastra
|
|
4201
|
-
}) : next;
|
|
4202
|
-
const stepKey = this.#makeStepKey(step, config);
|
|
4203
|
-
const when = config?.["#internal"]?.when || config?.when;
|
|
4204
|
-
const graphEntry = {
|
|
4205
|
-
step,
|
|
4206
|
-
config: {
|
|
4207
|
-
...this.#makeStepDef(stepKey),
|
|
4208
|
-
...config,
|
|
4209
|
-
loopLabel: config?.["#internal"]?.loopLabel,
|
|
4210
|
-
loopType: config?.["#internal"]?.loopType,
|
|
4211
|
-
serializedWhen: typeof when === "function" ? when.toString() : when,
|
|
4212
|
-
data: requiredData
|
|
4213
|
-
},
|
|
4214
|
-
get id() {
|
|
4215
|
-
return that.#makeStepKey(this.step, this.config);
|
|
4216
|
-
}
|
|
4217
|
-
};
|
|
4218
|
-
this.#steps[stepKey] = graphEntry;
|
|
4219
|
-
const parentStepKey = this.#getParentStepKey();
|
|
4220
|
-
const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
|
|
4221
|
-
const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
|
|
4222
|
-
if (parentStepKey && stepGraph) {
|
|
4223
|
-
if (!stepGraph.initial.some(step2 => step2.step.id === stepKey)) {
|
|
4224
|
-
stepGraph.initial.push(graphEntry);
|
|
4225
|
-
if (serializedStepGraph) serializedStepGraph.initial.push(graphEntry);
|
|
4226
|
-
}
|
|
4227
|
-
stepGraph[stepKey] = [];
|
|
4228
|
-
if (serializedStepGraph) serializedStepGraph[stepKey] = [];
|
|
4229
|
-
} else {
|
|
4230
|
-
if (!this.#stepGraph[stepKey]) this.#stepGraph[stepKey] = [];
|
|
4231
|
-
this.#stepGraph.initial.push(graphEntry);
|
|
4232
|
-
this.#serializedStepGraph.initial.push(graphEntry);
|
|
4233
|
-
}
|
|
4234
|
-
this.#lastStepStack.push(stepKey);
|
|
4235
|
-
this.#lastBuilderType = "step";
|
|
4236
|
-
return this;
|
|
4237
|
-
}
|
|
4238
|
-
#makeStepKey(step, config) {
|
|
4239
|
-
if (typeof step === "string") return step;
|
|
4240
|
-
return `${config?.id ?? step.id ?? step.name}`;
|
|
4241
|
-
}
|
|
4242
|
-
then(next, config) {
|
|
4243
|
-
const that = this;
|
|
4244
|
-
if (Array.isArray(next)) {
|
|
4245
|
-
const lastStep = this.#steps[this.#lastStepStack[this.#lastStepStack.length - 1] ?? ""];
|
|
4246
|
-
if (!lastStep) {
|
|
4247
|
-
throw new Error("Condition requires a step to be executed after");
|
|
4248
|
-
}
|
|
4249
|
-
this.after(lastStep.step);
|
|
4250
|
-
const nextSteps = next.map(step2 => {
|
|
4251
|
-
if (isWorkflow(step2)) {
|
|
4252
|
-
return workflowToStep(step2, {
|
|
4253
|
-
mastra: this.#mastra
|
|
4254
|
-
});
|
|
4255
|
-
}
|
|
4256
|
-
if (isAgent(step2)) {
|
|
4257
|
-
return agentToStep(step2);
|
|
4258
|
-
}
|
|
4259
|
-
return step2;
|
|
4260
|
-
});
|
|
4261
|
-
nextSteps.forEach(step2 => this.step(step2, config));
|
|
4262
|
-
this.step(new LegacyStep({
|
|
4263
|
-
// @ts-ignore
|
|
4264
|
-
id: `__after_${next.map(step2 => step2?.id ?? step2?.name).join("_")}`,
|
|
4265
|
-
execute: async () => {
|
|
4266
|
-
return {
|
|
4267
|
-
success: true
|
|
4268
|
-
};
|
|
4269
|
-
}
|
|
4270
|
-
}));
|
|
4271
|
-
return this;
|
|
4272
|
-
}
|
|
4273
|
-
const {
|
|
4274
|
-
variables = {}
|
|
4275
|
-
} = config || {};
|
|
4276
|
-
const requiredData = {};
|
|
4277
|
-
for (const [key, variable] of Object.entries(variables)) {
|
|
4278
|
-
if (variable && isVariableReference(variable)) {
|
|
4279
|
-
requiredData[key] = variable;
|
|
4280
|
-
}
|
|
4281
|
-
}
|
|
4282
|
-
const lastStepKey = this.#lastStepStack[this.#lastStepStack.length - 1];
|
|
4283
|
-
const step = isWorkflow(next) ? workflowToStep(next, {
|
|
4284
|
-
mastra: this.#mastra
|
|
4285
|
-
}) : isAgent(next) ? agentToStep(next) : next;
|
|
4286
|
-
const stepKey = this.#makeStepKey(step, config);
|
|
4287
|
-
const when = config?.["#internal"]?.when || config?.when;
|
|
4288
|
-
const graphEntry = {
|
|
4289
|
-
step,
|
|
4290
|
-
config: {
|
|
4291
|
-
...this.#makeStepDef(stepKey),
|
|
4292
|
-
...config,
|
|
4293
|
-
loopLabel: config?.["#internal"]?.loopLabel,
|
|
4294
|
-
loopType: config?.["#internal"]?.loopType,
|
|
4295
|
-
serializedWhen: typeof when === "function" ? when.toString() : when,
|
|
4296
|
-
data: requiredData
|
|
4297
|
-
},
|
|
4298
|
-
get id() {
|
|
4299
|
-
return that.#makeStepKey(this.step, this.config);
|
|
4300
|
-
}
|
|
4301
|
-
};
|
|
4302
|
-
this.#steps[stepKey] = graphEntry;
|
|
4303
|
-
if (!lastStepKey) return this;
|
|
4304
|
-
const parentStepKey = this.#getParentStepKey();
|
|
4305
|
-
const stepGraph = this.#stepSubscriberGraph[parentStepKey || ""];
|
|
4306
|
-
const serializedStepGraph = this.#serializedStepSubscriberGraph[parentStepKey || ""];
|
|
4307
|
-
if (parentStepKey && this.#lastBuilderType === "after") {
|
|
4308
|
-
return this.step(step, config);
|
|
4309
|
-
}
|
|
4310
|
-
if (parentStepKey && stepGraph && stepGraph[lastStepKey]) {
|
|
4311
|
-
stepGraph[lastStepKey].push(graphEntry);
|
|
4312
|
-
if (serializedStepGraph && serializedStepGraph[lastStepKey]) serializedStepGraph[lastStepKey].push(graphEntry);
|
|
4313
|
-
} else {
|
|
4314
|
-
if (!this.#stepGraph[lastStepKey]) this.#stepGraph[lastStepKey] = [];
|
|
4315
|
-
if (!this.#serializedStepGraph[lastStepKey]) this.#serializedStepGraph[lastStepKey] = [];
|
|
4316
|
-
this.#stepGraph[lastStepKey].push(graphEntry);
|
|
4317
|
-
this.#serializedStepGraph[lastStepKey].push(graphEntry);
|
|
4318
|
-
}
|
|
4319
|
-
this.#lastBuilderType = "then";
|
|
4320
|
-
return this;
|
|
4321
|
-
}
|
|
4322
|
-
loop(applyOperator, condition, fallbackStep, loopType, variables) {
|
|
4323
|
-
const lastStepKey = this.#lastStepStack[this.#lastStepStack.length - 1];
|
|
4324
|
-
if (!lastStepKey) return this;
|
|
4325
|
-
const fallbackStepKey = this.#makeStepKey(fallbackStep);
|
|
4326
|
-
const fallbackStepNode = {
|
|
4327
|
-
step: fallbackStep,
|
|
4328
|
-
config: {
|
|
4329
|
-
...this.#makeStepDef(fallbackStepKey)
|
|
4330
|
-
},
|
|
4331
|
-
get id() {
|
|
4332
|
-
return fallbackStepKey;
|
|
4333
|
-
}
|
|
4334
|
-
};
|
|
4335
|
-
this.#steps[fallbackStepKey] = fallbackStepNode;
|
|
4336
|
-
const checkStepKey = `__${fallbackStepKey}_${loopType}_loop_check`;
|
|
4337
|
-
const checkStep = {
|
|
4338
|
-
id: checkStepKey,
|
|
4339
|
-
execute: async ({
|
|
4340
|
-
context
|
|
4341
|
-
}) => {
|
|
4342
|
-
if (typeof condition === "function") {
|
|
4343
|
-
const result = await condition({
|
|
4344
|
-
context
|
|
4345
|
-
});
|
|
4346
|
-
switch (loopType) {
|
|
4347
|
-
case "while":
|
|
4348
|
-
return {
|
|
4349
|
-
status: result ? "continue" : "complete"
|
|
4350
|
-
};
|
|
4351
|
-
case "until":
|
|
4352
|
-
return {
|
|
4353
|
-
status: result ? "complete" : "continue"
|
|
4354
|
-
};
|
|
4355
|
-
default:
|
|
4356
|
-
throw new Error(`Invalid loop type: ${loopType}`);
|
|
4357
|
-
}
|
|
4358
|
-
}
|
|
4359
|
-
if (condition && "ref" in condition) {
|
|
4360
|
-
const {
|
|
4361
|
-
ref,
|
|
4362
|
-
query
|
|
4363
|
-
} = condition;
|
|
4364
|
-
const stepId = typeof ref.step === "string" ? ref.step : "id" in ref.step ? ref.step.id : null;
|
|
4365
|
-
if (!stepId) {
|
|
4366
|
-
return {
|
|
4367
|
-
status: "continue"
|
|
4368
|
-
};
|
|
4369
|
-
}
|
|
4370
|
-
const stepOutput = context.steps?.[stepId]?.output;
|
|
4371
|
-
if (!stepOutput) {
|
|
4372
|
-
return {
|
|
4373
|
-
status: "continue"
|
|
4374
|
-
};
|
|
4375
|
-
}
|
|
4376
|
-
const value = ref.path.split(".").reduce((obj, key) => obj?.[key], stepOutput);
|
|
4377
|
-
const operator = Object.keys(query)[0];
|
|
4378
|
-
const target = query[operator];
|
|
4379
|
-
return applyOperator(operator, value, target);
|
|
4380
|
-
}
|
|
4381
|
-
return {
|
|
4382
|
-
status: "continue"
|
|
4383
|
-
};
|
|
4384
|
-
},
|
|
4385
|
-
outputSchema: z.object({
|
|
4386
|
-
status: z.enum(["continue", "complete"])
|
|
4387
|
-
})
|
|
4388
|
-
};
|
|
4389
|
-
const checkStepNode = {
|
|
4390
|
-
step: checkStep,
|
|
4391
|
-
config: {
|
|
4392
|
-
...this.#makeStepDef(checkStepKey)
|
|
4393
|
-
},
|
|
4394
|
-
get id() {
|
|
4395
|
-
return checkStepKey;
|
|
4396
|
-
}
|
|
4397
|
-
};
|
|
4398
|
-
this.#steps[checkStepKey] = checkStepNode;
|
|
4399
|
-
const loopFinishedStepKey = `__${fallbackStepKey}_${loopType}_loop_finished`;
|
|
4400
|
-
const loopFinishedStep = {
|
|
4401
|
-
id: loopFinishedStepKey,
|
|
4402
|
-
execute: async () => {
|
|
4403
|
-
return {
|
|
4404
|
-
success: true
|
|
4405
|
-
};
|
|
4406
|
-
}
|
|
4407
|
-
};
|
|
4408
|
-
const loopFinishedStepNode = {
|
|
4409
|
-
step: loopFinishedStep,
|
|
4410
|
-
config: {
|
|
4411
|
-
...this.#makeStepDef(loopFinishedStepKey)
|
|
4412
|
-
},
|
|
4413
|
-
get id() {
|
|
4414
|
-
return loopFinishedStepKey;
|
|
4415
|
-
}
|
|
4416
|
-
};
|
|
4417
|
-
this.#steps[loopFinishedStepKey] = loopFinishedStepNode;
|
|
4418
|
-
this.then(checkStep, {
|
|
4419
|
-
id: checkStepKey,
|
|
4420
|
-
"#internal": {
|
|
4421
|
-
loopLabel: `${fallbackStepKey} ${loopType} loop check`
|
|
4422
|
-
}
|
|
4423
|
-
});
|
|
4424
|
-
this.after(checkStep);
|
|
4425
|
-
this.#__internalStep(fallbackStep, {
|
|
4426
|
-
when: async ({
|
|
4427
|
-
context
|
|
4428
|
-
}) => {
|
|
4429
|
-
const checkStepResult = context.steps?.[checkStepKey];
|
|
4430
|
-
if (checkStepResult?.status !== "success") {
|
|
4431
|
-
return "abort" /* ABORT */;
|
|
4432
|
-
}
|
|
4433
|
-
const status = checkStepResult?.output?.status;
|
|
4434
|
-
return status === "continue" ? "continue" /* CONTINUE */ : "continue_failed" /* CONTINUE_FAILED */;
|
|
4435
|
-
},
|
|
4436
|
-
variables,
|
|
4437
|
-
"#internal": {
|
|
4438
|
-
// @ts-ignore
|
|
4439
|
-
when: condition,
|
|
4440
|
-
loopType
|
|
4441
|
-
}
|
|
4442
|
-
}).then(checkStep, {
|
|
4443
|
-
id: checkStepKey,
|
|
4444
|
-
"#internal": {
|
|
4445
|
-
loopLabel: `${fallbackStepKey} ${loopType} loop check`
|
|
4446
|
-
}
|
|
4447
|
-
});
|
|
4448
|
-
this.#__internalStep(loopFinishedStep, {
|
|
4449
|
-
id: loopFinishedStepKey,
|
|
4450
|
-
when: async ({
|
|
4451
|
-
context
|
|
4452
|
-
}) => {
|
|
4453
|
-
const checkStepResult = context.steps?.[checkStepKey];
|
|
4454
|
-
if (checkStepResult?.status !== "success") {
|
|
4455
|
-
return "continue_failed" /* CONTINUE_FAILED */;
|
|
4456
|
-
}
|
|
4457
|
-
const status = checkStepResult?.output?.status;
|
|
4458
|
-
return status === "complete" ? "continue" /* CONTINUE */ : "continue_failed" /* CONTINUE_FAILED */;
|
|
4459
|
-
},
|
|
4460
|
-
"#internal": {
|
|
4461
|
-
loopLabel: `${fallbackStepKey} ${loopType} loop finished`,
|
|
4462
|
-
//@ts-ignore
|
|
4463
|
-
loopType
|
|
4464
|
-
}
|
|
4465
|
-
});
|
|
4466
|
-
return this;
|
|
4467
|
-
}
|
|
4468
|
-
while(condition, fallbackStep, variables) {
|
|
4469
|
-
const applyOperator = (operator, value, target) => {
|
|
4470
|
-
switch (operator) {
|
|
4471
|
-
case "$eq":
|
|
4472
|
-
return {
|
|
4473
|
-
status: value !== target ? "complete" : "continue"
|
|
4474
|
-
};
|
|
4475
|
-
case "$ne":
|
|
4476
|
-
return {
|
|
4477
|
-
status: value === target ? "complete" : "continue"
|
|
4478
|
-
};
|
|
4479
|
-
case "$gt":
|
|
4480
|
-
return {
|
|
4481
|
-
status: value <= target ? "complete" : "continue"
|
|
4482
|
-
};
|
|
4483
|
-
case "$gte":
|
|
4484
|
-
return {
|
|
4485
|
-
status: value < target ? "complete" : "continue"
|
|
4486
|
-
};
|
|
4487
|
-
case "$lt":
|
|
4488
|
-
return {
|
|
4489
|
-
status: value >= target ? "complete" : "continue"
|
|
4490
|
-
};
|
|
4491
|
-
case "$lte":
|
|
4492
|
-
return {
|
|
4493
|
-
status: value > target ? "complete" : "continue"
|
|
4494
|
-
};
|
|
4495
|
-
default:
|
|
4496
|
-
return {
|
|
4497
|
-
status: "continue"
|
|
4498
|
-
};
|
|
4499
|
-
}
|
|
4500
|
-
};
|
|
4501
|
-
const res = this.loop(applyOperator, condition, fallbackStep, "while", variables);
|
|
4502
|
-
this.#lastBuilderType = "while";
|
|
4503
|
-
return res;
|
|
4504
|
-
}
|
|
4505
|
-
until(condition, fallbackStep, variables) {
|
|
4506
|
-
const applyOperator = (operator, value, target) => {
|
|
4507
|
-
switch (operator) {
|
|
4508
|
-
case "$eq":
|
|
4509
|
-
return {
|
|
4510
|
-
status: value === target ? "complete" : "continue"
|
|
4511
|
-
};
|
|
4512
|
-
case "$ne":
|
|
4513
|
-
return {
|
|
4514
|
-
status: value !== target ? "complete" : "continue"
|
|
4515
|
-
};
|
|
4516
|
-
case "$gt":
|
|
4517
|
-
return {
|
|
4518
|
-
status: value > target ? "complete" : "continue"
|
|
4519
|
-
};
|
|
4520
|
-
case "$gte":
|
|
4521
|
-
return {
|
|
4522
|
-
status: value >= target ? "complete" : "continue"
|
|
4523
|
-
};
|
|
4524
|
-
case "$lt":
|
|
4525
|
-
return {
|
|
4526
|
-
status: value < target ? "complete" : "continue"
|
|
4527
|
-
};
|
|
4528
|
-
case "$lte":
|
|
4529
|
-
return {
|
|
4530
|
-
status: value <= target ? "complete" : "continue"
|
|
4531
|
-
};
|
|
4532
|
-
default:
|
|
4533
|
-
return {
|
|
4534
|
-
status: "continue"
|
|
4535
|
-
};
|
|
4536
|
-
}
|
|
4537
|
-
};
|
|
4538
|
-
const res = this.loop(applyOperator, condition, fallbackStep, "until", variables);
|
|
4539
|
-
this.#lastBuilderType = "until";
|
|
4540
|
-
return res;
|
|
4541
|
-
}
|
|
4542
|
-
if(condition, ifStep, elseStep) {
|
|
4543
|
-
this.#ifCount++;
|
|
4544
|
-
const lastStep = this.#getLastStep({
|
|
4545
|
-
if_else_check: this.#lastBuilderType !== "else"
|
|
4546
|
-
});
|
|
4547
|
-
if (!lastStep) {
|
|
4548
|
-
throw new Error("Condition requires a step to be executed after");
|
|
4549
|
-
}
|
|
4550
|
-
this.after(lastStep.step);
|
|
4551
|
-
if (ifStep) {
|
|
4552
|
-
const _ifStep = isWorkflow(ifStep) ? workflowToStep(ifStep, {
|
|
4553
|
-
mastra: this.#mastra
|
|
4554
|
-
}) : ifStep;
|
|
4555
|
-
this.step(_ifStep, {
|
|
4556
|
-
id: _ifStep.id,
|
|
4557
|
-
when: condition
|
|
4558
|
-
});
|
|
4559
|
-
if (elseStep) {
|
|
4560
|
-
const _elseStep = isWorkflow(elseStep) ? workflowToStep(elseStep, {
|
|
4561
|
-
mastra: this.#mastra
|
|
4562
|
-
}) : elseStep;
|
|
4563
|
-
this.step(_elseStep, {
|
|
4564
|
-
id: _elseStep.id,
|
|
4565
|
-
when: typeof condition === "function" ? async payload => {
|
|
4566
|
-
const result = await condition(payload);
|
|
4567
|
-
return !result;
|
|
4568
|
-
} : {
|
|
4569
|
-
not: condition
|
|
4570
|
-
}
|
|
4571
|
-
});
|
|
4572
|
-
this.after([_ifStep, _elseStep]);
|
|
4573
|
-
} else {
|
|
4574
|
-
this.after(_ifStep);
|
|
4575
|
-
}
|
|
4576
|
-
this.step(new LegacyStep({
|
|
4577
|
-
id: `${lastStep.id}_if_else`,
|
|
4578
|
-
execute: async () => {
|
|
4579
|
-
return {
|
|
4580
|
-
executed: true
|
|
4581
|
-
};
|
|
4582
|
-
}
|
|
4583
|
-
}));
|
|
4584
|
-
return this;
|
|
4585
|
-
}
|
|
4586
|
-
const ifStepKey = `__${lastStep.id}_if_${this.#ifCount}`;
|
|
4587
|
-
this.step({
|
|
4588
|
-
id: ifStepKey,
|
|
4589
|
-
execute: async () => {
|
|
4590
|
-
return {
|
|
4591
|
-
executed: true
|
|
4592
|
-
};
|
|
4593
|
-
}
|
|
4594
|
-
}, {
|
|
4595
|
-
id: ifStepKey,
|
|
4596
|
-
when: condition
|
|
4597
|
-
});
|
|
4598
|
-
const elseStepKey = `__${lastStep.id}_else_${this.#ifCount}`;
|
|
4599
|
-
this.#ifStack.push({
|
|
4600
|
-
condition,
|
|
4601
|
-
elseStepKey,
|
|
4602
|
-
condStep: lastStep.step
|
|
4603
|
-
});
|
|
4604
|
-
this.#lastBuilderType = "if";
|
|
4605
|
-
return this;
|
|
4606
|
-
}
|
|
4607
|
-
else() {
|
|
4608
|
-
const activeCondition = this.#ifStack.pop();
|
|
4609
|
-
if (!activeCondition) {
|
|
4610
|
-
throw new Error("No active condition found");
|
|
4611
|
-
}
|
|
4612
|
-
this.after(activeCondition.condStep).step({
|
|
4613
|
-
id: activeCondition.elseStepKey,
|
|
4614
|
-
execute: async () => {
|
|
4615
|
-
return {
|
|
4616
|
-
executed: true
|
|
4617
|
-
};
|
|
4618
|
-
}
|
|
4619
|
-
}, {
|
|
4620
|
-
id: activeCondition.elseStepKey,
|
|
4621
|
-
when: typeof activeCondition.condition === "function" ? async payload => {
|
|
4622
|
-
const result = await activeCondition.condition(payload);
|
|
4623
|
-
return !result;
|
|
4624
|
-
} : {
|
|
4625
|
-
not: activeCondition.condition
|
|
4626
|
-
}
|
|
4627
|
-
});
|
|
4628
|
-
this.#lastBuilderType = "else";
|
|
4629
|
-
return this;
|
|
4630
|
-
}
|
|
4631
|
-
after(steps) {
|
|
4632
|
-
const stepsArray = Array.isArray(steps) ? steps : [steps];
|
|
4633
|
-
const stepKeys = stepsArray.map(step => this.#makeStepKey(step));
|
|
4634
|
-
const compoundKey = stepKeys.join("&&");
|
|
4635
|
-
this.#afterStepStack.push(compoundKey);
|
|
4636
|
-
if (!this.#stepSubscriberGraph[compoundKey]) {
|
|
4637
|
-
this.#stepSubscriberGraph[compoundKey] = {
|
|
4638
|
-
initial: []
|
|
4639
|
-
};
|
|
4640
|
-
this.#serializedStepSubscriberGraph[compoundKey] = {
|
|
4641
|
-
initial: []
|
|
4642
|
-
};
|
|
4643
|
-
}
|
|
4644
|
-
this.#lastBuilderType = "after";
|
|
4645
|
-
return this;
|
|
4646
|
-
}
|
|
4647
|
-
afterEvent(eventName) {
|
|
4648
|
-
const event = this.events?.[eventName];
|
|
4649
|
-
if (!event) {
|
|
4650
|
-
throw new Error(`Event ${eventName} not found`);
|
|
4651
|
-
}
|
|
4652
|
-
const lastStep = this.#steps[this.#lastStepStack[this.#lastStepStack.length - 1] ?? ""];
|
|
4653
|
-
if (!lastStep) {
|
|
4654
|
-
throw new Error("Condition requires a step to be executed after");
|
|
4655
|
-
}
|
|
4656
|
-
const eventStepKey = `__${eventName}_event`;
|
|
4657
|
-
const eventStep = new LegacyStep({
|
|
4658
|
-
id: eventStepKey,
|
|
4659
|
-
execute: async ({
|
|
4660
|
-
context,
|
|
4661
|
-
suspend
|
|
4662
|
-
}) => {
|
|
4663
|
-
if (context.inputData?.resumedEvent) {
|
|
4664
|
-
return {
|
|
4665
|
-
executed: true,
|
|
4666
|
-
resumedEvent: context.inputData?.resumedEvent
|
|
4667
|
-
};
|
|
4668
|
-
}
|
|
4669
|
-
await suspend();
|
|
4670
|
-
return {
|
|
4671
|
-
executed: false
|
|
4672
|
-
};
|
|
4673
|
-
}
|
|
4674
|
-
});
|
|
4675
|
-
this.after(lastStep.step).step(eventStep).after(eventStep);
|
|
4676
|
-
this.#lastBuilderType = "afterEvent";
|
|
4677
|
-
return this;
|
|
4678
|
-
}
|
|
4679
|
-
/**
|
|
4680
|
-
* Executes the workflow with the given trigger data
|
|
4681
|
-
* @param triggerData - Initial data to start the workflow with
|
|
4682
|
-
* @returns Promise resolving to workflow results or rejecting with error
|
|
4683
|
-
* @throws Error if trigger schema validation fails
|
|
4684
|
-
*/
|
|
4685
|
-
createRun({
|
|
4686
|
-
runId,
|
|
4687
|
-
events
|
|
4688
|
-
} = {}) {
|
|
4689
|
-
const run = new WorkflowInstance({
|
|
4690
|
-
logger: this.logger,
|
|
4691
|
-
name: this.name,
|
|
4692
|
-
mastra: this.#mastra,
|
|
4693
|
-
retryConfig: this.#retryConfig,
|
|
4694
|
-
steps: this.#steps,
|
|
4695
|
-
runId,
|
|
4696
|
-
stepGraph: this.#stepGraph,
|
|
4697
|
-
stepSubscriberGraph: this.#stepSubscriberGraph,
|
|
4698
|
-
onStepTransition: this.#onStepTransition,
|
|
4699
|
-
resultMapping: this.resultMapping,
|
|
4700
|
-
onFinish: () => {
|
|
4701
|
-
this.#runs.delete(run.runId);
|
|
4702
|
-
},
|
|
4703
|
-
events
|
|
4704
|
-
});
|
|
4705
|
-
this.#runs.set(run.runId, run);
|
|
4706
|
-
return {
|
|
4707
|
-
start: run.start.bind(run),
|
|
4708
|
-
runId: run.runId,
|
|
4709
|
-
watch: run.watch.bind(run),
|
|
4710
|
-
resume: run.resume.bind(run),
|
|
4711
|
-
resumeWithEvent: run.resumeWithEvent.bind(run)
|
|
4712
|
-
};
|
|
4713
|
-
}
|
|
4714
|
-
/**
|
|
4715
|
-
* Gets a workflow run instance by ID
|
|
4716
|
-
* @param runId - ID of the run to retrieve
|
|
4717
|
-
* @returns The workflow run instance if found, undefined otherwise
|
|
4718
|
-
*/
|
|
4719
|
-
async getRun(runId) {
|
|
4720
|
-
const inMemoryRun = this.#runs.get(runId);
|
|
4721
|
-
if (inMemoryRun) {
|
|
4722
|
-
return inMemoryRun;
|
|
4723
|
-
}
|
|
4724
|
-
const storage = this.#mastra?.getStorage();
|
|
4725
|
-
if (!storage) {
|
|
4726
|
-
this.logger.debug("Cannot get workflow run. Mastra engine is not initialized");
|
|
4727
|
-
return null;
|
|
4728
|
-
}
|
|
4729
|
-
return await storage.getWorkflowRunById({
|
|
4730
|
-
runId,
|
|
4731
|
-
workflowName: this.name
|
|
4732
|
-
});
|
|
4733
|
-
}
|
|
4734
|
-
/**
|
|
4735
|
-
* Gets a workflow run instance by ID, from memory
|
|
4736
|
-
* @param runId - ID of the run to retrieve
|
|
4737
|
-
* @returns The workflow run instance if found, undefined otherwise
|
|
4738
|
-
*/
|
|
4739
|
-
getMemoryRun(runId) {
|
|
4740
|
-
return this.#runs.get(runId);
|
|
4741
|
-
}
|
|
4742
|
-
/**
|
|
4743
|
-
* Rebuilds the machine with the current steps configuration and validates the workflow
|
|
4744
|
-
*
|
|
4745
|
-
* This is the last step of a workflow builder method chain
|
|
4746
|
-
* @throws Error if validation fails
|
|
4747
|
-
*
|
|
4748
|
-
* @returns this instance for method chaining
|
|
4749
|
-
*/
|
|
4750
|
-
commit() {
|
|
4751
|
-
return this;
|
|
4752
|
-
}
|
|
4753
|
-
// record all object paths that leads to a suspended state
|
|
4754
|
-
#getSuspendedPaths({
|
|
4755
|
-
value,
|
|
4756
|
-
path,
|
|
4757
|
-
suspendedPaths
|
|
4758
|
-
}) {
|
|
4759
|
-
if (typeof value === "string") {
|
|
4760
|
-
if (value === "suspended") {
|
|
4761
|
-
suspendedPaths.add(path);
|
|
4762
|
-
}
|
|
4763
|
-
} else {
|
|
4764
|
-
Object.keys(value).forEach(key => this.#getSuspendedPaths({
|
|
4765
|
-
value: value[key],
|
|
4766
|
-
path: path ? `${path}.${key}` : key,
|
|
4767
|
-
suspendedPaths
|
|
4768
|
-
}));
|
|
4769
|
-
}
|
|
4770
|
-
}
|
|
4771
|
-
async getWorkflowRuns(args) {
|
|
4772
|
-
const storage = this.#mastra?.getStorage();
|
|
4773
|
-
if (!storage) {
|
|
4774
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
4775
|
-
return {
|
|
4776
|
-
runs: [],
|
|
4777
|
-
total: 0
|
|
4778
|
-
};
|
|
4779
|
-
}
|
|
4780
|
-
return storage.getWorkflowRuns({
|
|
4781
|
-
workflowName: this.name,
|
|
4782
|
-
...(args ?? {})
|
|
4783
|
-
});
|
|
4784
|
-
}
|
|
4785
|
-
getExecutionSpan(runId) {
|
|
4786
|
-
return this.#runs.get(runId)?.executionSpan;
|
|
4787
|
-
}
|
|
4788
|
-
#getParentStepKey({
|
|
4789
|
-
loop_check = false,
|
|
4790
|
-
if_else_check = false
|
|
4791
|
-
} = {}) {
|
|
4792
|
-
for (let i = this.#afterStepStack.length - 1; i >= 0; i--) {
|
|
4793
|
-
const stepKey = this.#afterStepStack[i];
|
|
4794
|
-
if (!stepKey) continue;
|
|
4795
|
-
const isValidStep = this.#stepSubscriberGraph[stepKey] && (!loop_check || !stepKey.includes("loop_check")) && (!if_else_check || !isConditionalKey(stepKey));
|
|
4796
|
-
if (isValidStep) {
|
|
4797
|
-
return stepKey;
|
|
4798
|
-
}
|
|
4799
|
-
}
|
|
4800
|
-
return void 0;
|
|
4801
|
-
}
|
|
4802
|
-
#getLastStep({
|
|
4803
|
-
if_else_check
|
|
4804
|
-
}) {
|
|
4805
|
-
for (let i = this.#lastStepStack.length - 1; i >= 0; i--) {
|
|
4806
|
-
const stepKey = this.#lastStepStack[i];
|
|
4807
|
-
if (!stepKey) continue;
|
|
4808
|
-
const step = this.#steps[stepKey];
|
|
4809
|
-
const isInvalidStep = !step || if_else_check && isConditionalKey(stepKey);
|
|
4810
|
-
if (isInvalidStep) continue;
|
|
4811
|
-
return step;
|
|
4812
|
-
}
|
|
4813
|
-
return void 0;
|
|
4814
|
-
}
|
|
4815
|
-
#makeStepDef(stepId) {
|
|
4816
|
-
const executeStep = (handler2, spanName, attributes) => {
|
|
4817
|
-
return async data => {
|
|
4818
|
-
return await context.with(trace.setSpan(context.active(), this.getExecutionSpan(attributes?.runId ?? data?.runId)), async () => {
|
|
4819
|
-
if (this?.telemetry) {
|
|
4820
|
-
return this.telemetry.traceMethod(handler2, {
|
|
4821
|
-
spanName,
|
|
4822
|
-
attributes
|
|
4823
|
-
})(data);
|
|
4824
|
-
} else {
|
|
4825
|
-
return handler2(data);
|
|
4826
|
-
}
|
|
4827
|
-
});
|
|
4828
|
-
};
|
|
4829
|
-
};
|
|
4830
|
-
const handler = async ({
|
|
4831
|
-
context,
|
|
4832
|
-
...rest
|
|
4833
|
-
}) => {
|
|
4834
|
-
const targetStep = this.#steps[stepId];
|
|
4835
|
-
if (!targetStep) throw new Error(`Step not found`);
|
|
4836
|
-
const {
|
|
4837
|
-
payload = {},
|
|
4838
|
-
execute = async () => {}
|
|
4839
|
-
} = targetStep.step;
|
|
4840
|
-
const finalAction = this.telemetry ? executeStep(execute, `workflow.${this.name}.action.${stepId}`, {
|
|
4841
|
-
componentName: this.name,
|
|
4842
|
-
runId: rest.runId
|
|
4843
|
-
}) : execute;
|
|
4844
|
-
return finalAction ? await finalAction({
|
|
4845
|
-
context: {
|
|
4846
|
-
...context,
|
|
4847
|
-
inputData: {
|
|
4848
|
-
...(context?.inputData || {}),
|
|
4849
|
-
...payload
|
|
4850
|
-
}
|
|
4851
|
-
},
|
|
4852
|
-
...rest
|
|
4853
|
-
}) : {};
|
|
4854
|
-
};
|
|
4855
|
-
const finalHandler = ({
|
|
4856
|
-
context,
|
|
4857
|
-
...rest
|
|
4858
|
-
}) => {
|
|
4859
|
-
if (this.getExecutionSpan(rest?.runId)) {
|
|
4860
|
-
return executeStep(handler, `workflow.${this.name}.step.${stepId}`, {
|
|
4861
|
-
componentName: this.name,
|
|
4862
|
-
runId: rest?.runId
|
|
4863
|
-
})({
|
|
4864
|
-
context,
|
|
4865
|
-
...rest
|
|
4866
|
-
});
|
|
4867
|
-
}
|
|
4868
|
-
return handler({
|
|
4869
|
-
context,
|
|
4870
|
-
...rest
|
|
4871
|
-
});
|
|
4872
|
-
};
|
|
4873
|
-
return {
|
|
4874
|
-
handler: finalHandler,
|
|
4875
|
-
data: {}
|
|
4876
|
-
};
|
|
4877
|
-
}
|
|
4878
|
-
#getActivePathsAndStatus(value) {
|
|
4879
|
-
const paths = [];
|
|
4880
|
-
const traverse = (current, path = []) => {
|
|
4881
|
-
for (const [key, value2] of Object.entries(current)) {
|
|
4882
|
-
const currentPath = [...path, key];
|
|
4883
|
-
if (typeof value2 === "string") {
|
|
4884
|
-
paths.push({
|
|
4885
|
-
stepPath: currentPath,
|
|
4886
|
-
stepId: key,
|
|
4887
|
-
status: value2
|
|
4888
|
-
});
|
|
4889
|
-
} else if (typeof value2 === "object" && value2 !== null) {
|
|
4890
|
-
traverse(value2, currentPath);
|
|
4891
|
-
}
|
|
4892
|
-
}
|
|
4893
|
-
};
|
|
4894
|
-
traverse(value);
|
|
4895
|
-
return paths;
|
|
4896
|
-
}
|
|
4897
|
-
async getState(runId) {
|
|
4898
|
-
const run = this.#runs.get(runId);
|
|
4899
|
-
if (run) {
|
|
4900
|
-
return run.getState();
|
|
4901
|
-
}
|
|
4902
|
-
const storage = this.#mastra?.getStorage();
|
|
4903
|
-
const storedSnapshot = await storage?.loadWorkflowSnapshot({
|
|
4904
|
-
runId,
|
|
4905
|
-
workflowName: this.name
|
|
4906
|
-
});
|
|
4907
|
-
if (storedSnapshot) {
|
|
4908
|
-
const parsed = storedSnapshot;
|
|
4909
|
-
const m = this.#getActivePathsAndStatus(parsed.value);
|
|
4910
|
-
return {
|
|
4911
|
-
runId,
|
|
4912
|
-
value: parsed.value,
|
|
4913
|
-
context: parsed.context,
|
|
4914
|
-
activePaths: m,
|
|
4915
|
-
timestamp: Date.now()
|
|
4916
|
-
};
|
|
4917
|
-
}
|
|
4918
|
-
return null;
|
|
4919
|
-
}
|
|
4920
|
-
async resume({
|
|
4921
|
-
runId,
|
|
4922
|
-
stepId,
|
|
4923
|
-
context: resumeContext,
|
|
4924
|
-
runtimeContext = new RuntimeContext()
|
|
4925
|
-
}) {
|
|
4926
|
-
this.logger.warn(`Please use 'resume' on the 'createRun' call instead, resume is deprecated`);
|
|
4927
|
-
const activeRun = this.#runs.get(runId);
|
|
4928
|
-
if (activeRun) {
|
|
4929
|
-
return activeRun.resume({
|
|
4930
|
-
stepId,
|
|
4931
|
-
context: resumeContext,
|
|
4932
|
-
runtimeContext
|
|
4933
|
-
});
|
|
4934
|
-
}
|
|
4935
|
-
const run = this.createRun({
|
|
4936
|
-
runId
|
|
4937
|
-
});
|
|
4938
|
-
return run.resume({
|
|
4939
|
-
stepId,
|
|
4940
|
-
context: resumeContext,
|
|
4941
|
-
runtimeContext
|
|
4942
|
-
});
|
|
4943
|
-
}
|
|
4944
|
-
watch(onTransition) {
|
|
4945
|
-
this.logger.warn(`Please use 'watch' on the 'createRun' call instead, watch is deprecated`);
|
|
4946
|
-
this.#onStepTransition.add(onTransition);
|
|
4947
|
-
return () => {
|
|
4948
|
-
this.#onStepTransition.delete(onTransition);
|
|
4949
|
-
};
|
|
4950
|
-
}
|
|
4951
|
-
async resumeWithEvent(runId, eventName, data) {
|
|
4952
|
-
this.logger.warn(`Please use 'resumeWithEvent' on the 'createRun' call instead, resumeWithEvent is deprecated`);
|
|
4953
|
-
const event = this.events?.[eventName];
|
|
4954
|
-
if (!event) {
|
|
4955
|
-
throw new Error(`Event ${eventName} not found`);
|
|
4956
|
-
}
|
|
4957
|
-
const results = await this.resume({
|
|
4958
|
-
runId,
|
|
4959
|
-
stepId: `__${eventName}_event`,
|
|
4960
|
-
context: {
|
|
4961
|
-
resumedEvent: data
|
|
4962
|
-
},
|
|
4963
|
-
runtimeContext: new RuntimeContext()
|
|
4964
|
-
});
|
|
4965
|
-
return results;
|
|
4966
|
-
}
|
|
4967
|
-
__registerMastra(mastra) {
|
|
4968
|
-
this.#mastra = mastra;
|
|
4969
|
-
}
|
|
4970
|
-
__registerPrimitives(p) {
|
|
4971
|
-
if (p.telemetry) {
|
|
4972
|
-
this.__setTelemetry(p.telemetry);
|
|
4973
|
-
}
|
|
4974
|
-
if (p.logger) {
|
|
4975
|
-
this.__setLogger(p.logger);
|
|
4976
|
-
}
|
|
4977
|
-
}
|
|
4978
|
-
get stepGraph() {
|
|
4979
|
-
return this.#stepGraph;
|
|
4980
|
-
}
|
|
4981
|
-
get stepSubscriberGraph() {
|
|
4982
|
-
return this.#stepSubscriberGraph;
|
|
4983
|
-
}
|
|
4984
|
-
get serializedStepGraph() {
|
|
4985
|
-
return this.#serializedStepGraph;
|
|
4986
|
-
}
|
|
4987
|
-
get serializedStepSubscriberGraph() {
|
|
4988
|
-
return this.#serializedStepSubscriberGraph;
|
|
4989
|
-
}
|
|
4990
|
-
get steps() {
|
|
4991
|
-
return Object.entries(this.#steps).reduce((acc, [key, step]) => {
|
|
4992
|
-
acc[key] = step.step;
|
|
4993
|
-
return acc;
|
|
4994
|
-
}, {});
|
|
4995
|
-
}
|
|
4996
|
-
setNested(isNested) {
|
|
4997
|
-
this.isNested = isNested;
|
|
4998
|
-
}
|
|
4999
|
-
toStep() {
|
|
5000
|
-
const x = workflowToStep(this, {
|
|
5001
|
-
mastra: this.#mastra
|
|
5002
|
-
});
|
|
5003
|
-
return new LegacyStep(x);
|
|
5004
|
-
}
|
|
5005
|
-
};
|
|
5006
|
-
|
|
5007
|
-
export { Agent, LegacyStep, LegacyWorkflow, WhenConditionReturnValue, agentToStep, getActivePathsAndStatus, getResultActivePaths, getStepResult, getSuspendedPaths, isAgent, isConditionalKey, isErrorEvent, isFinalState, isLimboState, isTransitionEvent, isVariableReference, isWorkflow, mergeChildValue, recursivelyCheckForFinalState, resolveVariables, updateStepInHierarchy, workflowToStep };
|