loopforge 1.0.0 → 1.3.0

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 (83) hide show
  1. package/dist/autonomous.d.ts +84 -0
  2. package/dist/autonomous.d.ts.map +1 -0
  3. package/dist/autonomous.js +250 -0
  4. package/dist/autonomous.js.map +1 -0
  5. package/dist/backends/ai.d.ts +37 -0
  6. package/dist/backends/ai.d.ts.map +1 -0
  7. package/dist/backends/ai.js +98 -0
  8. package/dist/backends/ai.js.map +1 -0
  9. package/dist/cli.d.ts +1 -1
  10. package/dist/cli.js +68 -6
  11. package/dist/cli.js.map +1 -1
  12. package/dist/engine.d.ts +15 -1
  13. package/dist/engine.d.ts.map +1 -1
  14. package/dist/engine.js +102 -1
  15. package/dist/engine.js.map +1 -1
  16. package/dist/generate-schema.js +56 -4
  17. package/dist/generate-schema.js.map +1 -1
  18. package/dist/index.d.ts +23 -5
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +22 -4
  21. package/dist/index.js.map +1 -1
  22. package/dist/loop-compiler.d.ts +4 -0
  23. package/dist/loop-compiler.d.ts.map +1 -1
  24. package/dist/loop-compiler.js +43 -0
  25. package/dist/loop-compiler.js.map +1 -1
  26. package/dist/mcp/server.d.ts +14 -0
  27. package/dist/mcp/server.d.ts.map +1 -0
  28. package/dist/mcp/server.js +93 -0
  29. package/dist/mcp/server.js.map +1 -0
  30. package/dist/mcp/session.d.ts +57 -0
  31. package/dist/mcp/session.d.ts.map +1 -0
  32. package/dist/mcp/session.js +177 -0
  33. package/dist/mcp/session.js.map +1 -0
  34. package/dist/mcp/tools.d.ts +108 -0
  35. package/dist/mcp/tools.d.ts.map +1 -0
  36. package/dist/mcp/tools.js +191 -0
  37. package/dist/mcp/tools.js.map +1 -0
  38. package/dist/mcp-server.d.ts +12 -0
  39. package/dist/mcp-server.d.ts.map +1 -0
  40. package/dist/mcp-server.js +14 -0
  41. package/dist/mcp-server.js.map +1 -0
  42. package/dist/policy.d.ts +8 -0
  43. package/dist/policy.d.ts.map +1 -1
  44. package/dist/policy.js +7 -0
  45. package/dist/policy.js.map +1 -1
  46. package/dist/protocol.d.ts +89 -1
  47. package/dist/protocol.d.ts.map +1 -1
  48. package/dist/protocol.js +20 -1
  49. package/dist/protocol.js.map +1 -1
  50. package/dist/runtime.d.ts +57 -0
  51. package/dist/runtime.d.ts.map +1 -0
  52. package/dist/runtime.js +414 -0
  53. package/dist/runtime.js.map +1 -0
  54. package/dist/tests/_helpers.d.ts +25 -0
  55. package/dist/tests/_helpers.d.ts.map +1 -0
  56. package/dist/tests/_helpers.js +47 -0
  57. package/dist/tests/_helpers.js.map +1 -0
  58. package/dist/tests/autonomous.test.d.ts +7 -0
  59. package/dist/tests/autonomous.test.d.ts.map +1 -0
  60. package/dist/tests/autonomous.test.js +294 -0
  61. package/dist/tests/autonomous.test.js.map +1 -0
  62. package/dist/tests/generate-schema.test.js +2 -2
  63. package/dist/tests/generate-schema.test.js.map +1 -1
  64. package/dist/tests/mcp.test.d.ts +7 -0
  65. package/dist/tests/mcp.test.d.ts.map +1 -0
  66. package/dist/tests/mcp.test.js +212 -0
  67. package/dist/tests/mcp.test.js.map +1 -0
  68. package/dist/tests/replay.test.js +69 -41
  69. package/dist/tests/replay.test.js.map +1 -1
  70. package/dist/tests/runtime.test.d.ts +7 -0
  71. package/dist/tests/runtime.test.d.ts.map +1 -0
  72. package/dist/tests/runtime.test.js +323 -0
  73. package/dist/tests/runtime.test.js.map +1 -0
  74. package/loop_policy.json +7 -0
  75. package/package.json +9 -3
  76. package/skills/perception/SKILL.md +186 -0
  77. package/skills/prompt-techniques/SKILL.md +52 -0
  78. package/skills/prompt-techniques/references/chain-of-thought.md +207 -0
  79. package/skills/prompt-techniques/references/few-shot.md +174 -0
  80. package/skills/prompt-techniques/references/least-to-most.md +182 -0
  81. package/skills/prompt-techniques/references/step-back.md +160 -0
  82. package/skills/prompt-techniques/references/tree-of-thought.md +191 -0
  83. package/skills/prompt-techniques/references/zero-shot.md +97 -0
