@mettlelabs/mettle 0.0.0-0 → 0.0.0-beta.1-linux-x64
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/THIRD_PARTY_NOTICES.md +11479 -0
- package/bin/mettle +4 -0
- package/harness/audit-investigation.mjs +203 -0
- package/harness/chunk-13tgmdey.mjs +33761 -0
- package/harness/chunk-1sygmp11.mjs +18142 -0
- package/harness/chunk-1ykxpmaz.mjs +7887 -0
- package/harness/chunk-2gt4cy7x.mjs +2290 -0
- package/harness/chunk-2pm2sayw.mjs +248 -0
- package/harness/chunk-32y07kkp.mjs +3747 -0
- package/harness/chunk-3m7jn5ac.mjs +16242 -0
- package/harness/chunk-3wvjs93w.mjs +538 -0
- package/harness/chunk-4bepyxmq.mjs +113 -0
- package/harness/chunk-4jtnt9k5.mjs +95 -0
- package/harness/chunk-50sbrf09.mjs +18972 -0
- package/harness/chunk-56csr8sw.mjs +322 -0
- package/harness/chunk-5cvb1jnb.mjs +41 -0
- package/harness/chunk-5wgmv4np.mjs +585 -0
- package/harness/chunk-65eyq32y.mjs +225 -0
- package/harness/chunk-6fnh6qhk.mjs +195 -0
- package/harness/chunk-6kgqw9ny.mjs +32303 -0
- package/harness/chunk-7b242j0n.mjs +14 -0
- package/harness/chunk-7bg2gnv2.mjs +7540 -0
- package/harness/chunk-ageqxj9v.mjs +63008 -0
- package/harness/chunk-b0qbt5jd.mjs +14 -0
- package/harness/chunk-b5g1r3fz.mjs +4785 -0
- package/harness/chunk-b71gpkxg.mjs +1514 -0
- package/harness/chunk-bdv1rx4a.mjs +20364 -0
- package/harness/chunk-c1631s2x.mjs +12241 -0
- package/harness/chunk-d5xgxsnp.mjs +74 -0
- package/harness/chunk-erg1fbh0.mjs +0 -0
- package/harness/chunk-fh78v9vn.mjs +19366 -0
- package/harness/chunk-fjx29qvp.mjs +50 -0
- package/harness/chunk-gryka6kg.mjs +39 -0
- package/harness/chunk-jb0r19et.mjs +180 -0
- package/harness/chunk-mfn574ss.mjs +179 -0
- package/harness/chunk-msg872ea.mjs +334 -0
- package/harness/chunk-nz5sv9as.mjs +1642 -0
- package/harness/chunk-p9d3cgvq.mjs +452 -0
- package/harness/chunk-pq6wvwxr.mjs +12 -0
- package/harness/chunk-qcm9arf8.mjs +7736 -0
- package/harness/chunk-qr8zfqjd.mjs +24 -0
- package/harness/chunk-rz2tz6jp.mjs +26 -0
- package/harness/chunk-sbkgc3kn.mjs +8 -0
- package/harness/chunk-v66qvpnb.mjs +169 -0
- package/harness/chunk-vjaxzab3.mjs +136 -0
- package/harness/chunk-vr1n5nza.mjs +1045 -0
- package/harness/chunk-vsf2zajv.mjs +3867 -0
- package/harness/chunk-wq253fj4.mjs +19041 -0
- package/harness/chunk-wyv7ceq4.mjs +0 -0
- package/harness/chunk-xnqknk2r.mjs +198 -0
- package/harness/chunk-xqyc4ca2.mjs +1890 -0
- package/harness/chunk-z6n9thea.mjs +45146 -0
- package/harness/chunk-zty0d3bw.mjs +0 -0
- package/harness/chunk-zvkxtj82.mjs +42 -0
- package/harness/issue-api-token.mjs +35 -0
- package/harness/launcher.mjs +159 -0
- package/harness/sandbox.mjs +132 -0
- package/harness/server.mjs +66322 -0
- package/package.json +20 -3
|
@@ -0,0 +1,585 @@
|
|
|
1
|
+
import {
|
|
2
|
+
parseFsAgentScheduleRowId,
|
|
3
|
+
MastraWorker,
|
|
4
|
+
PullTransport
|
|
5
|
+
} from "./chunk-jb0r19et.mjs";
|
|
6
|
+
import {
|
|
7
|
+
resolveAgentById
|
|
8
|
+
} from "./chunk-rz2tz6jp.mjs";
|
|
9
|
+
import {
|
|
10
|
+
RequestContext
|
|
11
|
+
} from "./chunk-mfn574ss.mjs";
|
|
12
|
+
|
|
13
|
+
// node_modules/.bun/@mastra+core@1.71.0+95d98e20cbc6e6e1/node_modules/@mastra/core/dist/worker-BoYkCgzR.js
|
|
14
|
+
var TOPIC_AGENT_SCHEDULES = "agent-schedules";
|
|
15
|
+
var DEFAULT_GROUP = "mastra-agent-schedules";
|
|
16
|
+
var AgentScheduleWorker = class extends MastraWorker {
|
|
17
|
+
name = "agent-schedule";
|
|
18
|
+
#config;
|
|
19
|
+
#transport;
|
|
20
|
+
#pushCb;
|
|
21
|
+
#running = false;
|
|
22
|
+
constructor(config = {}) {
|
|
23
|
+
super();
|
|
24
|
+
this.#config = config;
|
|
25
|
+
}
|
|
26
|
+
async init(deps) {
|
|
27
|
+
await super.init(deps);
|
|
28
|
+
if (!deps.mastra)
|
|
29
|
+
throw new Error("AgentScheduleWorker requires Mastra instance");
|
|
30
|
+
}
|
|
31
|
+
async start() {
|
|
32
|
+
if (this.#running)
|
|
33
|
+
return;
|
|
34
|
+
if (!this.deps)
|
|
35
|
+
throw new Error("AgentScheduleWorker: call init() before start()");
|
|
36
|
+
if (!(this.deps.pubsub.supportedModes ?? ["pull"]).includes("pull")) {
|
|
37
|
+
const cb = (event, ack, nack) => {
|
|
38
|
+
this.#handleEvent(event, ack, nack);
|
|
39
|
+
};
|
|
40
|
+
this.#pushCb = cb;
|
|
41
|
+
await this.deps.pubsub.subscribe(TOPIC_AGENT_SCHEDULES, cb);
|
|
42
|
+
this.#running = true;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const group = this.#config.group ?? DEFAULT_GROUP;
|
|
46
|
+
this.#transport = new PullTransport({
|
|
47
|
+
pubsub: this.deps.pubsub,
|
|
48
|
+
group,
|
|
49
|
+
topic: TOPIC_AGENT_SCHEDULES,
|
|
50
|
+
logger: this.deps.logger
|
|
51
|
+
});
|
|
52
|
+
await this.#transport.start({ route: (event, ack, nack) => this.#handleEvent(event, ack, nack) });
|
|
53
|
+
this.#running = true;
|
|
54
|
+
}
|
|
55
|
+
async stop() {
|
|
56
|
+
if (!this.#running)
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
if (this.#transport) {
|
|
60
|
+
await this.#transport.stop();
|
|
61
|
+
this.#transport = undefined;
|
|
62
|
+
}
|
|
63
|
+
if (this.#pushCb && this.deps) {
|
|
64
|
+
await this.deps.pubsub.unsubscribe(TOPIC_AGENT_SCHEDULES, this.#pushCb);
|
|
65
|
+
this.#pushCb = undefined;
|
|
66
|
+
}
|
|
67
|
+
} finally {
|
|
68
|
+
this.#running = false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
get isRunning() {
|
|
72
|
+
return this.#running;
|
|
73
|
+
}
|
|
74
|
+
async#handleEvent(event, ack, nack) {
|
|
75
|
+
if (event.type !== "agent-schedule.fire") {
|
|
76
|
+
await ack?.();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const mastra = this.mastra;
|
|
80
|
+
const payload = event.data;
|
|
81
|
+
try {
|
|
82
|
+
await this.#dispatch(mastra, payload);
|
|
83
|
+
await ack?.();
|
|
84
|
+
} catch (err) {
|
|
85
|
+
this.deps?.logger?.error("AgentScheduleWorker: error processing agent-schedule.fire", {
|
|
86
|
+
scheduleId: payload?.scheduleId,
|
|
87
|
+
claimId: payload?.claimId,
|
|
88
|
+
error: err
|
|
89
|
+
});
|
|
90
|
+
await nack?.();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async#dispatch(mastra, data) {
|
|
94
|
+
const { scheduleId, claimId, scheduledFireAt, target } = data;
|
|
95
|
+
const actualFireAt = Date.now();
|
|
96
|
+
const result = await executeAgentSchedule(mastra, scheduleId, target, {
|
|
97
|
+
triggerKind: data.triggerKind ?? "schedule-fire",
|
|
98
|
+
firedAt: new Date(actualFireAt),
|
|
99
|
+
logger: this.deps?.logger
|
|
100
|
+
});
|
|
101
|
+
await this.#recordTrigger({
|
|
102
|
+
scheduleId,
|
|
103
|
+
claimId,
|
|
104
|
+
scheduledFireAt,
|
|
105
|
+
actualFireAt,
|
|
106
|
+
outcome: result.outcome,
|
|
107
|
+
runId: result.runId,
|
|
108
|
+
error: result.reason,
|
|
109
|
+
triggerKind: data.triggerKind ?? "schedule-fire"
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async#recordTrigger(args) {
|
|
113
|
+
const store = await this.deps?.storage.getStore("schedules");
|
|
114
|
+
if (!store)
|
|
115
|
+
return;
|
|
116
|
+
try {
|
|
117
|
+
await store.recordTrigger({
|
|
118
|
+
scheduleId: args.scheduleId,
|
|
119
|
+
runId: args.runId ?? args.claimId,
|
|
120
|
+
scheduledFireAt: args.scheduledFireAt,
|
|
121
|
+
actualFireAt: args.actualFireAt,
|
|
122
|
+
outcome: args.outcome,
|
|
123
|
+
error: args.error,
|
|
124
|
+
triggerKind: args.triggerKind
|
|
125
|
+
});
|
|
126
|
+
} catch (err) {
|
|
127
|
+
this.deps?.logger?.error("AgentScheduleWorker: failed to record trigger", {
|
|
128
|
+
scheduleId: args.scheduleId,
|
|
129
|
+
claimId: args.claimId,
|
|
130
|
+
error: err
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
async function selfClean(mastra, scheduleId) {
|
|
136
|
+
try {
|
|
137
|
+
const store = await mastra.getStorage()?.getStore("schedules");
|
|
138
|
+
if (!store)
|
|
139
|
+
return;
|
|
140
|
+
await store.deleteSchedule(scheduleId);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
mastra.getLogger?.()?.debug?.("agent-schedule self-clean failed", {
|
|
143
|
+
scheduleId,
|
|
144
|
+
error
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
async function executeAgentSchedule(mastra, scheduleId, target, ctx = {}) {
|
|
149
|
+
const { agentId } = target;
|
|
150
|
+
const trigger = {
|
|
151
|
+
kind: ctx.triggerKind === "manual" ? "manual" : "cron",
|
|
152
|
+
firedAt: ctx.firedAt ?? /* @__PURE__ */ new Date
|
|
153
|
+
};
|
|
154
|
+
const log = ctx.logger ?? mastra.getLogger?.();
|
|
155
|
+
const resolved = await resolveAgentById(mastra, agentId);
|
|
156
|
+
if (resolved.status === "error") {
|
|
157
|
+
log?.error?.("Failed to resolve stored agent for schedule", {
|
|
158
|
+
scheduleId,
|
|
159
|
+
agentId,
|
|
160
|
+
error: resolved.error
|
|
161
|
+
});
|
|
162
|
+
return {
|
|
163
|
+
status: "agent-missing",
|
|
164
|
+
outcome: "failed",
|
|
165
|
+
reason: `failed to resolve agent "${agentId}"`
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
if (resolved.status === "missing") {
|
|
169
|
+
await selfClean(mastra, scheduleId);
|
|
170
|
+
return {
|
|
171
|
+
status: "agent-missing",
|
|
172
|
+
outcome: "failed",
|
|
173
|
+
reason: `agent "${agentId}" no longer registered`
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const agent = resolved.agent;
|
|
177
|
+
const hooks = mastra.__getScheduleHooks?.() ?? undefined;
|
|
178
|
+
const scheduleRef = hooks ? await loadScheduleRef(mastra, scheduleId, target, log) : scheduleRefFromTarget(scheduleId, target);
|
|
179
|
+
const fsHandler = mastra.__getFsAgentScheduleHandler?.(scheduleId);
|
|
180
|
+
const prepareStages = [];
|
|
181
|
+
if (fsHandler)
|
|
182
|
+
prepareStages.push(() => Promise.resolve(fsHandler({
|
|
183
|
+
mastra,
|
|
184
|
+
agentId,
|
|
185
|
+
scheduleId,
|
|
186
|
+
key: parseFsAgentScheduleRowId(scheduleId)?.key ?? scheduleId,
|
|
187
|
+
trigger
|
|
188
|
+
})));
|
|
189
|
+
if (hooks?.prepare)
|
|
190
|
+
prepareStages.push(() => Promise.resolve(hooks.prepare({
|
|
191
|
+
mastra,
|
|
192
|
+
agentId,
|
|
193
|
+
schedule: scheduleRef,
|
|
194
|
+
trigger
|
|
195
|
+
})));
|
|
196
|
+
let effective = buildEffectiveFromTarget(target);
|
|
197
|
+
for (const stage of prepareStages) {
|
|
198
|
+
let result;
|
|
199
|
+
try {
|
|
200
|
+
result = await stage();
|
|
201
|
+
} catch (err) {
|
|
202
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
203
|
+
mastra,
|
|
204
|
+
agentId,
|
|
205
|
+
schedule: scheduleRef,
|
|
206
|
+
trigger,
|
|
207
|
+
phase: "prepare",
|
|
208
|
+
error: err instanceof Error ? err : new Error(String(err)),
|
|
209
|
+
effective
|
|
210
|
+
}));
|
|
211
|
+
return {
|
|
212
|
+
status: "invalid-input",
|
|
213
|
+
outcome: "failed",
|
|
214
|
+
reason: err instanceof Error ? err.message : String(err)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
if (result === null) {
|
|
218
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
219
|
+
mastra,
|
|
220
|
+
agentId,
|
|
221
|
+
schedule: scheduleRef,
|
|
222
|
+
trigger,
|
|
223
|
+
outcome: "skipped",
|
|
224
|
+
effective
|
|
225
|
+
}));
|
|
226
|
+
return {
|
|
227
|
+
status: "fired",
|
|
228
|
+
outcome: "skipped"
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
effective = mergeEffective(effective, result ?? undefined);
|
|
232
|
+
}
|
|
233
|
+
if (fsHandler && (typeof effective.prompt !== "string" || effective.prompt.trim() === "")) {
|
|
234
|
+
const reason = "handler returned no prompt and the schedule has no stored prompt";
|
|
235
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
236
|
+
mastra,
|
|
237
|
+
agentId,
|
|
238
|
+
schedule: scheduleRef,
|
|
239
|
+
trigger,
|
|
240
|
+
phase: "prepare",
|
|
241
|
+
error: /* @__PURE__ */ new Error(reason),
|
|
242
|
+
effective
|
|
243
|
+
}));
|
|
244
|
+
return {
|
|
245
|
+
status: "invalid-input",
|
|
246
|
+
outcome: "failed",
|
|
247
|
+
reason
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
const scheduleRunMeta = {
|
|
251
|
+
scheduleId,
|
|
252
|
+
...effective.threadId ? { threadId: effective.threadId } : {}
|
|
253
|
+
};
|
|
254
|
+
if (effective.threadId) {
|
|
255
|
+
if (!effective.resourceId) {
|
|
256
|
+
const reason = "resourceId required when threadId is set";
|
|
257
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
258
|
+
mastra,
|
|
259
|
+
agentId,
|
|
260
|
+
schedule: scheduleRef,
|
|
261
|
+
trigger,
|
|
262
|
+
phase: "run",
|
|
263
|
+
error: /* @__PURE__ */ new Error(reason),
|
|
264
|
+
effective
|
|
265
|
+
}));
|
|
266
|
+
return {
|
|
267
|
+
status: "invalid-input",
|
|
268
|
+
outcome: "failed",
|
|
269
|
+
reason
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
const memory = await agent.getMemory();
|
|
273
|
+
if (memory) {
|
|
274
|
+
if (!await memory.getThreadById({ threadId: effective.threadId })) {
|
|
275
|
+
await selfClean(mastra, scheduleId);
|
|
276
|
+
const reason = `thread "${effective.threadId}" not found`;
|
|
277
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
278
|
+
mastra,
|
|
279
|
+
agentId,
|
|
280
|
+
schedule: scheduleRef,
|
|
281
|
+
trigger,
|
|
282
|
+
phase: "run",
|
|
283
|
+
error: new Error(reason),
|
|
284
|
+
effective
|
|
285
|
+
}));
|
|
286
|
+
return {
|
|
287
|
+
status: "thread-missing",
|
|
288
|
+
outcome: "failed",
|
|
289
|
+
reason
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
let signalResult;
|
|
294
|
+
try {
|
|
295
|
+
const signalType = effective.signalType ?? "notification";
|
|
296
|
+
const signalBase = {
|
|
297
|
+
tagName: effective.tagName ?? "schedule",
|
|
298
|
+
contents: effective.prompt,
|
|
299
|
+
...effective.attributes ? { attributes: effective.attributes } : {},
|
|
300
|
+
providerOptions: mergeProviderOptions(effective.providerOptions, scheduleRunMeta)
|
|
301
|
+
};
|
|
302
|
+
const signal = signalType === "state" ? {
|
|
303
|
+
...signalBase,
|
|
304
|
+
type: "state"
|
|
305
|
+
} : {
|
|
306
|
+
...signalBase,
|
|
307
|
+
type: signalType
|
|
308
|
+
};
|
|
309
|
+
signalResult = agent.sendSignal(signal, {
|
|
310
|
+
resourceId: effective.resourceId,
|
|
311
|
+
threadId: effective.threadId,
|
|
312
|
+
...effective.ifActive ? { ifActive: effective.ifActive } : {},
|
|
313
|
+
...effective.ifIdle ? { ifIdle: buildIfIdleOptions(effective.ifIdle) } : {}
|
|
314
|
+
});
|
|
315
|
+
} catch (err) {
|
|
316
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
317
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
318
|
+
mastra,
|
|
319
|
+
agentId,
|
|
320
|
+
schedule: scheduleRef,
|
|
321
|
+
trigger,
|
|
322
|
+
phase: "run",
|
|
323
|
+
error,
|
|
324
|
+
effective
|
|
325
|
+
}));
|
|
326
|
+
return {
|
|
327
|
+
status: "invalid-input",
|
|
328
|
+
outcome: "failed",
|
|
329
|
+
reason: error.message
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
let settled;
|
|
333
|
+
try {
|
|
334
|
+
settled = await signalResult.accepted;
|
|
335
|
+
} catch (err) {
|
|
336
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
337
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
338
|
+
mastra,
|
|
339
|
+
agentId,
|
|
340
|
+
schedule: scheduleRef,
|
|
341
|
+
trigger,
|
|
342
|
+
phase: "run",
|
|
343
|
+
error,
|
|
344
|
+
effective
|
|
345
|
+
}));
|
|
346
|
+
return {
|
|
347
|
+
status: "invalid-input",
|
|
348
|
+
outcome: "failed",
|
|
349
|
+
reason: error.message
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
const action = settled.action;
|
|
353
|
+
const runId = "runId" in settled ? settled.runId : undefined;
|
|
354
|
+
if (action === "deliver") {
|
|
355
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
356
|
+
mastra,
|
|
357
|
+
agentId,
|
|
358
|
+
schedule: scheduleRef,
|
|
359
|
+
trigger,
|
|
360
|
+
outcome: "delivered",
|
|
361
|
+
runId,
|
|
362
|
+
joinedExistingRun: true,
|
|
363
|
+
effective
|
|
364
|
+
}));
|
|
365
|
+
return {
|
|
366
|
+
status: "signal-accepted",
|
|
367
|
+
outcome: "delivered",
|
|
368
|
+
runId
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
if (action === "persist") {
|
|
372
|
+
if (signalResult.persisted)
|
|
373
|
+
try {
|
|
374
|
+
await signalResult.persisted;
|
|
375
|
+
} catch {}
|
|
376
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
377
|
+
mastra,
|
|
378
|
+
agentId,
|
|
379
|
+
schedule: scheduleRef,
|
|
380
|
+
trigger,
|
|
381
|
+
outcome: "persisted",
|
|
382
|
+
runId,
|
|
383
|
+
effective
|
|
384
|
+
}));
|
|
385
|
+
return {
|
|
386
|
+
status: "signal-accepted",
|
|
387
|
+
outcome: "persisted",
|
|
388
|
+
runId
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
if (action === "discard") {
|
|
392
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
393
|
+
mastra,
|
|
394
|
+
agentId,
|
|
395
|
+
schedule: scheduleRef,
|
|
396
|
+
trigger,
|
|
397
|
+
outcome: "discarded",
|
|
398
|
+
runId,
|
|
399
|
+
effective
|
|
400
|
+
}));
|
|
401
|
+
return {
|
|
402
|
+
status: "signal-accepted",
|
|
403
|
+
outcome: "discarded",
|
|
404
|
+
runId
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
if (action === "blocked") {
|
|
408
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
409
|
+
mastra,
|
|
410
|
+
agentId,
|
|
411
|
+
schedule: scheduleRef,
|
|
412
|
+
trigger,
|
|
413
|
+
outcome: "skipped",
|
|
414
|
+
runId,
|
|
415
|
+
effective
|
|
416
|
+
}));
|
|
417
|
+
return {
|
|
418
|
+
status: "skipped-thread-blocked",
|
|
419
|
+
outcome: "skipped",
|
|
420
|
+
runId
|
|
421
|
+
};
|
|
422
|
+
}
|
|
423
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
424
|
+
mastra,
|
|
425
|
+
agentId,
|
|
426
|
+
schedule: scheduleRef,
|
|
427
|
+
trigger,
|
|
428
|
+
outcome: "succeeded",
|
|
429
|
+
runId,
|
|
430
|
+
effective
|
|
431
|
+
}));
|
|
432
|
+
return {
|
|
433
|
+
status: "signal-accepted",
|
|
434
|
+
outcome: "succeeded",
|
|
435
|
+
runId
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
try {
|
|
439
|
+
const result = await agent.generate(effective.prompt, { providerOptions: mergeProviderOptions(effective.providerOptions, scheduleRunMeta) });
|
|
440
|
+
const runId = extractRunId(result);
|
|
441
|
+
await safeHookCall(log, () => hooks?.onFinish?.({
|
|
442
|
+
mastra,
|
|
443
|
+
agentId,
|
|
444
|
+
schedule: scheduleRef,
|
|
445
|
+
trigger,
|
|
446
|
+
outcome: "succeeded",
|
|
447
|
+
runId,
|
|
448
|
+
result: extractRunSnapshot(result),
|
|
449
|
+
effective
|
|
450
|
+
}));
|
|
451
|
+
return {
|
|
452
|
+
status: "fired",
|
|
453
|
+
outcome: "succeeded",
|
|
454
|
+
runId
|
|
455
|
+
};
|
|
456
|
+
} catch (err) {
|
|
457
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
458
|
+
if (isAbortError(error)) {
|
|
459
|
+
await safeHookCall(log, () => hooks?.onAbort?.({
|
|
460
|
+
mastra,
|
|
461
|
+
agentId,
|
|
462
|
+
schedule: scheduleRef,
|
|
463
|
+
trigger,
|
|
464
|
+
runId: extractRunId(error) ?? scheduleId,
|
|
465
|
+
effective
|
|
466
|
+
}));
|
|
467
|
+
return {
|
|
468
|
+
status: "fired",
|
|
469
|
+
outcome: "aborted"
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
await safeHookCall(log, () => hooks?.onError?.({
|
|
473
|
+
mastra,
|
|
474
|
+
agentId,
|
|
475
|
+
schedule: scheduleRef,
|
|
476
|
+
trigger,
|
|
477
|
+
phase: "run",
|
|
478
|
+
error,
|
|
479
|
+
effective
|
|
480
|
+
}));
|
|
481
|
+
return {
|
|
482
|
+
status: "invalid-input",
|
|
483
|
+
outcome: "failed",
|
|
484
|
+
reason: error.message
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function buildEffectiveFromTarget(target) {
|
|
489
|
+
return {
|
|
490
|
+
threadId: target.threadId,
|
|
491
|
+
resourceId: target.resourceId,
|
|
492
|
+
prompt: target.prompt,
|
|
493
|
+
signalType: target.signalType,
|
|
494
|
+
tagName: target.tagName,
|
|
495
|
+
attributes: target.attributes,
|
|
496
|
+
providerOptions: target.providerOptions,
|
|
497
|
+
ifActive: target.ifActive,
|
|
498
|
+
ifIdle: target.ifIdle
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function buildIfIdleOptions(ifIdle) {
|
|
502
|
+
const requestContext = ifIdle.streamOptions?.requestContext;
|
|
503
|
+
return {
|
|
504
|
+
...ifIdle.behavior ? { behavior: ifIdle.behavior } : {},
|
|
505
|
+
...ifIdle.attributes ? { attributes: ifIdle.attributes } : {},
|
|
506
|
+
...requestContext ? { streamOptions: { requestContext: new RequestContext(Object.entries(requestContext)) } } : {}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
function mergeEffective(base, overrides) {
|
|
510
|
+
if (!overrides)
|
|
511
|
+
return base;
|
|
512
|
+
return {
|
|
513
|
+
...base,
|
|
514
|
+
...overrides
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function mergeProviderOptions(fromHook, scheduleRunMeta) {
|
|
518
|
+
const base = fromHook ?? {};
|
|
519
|
+
const baseMastra = base.mastra ?? {};
|
|
520
|
+
return {
|
|
521
|
+
...base,
|
|
522
|
+
mastra: {
|
|
523
|
+
...baseMastra,
|
|
524
|
+
schedule: scheduleRunMeta
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
}
|
|
528
|
+
async function loadScheduleRef(mastra, scheduleId, target, logger) {
|
|
529
|
+
try {
|
|
530
|
+
const schedule = await mastra.schedules.get(scheduleId);
|
|
531
|
+
if (schedule && schedule.agentId !== undefined)
|
|
532
|
+
return {
|
|
533
|
+
...schedule,
|
|
534
|
+
agentId: schedule.agentId
|
|
535
|
+
};
|
|
536
|
+
} catch (err) {
|
|
537
|
+
logger?.debug?.("AgentScheduleWorker: failed to load schedule row for hook context", {
|
|
538
|
+
scheduleId,
|
|
539
|
+
error: err
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
return scheduleRefFromTarget(scheduleId, target);
|
|
543
|
+
}
|
|
544
|
+
function scheduleRefFromTarget(scheduleId, target) {
|
|
545
|
+
return {
|
|
546
|
+
id: scheduleId,
|
|
547
|
+
agentId: target.agentId,
|
|
548
|
+
...target.name !== undefined ? { name: target.name } : {}
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
async function safeHookCall(logger, fn) {
|
|
552
|
+
try {
|
|
553
|
+
await fn();
|
|
554
|
+
} catch (err) {
|
|
555
|
+
logger?.error?.("AgentScheduleWorker: hook threw, ignoring", { error: err });
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
function isAbortError(err) {
|
|
559
|
+
if (!err || typeof err !== "object")
|
|
560
|
+
return false;
|
|
561
|
+
return err.name === "AbortError";
|
|
562
|
+
}
|
|
563
|
+
function extractRunId(value) {
|
|
564
|
+
if (value && typeof value === "object" && "runId" in value) {
|
|
565
|
+
const runId = value.runId;
|
|
566
|
+
if (typeof runId === "string")
|
|
567
|
+
return runId;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
function extractRunSnapshot(value) {
|
|
571
|
+
if (!value || typeof value !== "object")
|
|
572
|
+
return;
|
|
573
|
+
const v = value;
|
|
574
|
+
const snapshot = {};
|
|
575
|
+
if (typeof v.text === "string")
|
|
576
|
+
snapshot.text = v.text;
|
|
577
|
+
if (v.usage && typeof v.usage === "object")
|
|
578
|
+
snapshot.usage = v.usage;
|
|
579
|
+
if (typeof v.finishReason === "string")
|
|
580
|
+
snapshot.finishReason = v.finishReason;
|
|
581
|
+
return Object.keys(snapshot).length > 0 ? snapshot : undefined;
|
|
582
|
+
}
|
|
583
|
+
export {
|
|
584
|
+
AgentScheduleWorker
|
|
585
|
+
};
|