@elizaos/cli 1.4.3 → 1.4.5

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 (70) hide show
  1. package/dist/BrowserWebSocketTransport-5YQPVDV7.js +7 -0
  2. package/dist/EnhancedEvaluationEngine-APOQ6INN.js +473 -0
  3. package/dist/EvaluationEngine-Y7ZQJBRC.js +9 -0
  4. package/dist/LocalEnvironmentProvider-JWFGG4IN.js +15 -0
  5. package/dist/NodeWebSocketTransport-PUO724EY.js +8 -0
  6. package/dist/ScreenRecorder-YK246DNJ.js +10 -0
  7. package/dist/agent-start-6QJQAMKA.js +13 -0
  8. package/dist/bidi-2SVNH6F7.js +15309 -0
  9. package/dist/{bun-exec-ULMPAIQC.js → bun-exec-NH4UCUY4.js} +1 -1
  10. package/dist/chunk-2ESYSVXG.js +48 -0
  11. package/dist/chunk-3AEYIKBZ.js +432 -0
  12. package/dist/chunk-5IWKEMEF.js +239 -0
  13. package/dist/chunk-5WZO2HMM.js +2644 -0
  14. package/dist/chunk-ABGBVB74.js +3501 -0
  15. package/dist/{chunk-NSNXXD3I.js → chunk-BCO32GR6.js} +2 -2
  16. package/dist/chunk-CGXTFHQP.js +25 -0
  17. package/dist/chunk-EXUFDTUD.js +3948 -0
  18. package/dist/chunk-FGGNHEXZ.js +211860 -0
  19. package/dist/chunk-FWYHSCLF.js +243 -0
  20. package/dist/chunk-I57T3WPO.js +165 -0
  21. package/dist/chunk-LBZLMFFF.js +221 -0
  22. package/dist/chunk-LG7YDBMV.js +401 -0
  23. package/dist/chunk-NHKLUXNE.js +166 -0
  24. package/dist/chunk-PUZHCSGF.js +828 -0
  25. package/dist/chunk-PWDR7CPA.js +7828 -0
  26. package/dist/{chunk-N5G5XSGP.js → chunk-Q6M2K53X.js} +3 -3
  27. package/dist/chunk-SVHCNBHM.js +289 -0
  28. package/dist/{chunk-HOC6B3QV.js → chunk-VFFOOPYS.js} +4 -238
  29. package/dist/chunk-WX37MM4G.js +292 -0
  30. package/dist/chunk-XFJIHUT3.js +6 -0
  31. package/dist/chunk-XPPESCCM.js +787 -0
  32. package/dist/chunk-YBDC5OZO.js +40 -0
  33. package/dist/commands/agent/actions/index.js +2 -2
  34. package/dist/commands/agent/index.js +2 -2
  35. package/dist/commands/create/actions/index.js +4 -3
  36. package/dist/commands/create/index.js +5 -4
  37. package/dist/commands/shared/index.js +1 -1
  38. package/dist/index.js +66820 -5009
  39. package/dist/js-yaml-KADNMPWR.js +35 -0
  40. package/dist/matrix-orchestrator-3WLRK7GG.js +1070 -0
  41. package/dist/matrix-runner-KDPETCKQ.js +160 -0
  42. package/dist/matrix-schema-PCO2KGJY.js +102 -0
  43. package/dist/parameter-override-ALOPPXCE.js +487 -0
  44. package/dist/{plugin-creator-TCUFII32.js → plugin-creator-J7GNPMPG.js} +1 -1
  45. package/dist/process-manager-IU2A3BTQ.js +9 -0
  46. package/dist/{registry-ELONUC44.js → registry-65KMEA7N.js} +2 -2
  47. package/dist/resource-monitor-EHZSH2P6.js +15 -0
  48. package/dist/run-isolation-PGLZ37Y7.js +29 -0
  49. package/dist/runtime-factory-Q4U5YBNV.js +22 -0
  50. package/dist/schema-C25LVPEK.js +17 -0
  51. package/dist/src/commands/report/src/assets/report_template.html +1704 -0
  52. package/dist/src-EJG4ILDC.js +5 -0
  53. package/dist/templates/plugin-quick-starter/package.json +2 -2
  54. package/dist/templates/plugin-quick-starter/src/__tests__/test-utils.ts +1 -0
  55. package/dist/templates/plugin-starter/package.json +2 -2
  56. package/dist/templates/plugin-starter/src/__tests__/test-utils.ts +1 -0
  57. package/dist/templates/project-starter/package.json +4 -4
  58. package/dist/templates/project-tee-starter/package.json +4 -4
  59. package/dist/templates/project-tee-starter/src/index.ts +1 -2
  60. package/dist/typescript-ZF3IK2DJ.js +5 -0
  61. package/dist/{utils-X6UXPLKD.js → utils-QFD2PW4X.js} +2 -2
  62. package/package.json +14 -8
  63. package/templates/plugin-quick-starter/package.json +2 -2
  64. package/templates/plugin-quick-starter/src/__tests__/test-utils.ts +1 -0
  65. package/templates/plugin-starter/package.json +2 -2
  66. package/templates/plugin-starter/src/__tests__/test-utils.ts +1 -0
  67. package/templates/project-starter/package.json +4 -4
  68. package/templates/project-tee-starter/package.json +4 -4
  69. package/templates/project-tee-starter/src/index.ts +1 -2
  70. package/dist/chunk-3RG5ZIWI.js +0 -10
