@mettlelabs/mettle 0.0.0-beta.1 → 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.
Files changed (60) hide show
  1. package/THIRD_PARTY_NOTICES.md +11479 -0
  2. package/bin/mettle +4 -0
  3. package/harness/audit-investigation.mjs +203 -0
  4. package/harness/chunk-13tgmdey.mjs +33761 -0
  5. package/harness/chunk-1sygmp11.mjs +18142 -0
  6. package/harness/chunk-1ykxpmaz.mjs +7887 -0
  7. package/harness/chunk-2gt4cy7x.mjs +2290 -0
  8. package/harness/chunk-2pm2sayw.mjs +248 -0
  9. package/harness/chunk-32y07kkp.mjs +3747 -0
  10. package/harness/chunk-3m7jn5ac.mjs +16242 -0
  11. package/harness/chunk-3wvjs93w.mjs +538 -0
  12. package/harness/chunk-4bepyxmq.mjs +113 -0
  13. package/harness/chunk-4jtnt9k5.mjs +95 -0
  14. package/harness/chunk-50sbrf09.mjs +18972 -0
  15. package/harness/chunk-56csr8sw.mjs +322 -0
  16. package/harness/chunk-5cvb1jnb.mjs +41 -0
  17. package/harness/chunk-5wgmv4np.mjs +585 -0
  18. package/harness/chunk-65eyq32y.mjs +225 -0
  19. package/harness/chunk-6fnh6qhk.mjs +195 -0
  20. package/harness/chunk-6kgqw9ny.mjs +32303 -0
  21. package/harness/chunk-7b242j0n.mjs +14 -0
  22. package/harness/chunk-7bg2gnv2.mjs +7540 -0
  23. package/harness/chunk-ageqxj9v.mjs +63008 -0
  24. package/harness/chunk-b0qbt5jd.mjs +14 -0
  25. package/harness/chunk-b5g1r3fz.mjs +4785 -0
  26. package/harness/chunk-b71gpkxg.mjs +1514 -0
  27. package/harness/chunk-bdv1rx4a.mjs +20364 -0
  28. package/harness/chunk-c1631s2x.mjs +12241 -0
  29. package/harness/chunk-d5xgxsnp.mjs +74 -0
  30. package/harness/chunk-erg1fbh0.mjs +0 -0
  31. package/harness/chunk-fh78v9vn.mjs +19366 -0
  32. package/harness/chunk-fjx29qvp.mjs +50 -0
  33. package/harness/chunk-gryka6kg.mjs +39 -0
  34. package/harness/chunk-jb0r19et.mjs +180 -0
  35. package/harness/chunk-mfn574ss.mjs +179 -0
  36. package/harness/chunk-msg872ea.mjs +334 -0
  37. package/harness/chunk-nz5sv9as.mjs +1642 -0
  38. package/harness/chunk-p9d3cgvq.mjs +452 -0
  39. package/harness/chunk-pq6wvwxr.mjs +12 -0
  40. package/harness/chunk-qcm9arf8.mjs +7736 -0
  41. package/harness/chunk-qr8zfqjd.mjs +24 -0
  42. package/harness/chunk-rz2tz6jp.mjs +26 -0
  43. package/harness/chunk-sbkgc3kn.mjs +8 -0
  44. package/harness/chunk-v66qvpnb.mjs +169 -0
  45. package/harness/chunk-vjaxzab3.mjs +136 -0
  46. package/harness/chunk-vr1n5nza.mjs +1045 -0
  47. package/harness/chunk-vsf2zajv.mjs +3867 -0
  48. package/harness/chunk-wq253fj4.mjs +19041 -0
  49. package/harness/chunk-wyv7ceq4.mjs +0 -0
  50. package/harness/chunk-xnqknk2r.mjs +198 -0
  51. package/harness/chunk-xqyc4ca2.mjs +1890 -0
  52. package/harness/chunk-z6n9thea.mjs +45146 -0
  53. package/harness/chunk-zty0d3bw.mjs +0 -0
  54. package/harness/chunk-zvkxtj82.mjs +42 -0
  55. package/harness/issue-api-token.mjs +35 -0
  56. package/harness/launcher.mjs +159 -0
  57. package/harness/sandbox.mjs +132 -0
  58. package/harness/server.mjs +66322 -0
  59. package/package.json +13 -15
  60. package/bin/mettle.js +0 -51
@@ -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 };