@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,322 @@
|
|
|
1
|
+
import"./chunk-z6n9thea.mjs";
|
|
2
|
+
import"./chunk-3wvjs93w.mjs";
|
|
3
|
+
import"./chunk-c1631s2x.mjs";
|
|
4
|
+
import"./chunk-50sbrf09.mjs";
|
|
5
|
+
import {
|
|
6
|
+
resolveSuspendedToolRunId
|
|
7
|
+
} from "./chunk-3m7jn5ac.mjs";
|
|
8
|
+
import {
|
|
9
|
+
BACKGROUND_TASK_WORKFLOW_ID
|
|
10
|
+
} from "./chunk-6kgqw9ny.mjs";
|
|
11
|
+
import {
|
|
12
|
+
createStep$1,
|
|
13
|
+
createWorkflow
|
|
14
|
+
} from "./chunk-ageqxj9v.mjs";
|
|
15
|
+
import {
|
|
16
|
+
string,
|
|
17
|
+
boolean,
|
|
18
|
+
any,
|
|
19
|
+
unknown,
|
|
20
|
+
object,
|
|
21
|
+
_enum
|
|
22
|
+
} from "./chunk-1sygmp11.mjs";
|
|
23
|
+
|
|
24
|
+
// node_modules/.bun/@mastra+core@1.71.0+95d98e20cbc6e6e1/node_modules/@mastra/core/dist/workflow-DLhRNxEW.js
|
|
25
|
+
var inputSchema = object({ taskId: string() });
|
|
26
|
+
var attemptOutcomeSchema = _enum([
|
|
27
|
+
"success",
|
|
28
|
+
"retry",
|
|
29
|
+
"failed",
|
|
30
|
+
"cancelled",
|
|
31
|
+
"timed_out"
|
|
32
|
+
]);
|
|
33
|
+
var attemptOutputSchema = object({
|
|
34
|
+
taskId: string(),
|
|
35
|
+
outcome: attemptOutcomeSchema,
|
|
36
|
+
result: unknown().optional(),
|
|
37
|
+
error: any().optional()
|
|
38
|
+
});
|
|
39
|
+
var bodyIOSchema = object({
|
|
40
|
+
taskId: string(),
|
|
41
|
+
done: boolean().optional(),
|
|
42
|
+
result: unknown().optional()
|
|
43
|
+
});
|
|
44
|
+
var bodyOutputSchema = object({
|
|
45
|
+
taskId: string(),
|
|
46
|
+
done: boolean(),
|
|
47
|
+
result: unknown().optional()
|
|
48
|
+
});
|
|
49
|
+
var WORKFLOW_STATUS_TO_PERSIST = [
|
|
50
|
+
"suspended",
|
|
51
|
+
"pending",
|
|
52
|
+
"paused",
|
|
53
|
+
"waiting"
|
|
54
|
+
];
|
|
55
|
+
function buildBackgroundTaskWorkflow(manager) {
|
|
56
|
+
const runAttemptStep = createStep$1({
|
|
57
|
+
id: "run-attempt",
|
|
58
|
+
inputSchema: bodyIOSchema,
|
|
59
|
+
outputSchema: attemptOutputSchema,
|
|
60
|
+
execute: async ({ inputData, abortSignal: workflowAbortSignal, suspend, resumeData, suspendData }) => {
|
|
61
|
+
const { taskId } = inputData;
|
|
62
|
+
const storage = await manager.getStorage();
|
|
63
|
+
const task = await storage.getTask(taskId);
|
|
64
|
+
if (!task || task.status === "cancelled") {
|
|
65
|
+
manager.deregisterTaskContext(taskId);
|
|
66
|
+
return {
|
|
67
|
+
taskId,
|
|
68
|
+
outcome: "cancelled"
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const executor = manager.taskContexts.get(taskId)?.executor ?? (task.agentId ? manager.getStaticExecutor(`${task.agentId}:${task.toolName}`) : undefined) ?? manager.getStaticExecutor(task.toolName);
|
|
72
|
+
if (!executor) {
|
|
73
|
+
const errorInfo = { message: `No executor registered for tool "${task.toolName}". Register the tool on Mastra (so workers can resolve it cross-process) or run the task in the same process as the producer.` };
|
|
74
|
+
await storage.updateTask(taskId, {
|
|
75
|
+
status: "failed",
|
|
76
|
+
error: errorInfo,
|
|
77
|
+
completedAt: /* @__PURE__ */ new Date
|
|
78
|
+
});
|
|
79
|
+
const failedTask = await storage.getTask(taskId);
|
|
80
|
+
if (failedTask) {
|
|
81
|
+
await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo });
|
|
82
|
+
await manager.publishLifecycleEvent("task.failed", failedTask);
|
|
83
|
+
}
|
|
84
|
+
manager.deregisterTaskContext(taskId);
|
|
85
|
+
throw new Error(errorInfo.message);
|
|
86
|
+
}
|
|
87
|
+
const progressThrottleMs = manager.config.progressThrottleMs;
|
|
88
|
+
const shouldThrottleProgress = typeof progressThrottleMs === "number" && Number.isFinite(progressThrottleMs) && progressThrottleMs > 0;
|
|
89
|
+
let lastProgressEmitMs;
|
|
90
|
+
const onProgress = async (chunk) => {
|
|
91
|
+
if (shouldThrottleProgress) {
|
|
92
|
+
const now = Date.now();
|
|
93
|
+
if (lastProgressEmitMs !== undefined && now - lastProgressEmitMs < progressThrottleMs)
|
|
94
|
+
return;
|
|
95
|
+
lastProgressEmitMs = now;
|
|
96
|
+
}
|
|
97
|
+
await manager.publishLifecycleEvent("task.output", {
|
|
98
|
+
...task,
|
|
99
|
+
chunk
|
|
100
|
+
});
|
|
101
|
+
};
|
|
102
|
+
const abortController = new AbortController;
|
|
103
|
+
if (!manager.registerActiveAbortController(taskId, abortController)) {
|
|
104
|
+
manager.deregisterTaskContext(taskId);
|
|
105
|
+
return {
|
|
106
|
+
taskId,
|
|
107
|
+
outcome: "cancelled"
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const onWorkflowAbort = () => abortController.abort(/* @__PURE__ */ new Error("Task cancelled"));
|
|
111
|
+
if (workflowAbortSignal.aborted)
|
|
112
|
+
abortController.abort(/* @__PURE__ */ new Error("Task cancelled"));
|
|
113
|
+
else
|
|
114
|
+
workflowAbortSignal.addEventListener("abort", onWorkflowAbort, { once: true });
|
|
115
|
+
const timeoutHandle = setTimeout(() => {
|
|
116
|
+
abortController.abort(/* @__PURE__ */ new Error(`Task timed out after ${task.timeoutMs}ms`));
|
|
117
|
+
}, task.timeoutMs);
|
|
118
|
+
let pendingSuspend;
|
|
119
|
+
const wrappedSuspend = async (data, suspendOptions) => {
|
|
120
|
+
await storage.updateTask(taskId, {
|
|
121
|
+
status: "suspended",
|
|
122
|
+
suspendPayload: data,
|
|
123
|
+
suspendedAt: /* @__PURE__ */ new Date
|
|
124
|
+
});
|
|
125
|
+
const suspendedTask = await storage.getTask(taskId);
|
|
126
|
+
if (suspendedTask) {
|
|
127
|
+
await manager.runLocalSuspendHooks(suspendedTask);
|
|
128
|
+
await manager.publishLifecycleEvent("task.suspended", suspendedTask);
|
|
129
|
+
}
|
|
130
|
+
pendingSuspend = {
|
|
131
|
+
data,
|
|
132
|
+
suspendOptions
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
try {
|
|
136
|
+
const args = { ...task.args };
|
|
137
|
+
delete args.suspendedToolRunId;
|
|
138
|
+
const suspendedToolRunId = resolveSuspendedToolRunId(suspendData?.suspendedToolRunId);
|
|
139
|
+
if (resumeData !== undefined && suspendedToolRunId)
|
|
140
|
+
args.suspendedToolRunId = suspendedToolRunId;
|
|
141
|
+
const result = await executor.execute(args, {
|
|
142
|
+
abortSignal: abortController.signal,
|
|
143
|
+
onProgress,
|
|
144
|
+
suspend: wrappedSuspend,
|
|
145
|
+
resumeData,
|
|
146
|
+
suspendedToolRunId: resumeData !== undefined ? suspendedToolRunId : undefined
|
|
147
|
+
});
|
|
148
|
+
if (pendingSuspend) {
|
|
149
|
+
const opts = pendingSuspend.suspendOptions;
|
|
150
|
+
const agentRunId = opts?.isAgentSuspend && typeof opts.runId === "string" ? opts.runId : undefined;
|
|
151
|
+
return suspend(!agentRunId ? pendingSuspend.data : pendingSuspend.data && typeof pendingSuspend.data === "object" ? {
|
|
152
|
+
...pendingSuspend.data,
|
|
153
|
+
suspendedToolRunId: agentRunId
|
|
154
|
+
} : { suspendedToolRunId: agentRunId }, opts);
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
taskId,
|
|
158
|
+
outcome: "success",
|
|
159
|
+
result
|
|
160
|
+
};
|
|
161
|
+
} catch (error) {
|
|
162
|
+
const currentTask = await storage.getTask(taskId);
|
|
163
|
+
if (!currentTask || currentTask.status === "cancelled") {
|
|
164
|
+
manager.deregisterTaskContext(taskId);
|
|
165
|
+
return {
|
|
166
|
+
taskId,
|
|
167
|
+
outcome: "cancelled"
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (manager.isShuttingDown()) {
|
|
171
|
+
manager.deregisterTaskContext(taskId);
|
|
172
|
+
return {
|
|
173
|
+
taskId,
|
|
174
|
+
outcome: "cancelled"
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
if (abortController.signal.aborted || error?.name === "AbortError" || error?.message === "Task cancelled" || error?.message?.startsWith("Task timed out after "))
|
|
178
|
+
return {
|
|
179
|
+
taskId,
|
|
180
|
+
outcome: "timed_out"
|
|
181
|
+
};
|
|
182
|
+
if (error?.name === "FGADeniedError")
|
|
183
|
+
return {
|
|
184
|
+
taskId,
|
|
185
|
+
outcome: "failed",
|
|
186
|
+
error: {
|
|
187
|
+
name: error.name,
|
|
188
|
+
message: error?.message ?? "Authorization denied",
|
|
189
|
+
stack: error?.stack
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
return {
|
|
193
|
+
taskId,
|
|
194
|
+
outcome: "retry",
|
|
195
|
+
error: {
|
|
196
|
+
message: error?.message ?? "Unknown error",
|
|
197
|
+
stack: error?.stack
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
} finally {
|
|
201
|
+
clearTimeout(timeoutHandle);
|
|
202
|
+
workflowAbortSignal.removeEventListener("abort", onWorkflowAbort);
|
|
203
|
+
manager.activeAbortControllers.delete(taskId);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
const classifyOutcomeStep = createStep$1({
|
|
208
|
+
id: "classify-outcome",
|
|
209
|
+
inputSchema: attemptOutputSchema,
|
|
210
|
+
outputSchema: bodyOutputSchema,
|
|
211
|
+
execute: async ({ inputData }) => {
|
|
212
|
+
const { taskId, outcome, result, error } = inputData;
|
|
213
|
+
const storage = await manager.getStorage();
|
|
214
|
+
const task = await storage.getTask(taskId);
|
|
215
|
+
if (!task)
|
|
216
|
+
return {
|
|
217
|
+
taskId,
|
|
218
|
+
done: true
|
|
219
|
+
};
|
|
220
|
+
if (outcome === "cancelled") {
|
|
221
|
+
manager.deregisterTaskContext(taskId);
|
|
222
|
+
return {
|
|
223
|
+
taskId,
|
|
224
|
+
done: true
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
if (outcome === "timed_out") {
|
|
228
|
+
const status = task.status;
|
|
229
|
+
if (status !== "timed_out" && status !== "cancelled") {
|
|
230
|
+
await storage.updateTask(taskId, {
|
|
231
|
+
status: "timed_out",
|
|
232
|
+
error: { message: `Task timed out after ${task.timeoutMs}ms` },
|
|
233
|
+
completedAt: /* @__PURE__ */ new Date
|
|
234
|
+
});
|
|
235
|
+
const timedOutTask = await storage.getTask(taskId);
|
|
236
|
+
if (timedOutTask)
|
|
237
|
+
await manager.publishLifecycleEvent("task.failed", timedOutTask);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
taskId,
|
|
241
|
+
done: true
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
if (outcome === "success") {
|
|
245
|
+
if (task.status === "cancelled") {
|
|
246
|
+
manager.deregisterTaskContext(taskId);
|
|
247
|
+
return {
|
|
248
|
+
taskId,
|
|
249
|
+
done: true
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
await storage.updateTask(taskId, {
|
|
253
|
+
status: "completed",
|
|
254
|
+
result,
|
|
255
|
+
completedAt: /* @__PURE__ */ new Date
|
|
256
|
+
});
|
|
257
|
+
const completedTask = await storage.getTask(taskId);
|
|
258
|
+
if (completedTask) {
|
|
259
|
+
await manager.runLocalCompletionHooks(completedTask, "completed", { result });
|
|
260
|
+
await manager.publishLifecycleEvent("task.completed", completedTask);
|
|
261
|
+
}
|
|
262
|
+
return {
|
|
263
|
+
taskId,
|
|
264
|
+
done: true,
|
|
265
|
+
result
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (outcome === "retry" && task.retryCount < task.maxRetries) {
|
|
269
|
+
await storage.updateTask(taskId, {
|
|
270
|
+
retryCount: task.retryCount + 1,
|
|
271
|
+
error: undefined,
|
|
272
|
+
startedAt: /* @__PURE__ */ new Date
|
|
273
|
+
});
|
|
274
|
+
return {
|
|
275
|
+
taskId,
|
|
276
|
+
done: false
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
const errorInfo = error ?? { message: "Unknown error" };
|
|
280
|
+
await storage.updateTask(taskId, {
|
|
281
|
+
status: "failed",
|
|
282
|
+
error: errorInfo,
|
|
283
|
+
completedAt: /* @__PURE__ */ new Date
|
|
284
|
+
});
|
|
285
|
+
const failedTask = await storage.getTask(taskId);
|
|
286
|
+
if (failedTask) {
|
|
287
|
+
await manager.runLocalCompletionHooks(failedTask, "failed", { error: errorInfo });
|
|
288
|
+
await manager.publishLifecycleEvent("task.failed", failedTask);
|
|
289
|
+
}
|
|
290
|
+
const thrown = new Error(errorInfo.message);
|
|
291
|
+
if (errorInfo.name)
|
|
292
|
+
thrown.name = errorInfo.name;
|
|
293
|
+
if (errorInfo.stack)
|
|
294
|
+
thrown.stack = errorInfo.stack;
|
|
295
|
+
throw thrown;
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
const attemptBodyWorkflow = createWorkflow({
|
|
299
|
+
id: `${BACKGROUND_TASK_WORKFLOW_ID}__attempt`,
|
|
300
|
+
inputSchema: bodyIOSchema,
|
|
301
|
+
outputSchema: bodyOutputSchema,
|
|
302
|
+
steps: [runAttemptStep, classifyOutcomeStep],
|
|
303
|
+
options: {
|
|
304
|
+
validateInputs: false,
|
|
305
|
+
shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),
|
|
306
|
+
tracingPolicy: { internal: 1 }
|
|
307
|
+
}
|
|
308
|
+
}).then(runAttemptStep).then(classifyOutcomeStep).commit();
|
|
309
|
+
return createWorkflow({
|
|
310
|
+
id: BACKGROUND_TASK_WORKFLOW_ID,
|
|
311
|
+
inputSchema,
|
|
312
|
+
outputSchema: bodyOutputSchema,
|
|
313
|
+
steps: [attemptBodyWorkflow],
|
|
314
|
+
options: {
|
|
315
|
+
shouldPersistSnapshot: ({ workflowStatus }) => WORKFLOW_STATUS_TO_PERSIST.includes(workflowStatus),
|
|
316
|
+
tracingPolicy: { internal: 1 }
|
|
317
|
+
}
|
|
318
|
+
}).dountil(attemptBodyWorkflow, async ({ inputData }) => inputData?.done === true).commit();
|
|
319
|
+
}
|
|
320
|
+
export {
|
|
321
|
+
buildBackgroundTaskWorkflow
|
|
322
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isLoopback,
|
|
3
|
+
HarnessError
|
|
4
|
+
} from "./chunk-2gt4cy7x.mjs";
|
|
5
|
+
import {
|
|
6
|
+
assertDatabaseRuntime
|
|
7
|
+
} from "./chunk-7bg2gnv2.mjs";
|
|
8
|
+
|
|
9
|
+
// apps/harness/src/config.ts
|
|
10
|
+
function databaseConfig(environment = process.env) {
|
|
11
|
+
assertDatabaseRuntime();
|
|
12
|
+
const profile = environment.HARNESS_DATABASE_PROFILE;
|
|
13
|
+
if (profile !== "local" && profile !== "remote") {
|
|
14
|
+
throw new HarnessError("database_config", "Set HARNESS_DATABASE_PROFILE=local (loopback) or remote (explicit opt-in, TLS required).");
|
|
15
|
+
}
|
|
16
|
+
const connectionString = environment.HARNESS_DATABASE_URL;
|
|
17
|
+
if (!connectionString)
|
|
18
|
+
throw new HarnessError("database_config", "An explicit HARNESS_DATABASE_URL is required; DATABASE_URL is never used as a fallback.");
|
|
19
|
+
let endpoint;
|
|
20
|
+
try {
|
|
21
|
+
endpoint = new URL(connectionString);
|
|
22
|
+
} catch {
|
|
23
|
+
throw new HarnessError("database_config", "The database URL is invalid.");
|
|
24
|
+
}
|
|
25
|
+
if (!["postgres:", "postgresql:"].includes(endpoint.protocol) || endpoint.search || endpoint.hash || endpoint.pathname.length < 2) {
|
|
26
|
+
throw new HarnessError("database_config", "Use an explicit PostgreSQL database URL without query or fragment overrides.");
|
|
27
|
+
}
|
|
28
|
+
const loopback = isLoopback(endpoint.hostname);
|
|
29
|
+
if (profile === "local") {
|
|
30
|
+
if (!loopback) {
|
|
31
|
+
throw new HarnessError("database_config", "The local profile requires a loopback address, 127.0.0.1 or [::1]. Use HARNESS_DATABASE_PROFILE=remote for a non-loopback database.");
|
|
32
|
+
}
|
|
33
|
+
return { connectionString, ssl: false };
|
|
34
|
+
}
|
|
35
|
+
if (loopback) {
|
|
36
|
+
throw new HarnessError("database_config", "The remote profile is for non-loopback databases. Use HARNESS_DATABASE_PROFILE=local for loopback.");
|
|
37
|
+
}
|
|
38
|
+
return { connectionString, ssl: true };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { databaseConfig };
|