@@ -0,0 +1,243 @@
1
+ import {
2
+ require_src
3
+ } from "./chunk-XPPESCCM.js";
4
+ import {
5
+ CDPSessionEvent,
6
+ asyncDisposeSymbol,
7
+ bufferCount,
8
+ concatMap,
9
+ debugError,
10
+ filter,
11
+ from,
12
+ fromEmitterEvent,
13
+ fromEvent,
14
+ guarded,
15
+ lastValueFrom,
16
+ map,
17
+ takeUntil,
18
+ tap
19
+ } from "./chunk-ABGBVB74.js";
20
+ import {
21
+ __toESM
22
+ } from "./chunk-2ESYSVXG.js";
23
+
24
+ // ../../node_modules/puppeteer-core/lib/esm/puppeteer/node/ScreenRecorder.js
25
+ var import_debug = __toESM(require_src(), 1);
26
+ import { spawn, spawnSync } from "child_process";
27
+ import { PassThrough } from "stream";
28
+ var __runInitializers = function(thisArg, initializers, value) {
29
+ var useValue = arguments.length > 2;
30
+ for (var i = 0; i < initializers.length; i++) {
31
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
32
+ }
33
+ return useValue ? value : void 0;
34
+ };
35
+ var __esDecorate = function(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
36
+ function accept(f) {
37
+ if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected");
38
+ return f;
39
+ }
40
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
41
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
42
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
43
+ var _, done = false;
44
+ for (var i = decorators.length - 1; i >= 0; i--) {
45
+ var context = {};
46
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
47
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
48
+ context.addInitializer = function(f) {
49
+ if (done) throw new TypeError("Cannot add initializers after decoration has completed");
50
+ extraInitializers.push(accept(f || null));
51
+ };
52
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
53
+ if (kind === "accessor") {
54
+ if (result === void 0) continue;
55
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
56
+ if (_ = accept(result.get)) descriptor.get = _;
57
+ if (_ = accept(result.set)) descriptor.set = _;
58
+ if (_ = accept(result.init)) initializers.unshift(_);
59
+ } else if (_ = accept(result)) {
60
+ if (kind === "field") initializers.unshift(_);
61
+ else descriptor[key] = _;
62
+ }
63
+ }
64
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
65
+ done = true;
66
+ };
67
+ var __setFunctionName = function(f, name, prefix) {
68
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
69
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
70
+ };
71
+ var CRF_VALUE = 30;
72
+ var DEFAULT_FPS = 30;
73
+ var debugFfmpeg = (0, import_debug.default)("puppeteer:ffmpeg");
74
+ var ScreenRecorder = (() => {
75
+ let _classSuper = PassThrough;
76
+ let _instanceExtraInitializers = [];
77
+ let _private_writeFrame_decorators;
78
+ let _private_writeFrame_descriptor;
79
+ let _stop_decorators;
80
+ return class ScreenRecorder extends _classSuper {
81
+ static {
82
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
83
+ __esDecorate(this, _private_writeFrame_descriptor = { value: __setFunctionName(async function(buffer) {
84
+ const error = await new Promise((resolve) => {
85
+ this.#process.stdin.write(buffer, resolve);
86
+ });
87
+ if (error) {
88
+ console.log(`ffmpeg failed to write: ${error.message}.`);
89
+ }
90
+ }, "#writeFrame") }, _private_writeFrame_decorators, { kind: "method", name: "#writeFrame", static: false, private: true, access: { has: (obj) => #writeFrame in obj, get: (obj) => obj.#writeFrame }, metadata: _metadata }, null, _instanceExtraInitializers);
91
+ __esDecorate(this, null, _stop_decorators, { kind: "method", name: "stop", static: false, private: false, access: { has: (obj) => "stop" in obj, get: (obj) => obj.stop }, metadata: _metadata }, null, _instanceExtraInitializers);
92
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
93
+ }
94
+ #page = __runInitializers(this, _instanceExtraInitializers);
95
+ #process;
96
+ #controller = new AbortController();
97
+ #lastFrame;
98
+ /**
99
+ * @internal
100
+ */
101
+ constructor(page, width, height, { speed, scale, crop, format, path } = {}) {
102
+ super({ allowHalfOpen: false });
103
+ path ??= "ffmpeg";
104
+ const { error } = spawnSync(path);
105
+ if (error) {
106
+ throw error;
107
+ }
108
+ this.#process = spawn(
109
+ path,
110
+ // See https://trac.ffmpeg.org/wiki/Encode/VP9 for more information on flags.
111
+ [
112
+ ["-loglevel", "error"],
113
+ // Reduces general buffering.
114
+ ["-avioflags", "direct"],
115
+ // Reduces initial buffering while analyzing input fps and other stats.
116
+ [
117
+ "-fpsprobesize",
118
+ "0",
119
+ "-probesize",
120
+ "32",
121
+ "-analyzeduration",
122
+ "0",
123
+ "-fflags",
124
+ "nobuffer"
125
+ ],
126
+ // Forces input to be read from standard input, and forces png input
127
+ // image format.
128
+ ["-f", "image2pipe", "-c:v", "png", "-i", "pipe:0"],
129
+ // Overwrite output and no audio.
130
+ ["-y", "-an"],
131
+ // This drastically reduces stalling when cpu is overbooked. By default
132
+ // VP9 tries to use all available threads?
133
+ ["-threads", "1"],
134
+ // Specifies the frame rate we are giving ffmpeg.
135
+ ["-framerate", `${DEFAULT_FPS}`],
136
+ // Specifies the encoding and format we are using.
137
+ this.#getFormatArgs(format ?? "webm"),
138
+ // Disable bitrate.
139
+ ["-b:v", "0"],
140
+ // Filters to ensure the images are piped correctly.
141
+ [
142
+ "-vf",
143
+ `${speed ? `setpts=${1 / speed}*PTS,` : ""}crop='min(${width},iw):min(${height},ih):0:0',pad=${width}:${height}:0:0${crop ? `,crop=${crop.width}:${crop.height}:${crop.x}:${crop.y}` : ""}${scale ? `,scale=iw*${scale}:-1` : ""}`
144
+ ],
145
+ "pipe:1"
146
+ ].flat(),
147
+ { stdio: ["pipe", "pipe", "pipe"] }
148
+ );
149
+ this.#process.stdout.pipe(this);
150
+ this.#process.stderr.on("data", (data) => {
151
+ debugFfmpeg(data.toString("utf8"));
152
+ });
153
+ this.#page = page;
154
+ const { client } = this.#page.mainFrame();
155
+ client.once(CDPSessionEvent.Disconnected, () => {
156
+ void this.stop().catch(debugError);
157
+ });
158
+ this.#lastFrame = lastValueFrom(fromEmitterEvent(client, "Page.screencastFrame").pipe(tap((event) => {
159
+ void client.send("Page.screencastFrameAck", {
160
+ sessionId: event.sessionId
161
+ });
162
+ }), filter((event) => {
163
+ return event.metadata.timestamp !== void 0;
164
+ }), map((event) => {
165
+ return {
166
+ buffer: Buffer.from(event.data, "base64"),
167
+ timestamp: event.metadata.timestamp
168
+ };
169
+ }), bufferCount(2, 1), concatMap(([{ timestamp: previousTimestamp, buffer }, { timestamp }]) => {
170
+ return from(Array(Math.round(DEFAULT_FPS * Math.max(timestamp - previousTimestamp, 0))).fill(buffer));
171
+ }), map((buffer) => {
172
+ void this.#writeFrame(buffer);
173
+ return [buffer, performance.now()];
174
+ }), takeUntil(fromEvent(this.#controller.signal, "abort"))), { defaultValue: [Buffer.from([]), performance.now()] });
175
+ }
176
+ #getFormatArgs(format) {
177
+ switch (format) {
178
+ case "webm":
179
+ return [
180
+ // Sets the codec to use.
181
+ ["-c:v", "vp9"],
182
+ // Sets the format
183
+ ["-f", "webm"],
184
+ // Sets the quality. Lower the better.
185
+ ["-crf", `${CRF_VALUE}`],
186
+ // Sets the quality and how efficient the compression will be.
187
+ ["-deadline", "realtime", "-cpu-used", "8"]
188
+ ].flat();
189
+ case "gif":
190
+ return [
191
+ // Sets the frame rate and uses a custom palette generated from the
192
+ // input.
193
+ [
194
+ "-vf",
195
+ "fps=5,split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse"
196
+ ],
197
+ // Sets the format
198
+ ["-f", "gif"]
199
+ ].flat();
200
+ }
201
+ }
202
+ get #writeFrame() {
203
+ return _private_writeFrame_descriptor.value;
204
+ }
205
+ /**
206
+ * Stops the recorder.
207
+ *
208
+ * @public
209
+ */
210
+ async stop() {
211
+ if (this.#controller.signal.aborted) {
212
+ return;
213
+ }
214
+ await this.#page._stopScreencast().catch(debugError);
215
+ this.#controller.abort();
216
+ const [buffer, timestamp] = await this.#lastFrame;
217
+ await Promise.all(Array(Math.max(1, Math.round(DEFAULT_FPS * (performance.now() - timestamp) / 1e3))).fill(buffer).map(this.#writeFrame.bind(this)));
218
+ this.#process.stdin.end();
219
+ await new Promise((resolve) => {
220
+ this.#process.once("close", resolve);
221
+ });
222
+ }
223
+ /**
224
+ * @internal
225
+ */
226
+ async [(_private_writeFrame_decorators = [guarded()], _stop_decorators = [guarded()], asyncDisposeSymbol)]() {
227
+ await this.stop();
228
+ }
229
+ };
230
+ })();
231
+
232
+ export {
233
+ ScreenRecorder
234
+ };
235
+ /*! Bundled license information:
236
+
237
+ puppeteer-core/lib/esm/puppeteer/node/ScreenRecorder.js:
238
+ (**
239
+ * @license
240
+ * Copyright 2023 Google Inc.
241
+ * SPDX-License-Identifier: Apache-2.0
242
+ *)
243
+ */
@@ -0,0 +1,165 @@
1
+ // src/commands/scenario/src/process-manager.ts
2
+ var ProcessManager = class {
3
+ processes = /* @__PURE__ */ new Map();
4
+ signalHandlersRegistered = false;
5
+ /**
6
+ * Register a process for tracking
7
+ */
8
+ registerProcess(runId, pid, type, port) {
9
+ console.log(
10
+ `\u{1F527} [ProcessManager] Registering process ${pid} for runId: ${runId} (type: ${type})`
11
+ );
12
+ this.processes.set(runId, {
13
+ pid,
14
+ runId,
15
+ type,
16
+ startTime: /* @__PURE__ */ new Date(),
17
+ port
18
+ });
19
+ if (!this.signalHandlersRegistered) {
20
+ this.registerSignalHandlers();
21
+ this.signalHandlersRegistered = true;
22
+ }
23
+ }
24
+ /**
25
+ * Unregister a process when it completes normally
26
+ */
27
+ unregisterProcess(runId) {
28
+ const processInfo = this.processes.get(runId);
29
+ if (processInfo) {
30
+ console.log(
31
+ `\u{1F527} [ProcessManager] Unregistering process ${processInfo.pid} for runId: ${runId}`
32
+ );
33
+ this.processes.delete(runId);
34
+ }
35
+ }
36
+ /**
37
+ * Get all registered processes
38
+ */
39
+ getProcesses() {
40
+ return new Map(this.processes);
41
+ }
42
+ /**
43
+ * Check if a process is still running
44
+ */
45
+ isProcessRunning(pid) {
46
+ try {
47
+ process.kill(pid, 0);
48
+ return true;
49
+ } catch (error) {
50
+ return false;
51
+ }
52
+ }
53
+ /**
54
+ * Gracefully terminate a specific process
55
+ */
56
+ async terminateProcess(runId, timeout = 5e3) {
57
+ const processInfo = this.processes.get(runId);
58
+ if (!processInfo) {
59
+ console.log(`\u{1F527} [ProcessManager] No process found for runId: ${runId}`);
60
+ return true;
61
+ }
62
+ const { pid } = processInfo;
63
+ console.log(`\u{1F527} [ProcessManager] Terminating process ${pid} for runId: ${runId}`);
64
+ if (!this.isProcessRunning(pid)) {
65
+ console.log(`\u{1F527} [ProcessManager] Process ${pid} already terminated`);
66
+ this.unregisterProcess(runId);
67
+ return true;
68
+ }
69
+ try {
70
+ process.kill(pid, "SIGTERM");
71
+ const startTime = Date.now();
72
+ while (Date.now() - startTime < timeout) {
73
+ if (!this.isProcessRunning(pid)) {
74
+ console.log(`\u{1F527} [ProcessManager] Process ${pid} terminated gracefully`);
75
+ this.unregisterProcess(runId);
76
+ return true;
77
+ }
78
+ await new Promise((resolve) => setTimeout(resolve, 100));
79
+ }
80
+ console.log(`\u{1F527} [ProcessManager] Force killing process ${pid} after timeout`);
81
+ process.kill(pid, "SIGKILL");
82
+ this.unregisterProcess(runId);
83
+ return true;
84
+ } catch (error) {
85
+ console.log(`\u{1F527} [ProcessManager] Failed to terminate process ${pid}:`, error);
86
+ return false;
87
+ }
88
+ }
89
+ /**
90
+ * Terminate all registered processes
91
+ */
92
+ async terminateAllProcesses(timeout = 1e4) {
93
+ const processes = Array.from(this.processes.keys());
94
+ console.log(`\u{1F527} [ProcessManager] Terminating ${processes.length} processes`);
95
+ if (processes.length === 0) {
96
+ return;
97
+ }
98
+ const terminationPromises = processes.map(
99
+ (runId) => this.terminateProcess(runId, timeout / processes.length)
100
+ );
101
+ await Promise.allSettled(terminationPromises);
102
+ for (const [runId, processInfo] of this.processes.entries()) {
103
+ if (this.isProcessRunning(processInfo.pid)) {
104
+ console.log(`\u{1F527} [ProcessManager] Force killing remaining process ${processInfo.pid}`);
105
+ try {
106
+ process.kill(processInfo.pid, "SIGKILL");
107
+ } catch (error) {
108
+ console.log(`\u{1F527} [ProcessManager] Failed to force kill ${processInfo.pid}:`, error);
109
+ }
110
+ }
111
+ }
112
+ this.processes.clear();
113
+ }
114
+ /**
115
+ * Register signal handlers to cleanup on exit
116
+ */
117
+ registerSignalHandlers() {
118
+ console.log(`\u{1F527} [ProcessManager] Registering signal handlers`);
119
+ const handleExit = async (signal) => {
120
+ console.log(`\u{1F527} [ProcessManager] Received ${signal}, cleaning up processes...`);
121
+ await this.terminateAllProcesses();
122
+ console.log(`\u{1F527} [ProcessManager] Process cleanup completed`);
123
+ process.exit(0);
124
+ };
125
+ process.on("SIGINT", () => handleExit("SIGINT"));
126
+ process.on("SIGTERM", () => handleExit("SIGTERM"));
127
+ process.on("SIGUSR1", () => handleExit("SIGUSR1"));
128
+ process.on("SIGUSR2", () => handleExit("SIGUSR2"));
129
+ process.on("uncaughtException", async (error) => {
130
+ console.error(`\u{1F527} [ProcessManager] Uncaught exception:`, error);
131
+ await this.terminateAllProcesses();
132
+ process.exit(1);
133
+ });
134
+ process.on("unhandledRejection", async (reason, promise) => {
135
+ console.error(`\u{1F527} [ProcessManager] Unhandled rejection at:`, promise, "reason:", reason);
136
+ await this.terminateAllProcesses();
137
+ process.exit(1);
138
+ });
139
+ }
140
+ /**
141
+ * Get summary of managed processes
142
+ */
143
+ getSummary() {
144
+ const processes = Array.from(this.processes.values());
145
+ const byType = {};
146
+ let oldestProcess;
147
+ for (const proc of processes) {
148
+ byType[proc.type] = (byType[proc.type] || 0) + 1;
149
+ if (!oldestProcess || proc.startTime < oldestProcess.startTime) {
150
+ oldestProcess = proc;
151
+ }
152
+ }
153
+ return {
154
+ total: processes.length,
155
+ byType,
156
+ oldestProcess
157
+ };
158
+ }
159
+ };
160
+ var processManager = new ProcessManager();
161
+
162
+ export {
163
+ ProcessManager,
164
+ processManager
165
+ };
@@ -0,0 +1,221 @@
1
+ // src/commands/scenario/src/run-isolation.ts
2
+ import { promises as fs } from "fs";
3
+ import { join, dirname } from "path";
4
+ import { tmpdir } from "os";
5
+ var runSequence = 0;
6
+ function resetRunSequence() {
7
+ runSequence = 0;
8
+ }
9
+ function generateRunId() {
10
+ const sequence = String(runSequence++).padStart(3, "0");
11
+ const hash = Math.random().toString(16).substring(2, 10);
12
+ return `run-${sequence}-${hash}`;
13
+ }
14
+ async function createIsolatedEnvironment(runId, outputDir) {
15
+ const tempDir = join(outputDir, "temp", runId);
16
+ await fs.mkdir(tempDir, { recursive: true });
17
+ const dbPath = join(tempDir, "database");
18
+ const logsDir = join(tempDir, "logs");
19
+ const logPath = join(logsDir, "run.log");
20
+ const scenarioPath = join(tempDir, "scenario.yaml");
21
+ await fs.mkdir(dirname(logPath), { recursive: true });
22
+ await fs.mkdir(dbPath, { recursive: true });
23
+ const cleanup = async () => {
24
+ await cleanupIsolatedEnvironment({
25
+ runId,
26
+ tempDir,
27
+ dbPath,
28
+ logPath,
29
+ scenarioPath,
30
+ cleanup: () => Promise.resolve()
31
+ });
32
+ };
33
+ return {
34
+ runId,
35
+ tempDir,
36
+ dbPath,
37
+ logPath,
38
+ scenarioPath,
39
+ cleanup
40
+ };
41
+ }
42
+ async function cleanupIsolatedEnvironment(context) {
43
+ try {
44
+ await fs.rm(context.tempDir, { recursive: true, force: true });
45
+ } catch (error) {
46
+ console.warn(`Warning: Failed to cleanup isolated environment ${context.runId}:`, error);
47
+ }
48
+ }
49
+ async function ensureIsolatedDatabase(dbPath) {
50
+ try {
51
+ await fs.mkdir(dbPath, { recursive: true });
52
+ const dbConfig = {
53
+ type: "pglite",
54
+ path: dbPath,
55
+ isolated: true,
56
+ temporary: true
57
+ };
58
+ const configPath = join(dbPath, "config.json");
59
+ await fs.writeFile(configPath, JSON.stringify(dbConfig, null, 2));
60
+ } catch (error) {
61
+ throw new Error(
62
+ `Failed to setup isolated database: ${error instanceof Error ? error.message : String(error)}`
63
+ );
64
+ }
65
+ }
66
+ async function writeTemporaryScenario(scenarioPath, baseScenario, parameters) {
67
+ try {
68
+ const modifiedScenario = JSON.parse(JSON.stringify(baseScenario));
69
+ for (const [path, value] of Object.entries(parameters)) {
70
+ setNestedProperty(modifiedScenario, path, value);
71
+ }
72
+ await fs.writeFile(scenarioPath, JSON.stringify(modifiedScenario, null, 2));
73
+ } catch (error) {
74
+ throw new Error(
75
+ `Failed to write temporary scenario: ${error instanceof Error ? error.message : String(error)}`
76
+ );
77
+ }
78
+ }
79
+ function setNestedProperty(obj, path, value) {
80
+ const keys = path.split(".");
81
+ let current = obj;
82
+ for (let i = 0; i < keys.length - 1; i++) {
83
+ const key = keys[i];
84
+ const arrayMatch2 = key.match(/^(.+)\[(\d+)\]$/);
85
+ if (arrayMatch2) {
86
+ const [, arrayKey, indexStr] = arrayMatch2;
87
+ const index = parseInt(indexStr, 10);
88
+ if (!current[arrayKey]) {
89
+ current[arrayKey] = [];
90
+ }
91
+ if (!current[arrayKey][index]) {
92
+ current[arrayKey][index] = {};
93
+ }
94
+ current = current[arrayKey][index];
95
+ } else {
96
+ if (!current[key]) {
97
+ current[key] = {};
98
+ }
99
+ current = current[key];
100
+ }
101
+ }
102
+ const finalKey = keys[keys.length - 1];
103
+ const arrayMatch = finalKey.match(/^(.+)\[(\d+)\]$/);
104
+ if (arrayMatch) {
105
+ const [, arrayKey, indexStr] = arrayMatch;
106
+ const index = parseInt(indexStr, 10);
107
+ if (!current[arrayKey]) {
108
+ current[arrayKey] = [];
109
+ }
110
+ current[arrayKey][index] = value;
111
+ } else {
112
+ current[finalKey] = value;
113
+ }
114
+ }
115
+ async function validateIsolationContext(context) {
116
+ try {
117
+ const tempDirExists = await fs.access(context.tempDir).then(() => true).catch(() => false);
118
+ const dbDirExists = await fs.access(context.dbPath).then(() => true).catch(() => false);
119
+ const logDirExists = await fs.access(dirname(context.logPath)).then(() => true).catch(() => false);
120
+ return tempDirExists && dbDirExists && logDirExists;
121
+ } catch {
122
+ return false;
123
+ }
124
+ }
125
+ function createIsolatedEnvironmentVariables(context) {
126
+ const baseEnv = { ...process.env };
127
+ const isolatedEnv = {
128
+ ...baseEnv,
129
+ // Point to isolated database
130
+ DATABASE_URL: `file://${context.dbPath}/database.db`,
131
+ PGLITE_DATABASE_PATH: context.dbPath,
132
+ // Set isolated temp directory
133
+ TMPDIR: context.tempDir,
134
+ TEMP: context.tempDir,
135
+ TMP: context.tempDir,
136
+ // Set log configuration
137
+ LOG_FILE: context.logPath,
138
+ LOG_LEVEL: "debug",
139
+ // Mark as isolated execution
140
+ ELIZA_ISOLATED_RUN: "true",
141
+ ELIZA_RUN_ID: context.runId,
142
+ // Disable any global state or caching
143
+ DISABLE_GLOBAL_CACHE: "true",
144
+ FORCE_ISOLATED_MODE: "true"
145
+ };
146
+ return isolatedEnv;
147
+ }
148
+ function getIsolatedTempDir(prefix = "eliza-matrix") {
149
+ const timestamp = Date.now();
150
+ const random = Math.random().toString(36).substring(2, 8);
151
+ return join(tmpdir(), `${prefix}-${timestamp}-${random}`);
152
+ }
153
+ function estimateRunDiskSpace(baseScenario) {
154
+ const baseSize = 50 * 1024 * 1024;
155
+ const runCount = baseScenario.run?.length || 1;
156
+ const evaluationCount = baseScenario.run?.reduce((sum, run) => sum + (run.evaluations?.length || 0), 0) || 0;
157
+ const complexityMultiplier = 1 + runCount * 0.1 + evaluationCount * 0.05;
158
+ return Math.ceil(baseSize * complexityMultiplier);
159
+ }
160
+ async function checkDiskSpace(outputDir, estimatedSpace) {
161
+ try {
162
+ const stats = await fs.stat(outputDir);
163
+ return true;
164
+ } catch {
165
+ try {
166
+ await fs.mkdir(outputDir, { recursive: true });
167
+ return true;
168
+ } catch {
169
+ return false;
170
+ }
171
+ }
172
+ }
173
+ async function monitorIsolatedResources(context) {
174
+ try {
175
+ let totalSize = 0;
176
+ let fileCount = 0;
177
+ async function calculateSize(dirPath) {
178
+ try {
179
+ const entries = await fs.readdir(dirPath, { withFileTypes: true });
180
+ for (const entry of entries) {
181
+ const fullPath = join(dirPath, entry.name);
182
+ if (entry.isDirectory()) {
183
+ await calculateSize(fullPath);
184
+ } else {
185
+ const stats = await fs.stat(fullPath);
186
+ totalSize += stats.size;
187
+ fileCount++;
188
+ }
189
+ }
190
+ } catch {
191
+ }
192
+ }
193
+ await calculateSize(context.tempDir);
194
+ return {
195
+ diskUsage: totalSize,
196
+ fileCount,
197
+ directorySize: totalSize
198
+ };
199
+ } catch {
200
+ return {
201
+ diskUsage: 0,
202
+ fileCount: 0,
203
+ directorySize: 0
204
+ };
205
+ }
206
+ }
207
+
208
+ export {
209
+ resetRunSequence,
210
+ generateRunId,
211
+ createIsolatedEnvironment,
212
+ cleanupIsolatedEnvironment,
213
+ ensureIsolatedDatabase,
214
+ writeTemporaryScenario,
215
+ validateIsolationContext,
216
+ createIsolatedEnvironmentVariables,
217
+ getIsolatedTempDir,
218
+ estimateRunDiskSpace,
219
+ checkDiskSpace,
220
+ monitorIsolatedResources
221
+ };