@@ -0,0 +1,57 @@
1
+ /** LoopForge — Loop Runtime (v1.2).
2
+ *
3
+ * Event-driven loop driver that wraps the compilation engine with
4
+ * heartbeat monitoring, timeout/stall detection, and graceful shutdown.
5
+ *
6
+ * Primary API:
7
+ * import { run } from 'loopforge';
8
+ * const result = await run({ task: '...', execute: myAgent });
9
+ *
10
+ * Advanced API:
11
+ * const rt = new LoopRuntime(config);
12
+ * rt.on('round:complete', (info) => console.log(info));
13
+ * const result = await rt.start();
14
+ */
15
+ import { EventEmitter } from "node:events";
16
+ import { RuntimeStatus, type RuntimeConfig, type RunResult } from "./protocol.js";
17
+ export declare class LoopRuntime extends EventEmitter {
18
+ private config;
19
+ private engine;
20
+ private _status;
21
+ private currentRound;
22
+ private qualityTrajectory;
23
+ private heartbeatTimer;
24
+ private sigintHandler;
25
+ private sigtermHandler;
26
+ private roundStartTime;
27
+ private lastProgressTime;
28
+ private activeCtx;
29
+ private timedOut;
30
+ constructor(rawConfig: RuntimeConfig);
31
+ get status(): RuntimeStatus;
32
+ getCurrentRound(): number;
33
+ getQualityTrajectory(): number[];
34
+ /** Start the loop. Returns when the loop terminates (task complete,
35
+ * circuit breaker, max rounds, stalled, or manual stop). */
36
+ start(): Promise<RunResult>;
37
+ /** Stop the loop gracefully. Safe to call from any thread/timer. */
38
+ stop(): void;
39
+ private buildCompileRequest;
40
+ private startHeartbeat;
41
+ private heartbeatTick;
42
+ private stopHeartbeat;
43
+ private registerSignalHandlers;
44
+ private unregisterSignalHandlers;
45
+ }
46
+ /** Run a fully autonomous loop. Only `task` and `execute` are required.
47
+ * All other configuration has sensible defaults from `loop_policy.json`.
48
+ *
49
+ * @example
50
+ * const result = await run({
51
+ * task: 'Audit ERC20 token for security vulnerabilities',
52
+ * execute: async (prompt) => await myAgent.call(prompt),
53
+ * });
54
+ * // result: { success, stopReason, roundsCompleted, qualityTrajectory }
55
+ */
56
+ export declare function run(rawConfig: RuntimeConfig): Promise<RunResult>;
57
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAEL,aAAa,EAab,KAAK,aAAa,EAClB,KAAK,SAAS,EAGf,MAAM,eAAe,CAAC;AAoEvB,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,cAAc,CAA6B;IAGnD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,QAAQ,CAAS;gBAEb,SAAS,EAAE,aAAa;IAMpC,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,eAAe,IAAI,MAAM;IAIzB,oBAAoB,IAAI,MAAM,EAAE;IAMhC;iEAC6D;IACvD,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC;IAgNjC,oEAAoE;IACpE,IAAI,IAAI,IAAI;IAWZ,OAAO,CAAC,mBAAmB;IAyC3B,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,aAAa;IA8DrB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,wBAAwB;CAUjC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,GAAG,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,CAGtE"}
@@ -0,0 +1,414 @@
1
+ /** LoopForge — Loop Runtime (v1.2).
2
+ *
3
+ * Event-driven loop driver that wraps the compilation engine with
4
+ * heartbeat monitoring, timeout/stall detection, and graceful shutdown.
5
+ *
6
+ * Primary API:
7
+ * import { run } from 'loopforge';
8
+ * const result = await run({ task: '...', execute: myAgent });
9
+ *
10
+ * Advanced API:
11
+ * const rt = new LoopRuntime(config);
12
+ * rt.on('round:complete', (info) => console.log(info));
13
+ * const result = await rt.start();
14
+ */
15
+ import { EventEmitter } from "node:events";
16
+ import { extractSelfEvaluation, heuristicSelfEvaluation, createEngine, } from "./engine.js";
17
+ import { Mode, RuntimeStatus, makeLoopCompileRequest, makeLoopRoundResult, makeSelfEvaluation, makeVaultConfig, } from "./protocol.js";
18
+ import { getPolicy } from "./policy.js";
19
+ // ═══════════════════════════════════════════════════════════════════════════
20
+ // Helpers
21
+ // ═══════════════════════════════════════════════════════════════════════════
22
+ function autoLoopId(task) {
23
+ let slug = task.toLowerCase().trim().slice(0, 60);
24
+ slug = slug.replace(/[^a-z0-9\s-]/g, "");
25
+ slug = slug.replace(/\s+/g, "-");
26
+ return slug || "unnamed-loop";
27
+ }
28
+ function resolveConfig(raw) {
29
+ const policy = getPolicy();
30
+ const rtPolicy = policy.runtime;
31
+ return {
32
+ task: raw.task,
33
+ execute: raw.execute,
34
+ loopId: raw.loopId || autoLoopId(raw.task),
35
+ goalId: raw.goalId || "",
36
+ maxRounds: raw.maxRounds ?? rtPolicy.max_rounds,
37
+ roundTimeoutMs: raw.roundTimeoutMs ?? rtPolicy.round_timeout_ms,
38
+ heartbeatIntervalMs: raw.heartbeatIntervalMs ?? rtPolicy.heartbeat_interval_ms,
39
+ stallGraceMs: raw.stallGraceMs ?? rtPolicy.stall_grace_ms,
40
+ maxConsecutiveErrors: raw.maxConsecutiveErrors ?? rtPolicy.max_consecutive_errors,
41
+ interactive: raw.interactive ?? false,
42
+ healthCheckInterval: raw.healthCheckInterval ?? policy.summary.health_check_interval,
43
+ planSource: raw.planSource ?? undefined,
44
+ constraintsFromPlan: raw.constraintsFromPlan ?? [],
45
+ domain: raw.domain ?? "",
46
+ onRoundStart: raw.onRoundStart,
47
+ onRoundComplete: raw.onRoundComplete,
48
+ onHeartbeat: raw.onHeartbeat,
49
+ onTimeout: raw.onTimeout,
50
+ onHealthWarning: raw.onHealthWarning,
51
+ };
52
+ }
53
+ // ═══════════════════════════════════════════════════════════════════════════
54
+ // LoopRuntime
55
+ // ═══════════════════════════════════════════════════════════════════════════
56
+ export class LoopRuntime extends EventEmitter {
57
+ config;
58
+ engine;
59
+ _status = RuntimeStatus.IDLE;
60
+ currentRound = 1;
61
+ qualityTrajectory = [];
62
+ heartbeatTimer = null;
63
+ sigintHandler = null;
64
+ sigtermHandler = null;
65
+ // Shared mutable state between the main loop and the heartbeat tick
66
+ roundStartTime = 0;
67
+ lastProgressTime = 0;
68
+ activeCtx = null;
69
+ timedOut = false;
70
+ constructor(rawConfig) {
71
+ super();
72
+ this.config = resolveConfig(rawConfig);
73
+ this.engine = createEngine();
74
+ }
75
+ get status() {
76
+ return this._status;
77
+ }
78
+ getCurrentRound() {
79
+ return this.currentRound;
80
+ }
81
+ getQualityTrajectory() {
82
+ return [...this.qualityTrajectory];
83
+ }
84
+ // ── Lifecycle ──────────────────────────────────────────────────────────
85
+ /** Start the loop. Returns when the loop terminates (task complete,
86
+ * circuit breaker, max rounds, stalled, or manual stop). */
87
+ async start() {
88
+ if (this._status !== RuntimeStatus.IDLE) {
89
+ throw new Error(`Cannot start: runtime is ${this._status}`);
90
+ }
91
+ this._status = RuntimeStatus.RUNNING;
92
+ this.registerSignalHandlers();
93
+ this.startHeartbeat();
94
+ this.emit("start");
95
+ let stopReason = "max_rounds";
96
+ let previousAgentOutput = null;
97
+ let consecutiveErrors = 0;
98
+ for (this.currentRound = 1; this.currentRound <= this.config.maxRounds; this.currentRound++) {
99
+ if (this._status !== RuntimeStatus.RUNNING) {
100
+ stopReason = "stopped";
101
+ break;
102
+ }
103
+ // ── Compile ──────────────────────────────────────────────────
104
+ const lcr = this.buildCompileRequest(previousAgentOutput);
105
+ const compileResult = this.engine.invokeLoopCompile({
106
+ task: this.config.task,
107
+ mode: Mode.LOOP_COMPILE,
108
+ vault_config: makeVaultConfig(),
109
+ feedback: null,
110
+ skill_name: null,
111
+ task_id: null,
112
+ loop_id: lcr.loop_id,
113
+ round: lcr.round,
114
+ goal_id: lcr.goal_id,
115
+ domain: lcr.domain ?? "",
116
+ plan_source: lcr.plan_source ?? null,
117
+ constraints_from_plan: lcr.constraints_from_plan ?? [],
118
+ health_check_interval: lcr.health_check_interval,
119
+ last_round_result: (lcr.last_round_result ?? undefined),
120
+ });
121
+ if (!compileResult.response?.prompt) {
122
+ stopReason = "stalled";
123
+ break;
124
+ }
125
+ const prompt = compileResult.response.prompt;
126
+ const analysis = compileResult.response.analysis;
127
+ const level = analysis?.rationale?.includes("l0")
128
+ ? "l0"
129
+ : analysis?.rationale?.includes("l1")
130
+ ? "l1"
131
+ : "l2";
132
+ const technique = analysis?.technique ?? "unknown";
133
+ // ── Emit round:start ──────────────────────────────────────────
134
+ const startInfo = { round: this.currentRound, level, technique, prompt };
135
+ this.emit("round:start", startInfo);
136
+ this.config.onRoundStart?.(startInfo);
137
+ // ── Execute ───────────────────────────────────────────────────
138
+ this.roundStartTime = Date.now();
139
+ this.lastProgressTime = this.roundStartTime;
140
+ this.timedOut = false;
141
+ const ctx = {
142
+ round: this.currentRound,
143
+ signal: { aborted: false },
144
+ reportProgress: (message) => {
145
+ this.lastProgressTime = Date.now();
146
+ void message; // consumed by heartbeat via lastProgressTime
147
+ },
148
+ };
149
+ this.activeCtx = ctx;
150
+ let agentOutput;
151
+ try {
152
+ agentOutput = await this.config.execute(prompt, ctx);
153
+ consecutiveErrors = 0;
154
+ }
155
+ catch (err) {
156
+ consecutiveErrors++;
157
+ const dur = Date.now() - this.roundStartTime;
158
+ this.activeCtx = null;
159
+ // Emit round:complete with error info
160
+ const errInfo = {
161
+ round: this.currentRound,
162
+ quality: 0,
163
+ selfEval: makeSelfEvaluation({
164
+ success: false,
165
+ output_summary: `execute threw: ${String(err).slice(0, 200)}`,
166
+ constraint_violations: ["execute() threw an exception"],
167
+ should_continue: true,
168
+ }),
169
+ durationMs: dur,
170
+ };
171
+ this.emit("round:complete", errInfo);
172
+ this.config.onRoundComplete?.(errInfo);
173
+ this.qualityTrajectory.push(0);
174
+ if (consecutiveErrors >= this.config.maxConsecutiveErrors) {
175
+ stopReason = "executor_failure";
176
+ break;
177
+ }
178
+ // Record as a failed round so the next round's compilation
179
+ // sees the failure context (forces L1/L2)
180
+ previousAgentOutput = null;
181
+ continue;
182
+ }
183
+ const durationMs = Date.now() - this.roundStartTime;
184
+ this.activeCtx = null;
185
+ // ── Extract self-eval ─────────────────────────────────────────
186
+ let selfEval = extractSelfEvaluation(agentOutput);
187
+ let extractionSucceeded = selfEval !== null;
188
+ if (selfEval === null) {
189
+ selfEval = heuristicSelfEvaluation(agentOutput);
190
+ extractionSucceeded = false;
191
+ }
192
+ // ── Auto-feedback ─────────────────────────────────────────────
193
+ if (selfEval !== null) {
194
+ this.engine.autoFeedback(selfEval, this.config.loopId, this.currentRound, this.config.task);
195
+ }
196
+ // Compute quality score
197
+ let quality = 0;
198
+ if (selfEval) {
199
+ if (selfEval.success && selfEval.constraint_violations.length === 0) {
200
+ quality = 5;
201
+ }
202
+ else if (selfEval.success) {
203
+ quality = 3;
204
+ }
205
+ else if (selfEval.constraint_violations.length > 0) {
206
+ quality = 2;
207
+ }
208
+ else {
209
+ quality = 1;
210
+ }
211
+ }
212
+ this.qualityTrajectory.push(quality);
213
+ // ── Emit round:complete ───────────────────────────────────────
214
+ const completeInfo = {
215
+ round: this.currentRound,
216
+ quality,
217
+ selfEval,
218
+ durationMs,
219
+ };
220
+ this.emit("round:complete", completeInfo);
221
+ this.config.onRoundComplete?.(completeInfo);
222
+ // ── Check stop conditions ─────────────────────────────────────
223
+ // Extraction check FIRST — heuristic results are low-confidence
224
+ if (!extractionSucceeded) {
225
+ stopReason = "stalled"; // extraction_failure mapped to stalled
226
+ break;
227
+ }
228
+ if (selfEval && !selfEval.should_continue) {
229
+ stopReason = "task_complete";
230
+ break;
231
+ }
232
+ if (this.engine.shouldBreak()) {
233
+ stopReason = "circuit_breaker";
234
+ break;
235
+ }
236
+ if (this.timedOut) {
237
+ // Next round will be forced L2 via the compile request
238
+ this.timedOut = false;
239
+ }
240
+ previousAgentOutput = agentOutput;
241
+ }
242
+ // ── Cleanup ──────────────────────────────────────────────────────
243
+ this.stopHeartbeat();
244
+ this.unregisterSignalHandlers();
245
+ if (this._status === RuntimeStatus.RUNNING) {
246
+ this._status = RuntimeStatus.STOPPED;
247
+ }
248
+ const result = {
249
+ success: stopReason === "task_complete",
250
+ stopReason,
251
+ roundsCompleted: this.currentRound > this.config.maxRounds
252
+ ? this.config.maxRounds
253
+ : this.currentRound,
254
+ qualityTrajectory: [...this.qualityTrajectory],
255
+ };
256
+ this.emit("done", result);
257
+ return result;
258
+ }
259
+ /** Stop the loop gracefully. Safe to call from any thread/timer. */
260
+ stop() {
261
+ if (this._status === RuntimeStatus.RUNNING) {
262
+ this._status = RuntimeStatus.STOPPED;
263
+ this.emit("stop");
264
+ }
265
+ }
266
+ // ── Internal: compile request builder ─────────────────────────────────
267
+ buildCompileRequest(previousAgentOutput) {
268
+ const lcr = makeLoopCompileRequest({
269
+ loop_id: this.config.loopId,
270
+ round: this.currentRound,
271
+ goal_id: this.config.goalId || "",
272
+ task: this.config.task,
273
+ domain: this.config.domain,
274
+ plan_source: this.config.planSource ?? null,
275
+ constraints_from_plan: this.config.constraintsFromPlan,
276
+ health_check_interval: this.config.healthCheckInterval,
277
+ vault_config: makeVaultConfig(),
278
+ });
279
+ if (this.timedOut && this.currentRound > 1) {
280
+ lcr.force_level = "l2";
281
+ }
282
+ // Attach last round result from previous iteration
283
+ if (previousAgentOutput !== null && this.currentRound > 1) {
284
+ const selfEval = extractSelfEvaluation(previousAgentOutput) ??
285
+ heuristicSelfEvaluation(previousAgentOutput);
286
+ if (selfEval) {
287
+ lcr.last_round_result = makeLoopRoundResult({
288
+ round: this.currentRound - 1,
289
+ success: selfEval.success,
290
+ output_summary: selfEval.output_summary,
291
+ constraint_violations: selfEval.constraint_violations,
292
+ manual_fixes_needed: "",
293
+ quality_score: 0,
294
+ });
295
+ }
296
+ }
297
+ return lcr;
298
+ }
299
+ // ── Internal: heartbeat ──────────────────────────────────────────────
300
+ startHeartbeat() {
301
+ if (this.config.heartbeatIntervalMs <= 0)
302
+ return;
303
+ this.heartbeatTimer = setInterval(() => {
304
+ this.heartbeatTick();
305
+ }, this.config.heartbeatIntervalMs);
306
+ // Allow the process to exit even if this timer is still running
307
+ if (this.heartbeatTimer && typeof this.heartbeatTimer === "object") {
308
+ this.heartbeatTimer.unref?.();
309
+ }
310
+ }
311
+ heartbeatTick() {
312
+ if (this._status !== RuntimeStatus.RUNNING)
313
+ return;
314
+ if (this.roundStartTime === 0)
315
+ return;
316
+ try {
317
+ const now = Date.now();
318
+ const elapsed = now - this.roundStartTime;
319
+ const sinceProgress = now - this.lastProgressTime;
320
+ const hbInfo = {
321
+ round: this.currentRound,
322
+ elapsedMs: elapsed,
323
+ sinceProgressMs: sinceProgress,
324
+ };
325
+ this.emit("heartbeat", hbInfo);
326
+ this.config.onHeartbeat?.(hbInfo);
327
+ // Interactive mode: only emit heartbeat, never timeout/stall
328
+ if (this.config.interactive)
329
+ return;
330
+ // Approaching timeout warning (80%)
331
+ if (elapsed > this.config.roundTimeoutMs * 0.8 && !this.timedOut) {
332
+ const warning = {
333
+ type: "approaching_timeout",
334
+ message: `Round ${this.currentRound} approaching timeout ` +
335
+ `(${elapsed}ms / ${this.config.roundTimeoutMs}ms)`,
336
+ };
337
+ this.emit("health:warning", warning);
338
+ this.config.onHealthWarning?.(warning);
339
+ }
340
+ // Timeout
341
+ if (elapsed > this.config.roundTimeoutMs && !this.timedOut) {
342
+ this.timedOut = true;
343
+ if (this.activeCtx) {
344
+ this.activeCtx.signal.aborted = true;
345
+ }
346
+ const timeoutInfo = {
347
+ round: this.currentRound,
348
+ elapsedMs: elapsed,
349
+ };
350
+ this.emit("timeout", timeoutInfo);
351
+ this.config.onTimeout?.(timeoutInfo);
352
+ }
353
+ // Stall — timeout + grace period elapsed, execute still hasn't returned
354
+ if (elapsed > this.config.roundTimeoutMs + this.config.stallGraceMs) {
355
+ this._status = RuntimeStatus.STALLED;
356
+ const stallMsg = `Round ${this.currentRound} stalled after ${elapsed}ms`;
357
+ this.emit("stalled", {
358
+ reason: "round_timeout",
359
+ lastRound: this.currentRound,
360
+ elapsedMs: elapsed,
361
+ message: stallMsg,
362
+ });
363
+ }
364
+ }
365
+ catch {
366
+ // heartbeatTick must never throw — silently ignore errors
367
+ }
368
+ }
369
+ stopHeartbeat() {
370
+ if (this.heartbeatTimer !== null) {
371
+ clearInterval(this.heartbeatTimer);
372
+ this.heartbeatTimer = null;
373
+ }
374
+ }
375
+ // ── Internal: signal handlers ────────────────────────────────────────
376
+ registerSignalHandlers() {
377
+ this.sigintHandler = () => {
378
+ this.stop();
379
+ };
380
+ this.sigtermHandler = () => {
381
+ this.stop();
382
+ };
383
+ process.on("SIGINT", this.sigintHandler);
384
+ process.on("SIGTERM", this.sigtermHandler);
385
+ }
386
+ unregisterSignalHandlers() {
387
+ if (this.sigintHandler) {
388
+ process.removeListener("SIGINT", this.sigintHandler);
389
+ this.sigintHandler = null;
390
+ }
391
+ if (this.sigtermHandler) {
392
+ process.removeListener("SIGTERM", this.sigtermHandler);
393
+ this.sigtermHandler = null;
394
+ }
395
+ }
396
+ }
397
+ // ═══════════════════════════════════════════════════════════════════════════
398
+ // Convenience function — the 80% API
399
+ // ═══════════════════════════════════════════════════════════════════════════
400
+ /** Run a fully autonomous loop. Only `task` and `execute` are required.
401
+ * All other configuration has sensible defaults from `loop_policy.json`.
402
+ *
403
+ * @example
404
+ * const result = await run({
405
+ * task: 'Audit ERC20 token for security vulnerabilities',
406
+ * execute: async (prompt) => await myAgent.call(prompt),
407
+ * });
408
+ * // result: { success, stopReason, roundsCompleted, qualityTrajectory }
409
+ */
410
+ export async function run(rawConfig) {
411
+ const runtime = new LoopRuntime(rawConfig);
412
+ return runtime.start();
413
+ }
414
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /** Shared test utilities — in-memory backend, test data factories.
2
+ *
3
+ * Imported by replay.test.ts and mcp.test.ts to avoid ~50 lines of
4
+ * duplicated MemoryBackend implementation.
5
+ */
6
+ import type { VaultBackend, VaultEntry } from "../backends/interface.js";
7
+ /** In-memory backend for testing — implements VaultBackend without filesystem. */
8
+ export declare class MemoryBackend implements VaultBackend {
9
+ entries: VaultEntry[];
10
+ markdownFiles: Map<string, string>;
11
+ markdownScans: Map<string, VaultEntry[]>;
12
+ readVault(): Record<string, unknown>;
13
+ writeVault(data: Record<string, unknown>): void;
14
+ queryEntries(opts?: {
15
+ prefix?: string;
16
+ taskIdPattern?: string;
17
+ feedbackOnly?: boolean;
18
+ }): VaultEntry[];
19
+ appendEntry(entry: VaultEntry): void;
20
+ appendEntries(entries: VaultEntry[]): number;
21
+ writeLineageMd(_loopId: string, roundNum: number, content: string, _metadata: Record<string, unknown>): string | null;
22
+ readLineageMd(loopId: string, roundNum: number): string | null;
23
+ scanLineageMd(loopId: string): VaultEntry[];
24
+ }
25
+ //# sourceMappingURL=_helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.d.ts","sourceRoot":"","sources":["../../src/tests/_helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEzE,kFAAkF;AAClF,qBAAa,aAAc,YAAW,YAAY;IAChD,OAAO,EAAE,UAAU,EAAE,CAAM;IAC3B,aAAa,sBAA6B;IAC1C,aAAa,4BAAmC;IAEhD,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAGpC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAG/C,YAAY,CAAC,IAAI,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,CAAC,EAAE,OAAO,CAAC;KACxB,GAAG,UAAU,EAAE;IAShB,WAAW,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAGpC,aAAa,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM;IAI5C,cAAc,CACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,MAAM,GAAG,IAAI;IAIhB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAG9D,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;CAG5C"}
@@ -0,0 +1,47 @@
1
+ /** Shared test utilities — in-memory backend, test data factories.
2
+ *
3
+ * Imported by replay.test.ts and mcp.test.ts to avoid ~50 lines of
4
+ * duplicated MemoryBackend implementation.
5
+ */
6
+ /** In-memory backend for testing — implements VaultBackend without filesystem. */
7
+ export class MemoryBackend {
8
+ entries = [];
9
+ markdownFiles = new Map();
10
+ markdownScans = new Map();
11
+ readVault() {
12
+ return { entries: this.entries };
13
+ }
14
+ writeVault(data) {
15
+ this.entries = data.entries || [];
16
+ }
17
+ queryEntries(opts) {
18
+ return this.entries.filter((entry) => {
19
+ const taskId = String(entry.task_id ?? "");
20
+ if (opts?.feedbackOnly && !taskId.endsWith(":feedback"))
21
+ return false;
22
+ if (!opts?.feedbackOnly && taskId.endsWith(":feedback"))
23
+ return false;
24
+ if (opts?.prefix && !taskId.startsWith(opts.prefix))
25
+ return false;
26
+ return true;
27
+ });
28
+ }
29
+ appendEntry(entry) {
30
+ this.entries.push(entry);
31
+ }
32
+ appendEntries(entries) {
33
+ this.entries.push(...entries);
34
+ return entries.length;
35
+ }
36
+ writeLineageMd(_loopId, roundNum, content, _metadata) {
37
+ this.markdownFiles.set(`${_loopId}:r${roundNum}`, content);
38
+ return `/fake/${_loopId}/r${roundNum}.md`;
39
+ }
40
+ readLineageMd(loopId, roundNum) {
41
+ return this.markdownFiles.get(`${loopId}:r${roundNum}`) ?? null;
42
+ }
43
+ scanLineageMd(loopId) {
44
+ return this.markdownScans.get(loopId) ?? [];
45
+ }
46
+ }
47
+ //# sourceMappingURL=_helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_helpers.js","sourceRoot":"","sources":["../../src/tests/_helpers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,kFAAkF;AAClF,MAAM,OAAO,aAAa;IACxB,OAAO,GAAiB,EAAE,CAAC;IAC3B,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEhD,SAAS;QACP,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACnC,CAAC;IACD,UAAU,CAAC,IAA6B;QACtC,IAAI,CAAC,OAAO,GAAI,IAAI,CAAC,OAAwB,IAAI,EAAE,CAAC;IACtD,CAAC;IACD,YAAY,CAAC,IAIZ;QACC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;YAC3C,IAAI,IAAI,EAAE,YAAY,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAAE,OAAO,KAAK,CAAC;YACtE,IAAI,CAAC,IAAI,EAAE,YAAY,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAAE,OAAO,KAAK,CAAC;YACtE,IAAI,IAAI,EAAE,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;gBAAE,OAAO,KAAK,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,WAAW,CAAC,KAAiB;QAC3B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,aAAa,CAAC,OAAqB;QACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;QAC9B,OAAO,OAAO,CAAC,MAAM,CAAC;IACxB,CAAC;IACD,cAAc,CACZ,OAAe,EACf,QAAgB,EAChB,OAAe,EACf,SAAkC;QAElC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,OAAO,KAAK,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3D,OAAO,SAAS,OAAO,KAAK,QAAQ,KAAK,CAAC;IAC5C,CAAC;IACD,aAAa,CAAC,MAAc,EAAE,QAAgB;QAC5C,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,QAAQ,EAAE,CAAC,IAAI,IAAI,CAAC;IAClE,CAAC;IACD,aAAa,CAAC,MAAc;QAC1B,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9C,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ /** LoopForge — Autonomous loop tests (v1.1).
2
+ *
3
+ * Tests: extractSelfEvaluation, heuristicSelfEvaluation, buildSelfEvalBlock,
4
+ * autoFeedback, runOneRound.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=autonomous.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autonomous.test.d.ts","sourceRoot":"","sources":["../../src/tests/autonomous.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}