loopforge 1.1.1 → 1.3.1
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/LICENSE +1 -1
- package/README.md +2 -0
- package/dist/backends/fs.d.ts.map +1 -1
- package/dist/backends/fs.js +1 -0
- package/dist/backends/fs.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +69 -180
- package/dist/cli.js.map +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +6 -2
- package/dist/engine.js.map +1 -1
- package/dist/generate-schema.js +56 -4
- package/dist/generate-schema.js.map +1 -1
- package/dist/index.d.ts +17 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -7
- package/dist/index.js.map +1 -1
- package/dist/loop-compiler.js +1 -1
- package/dist/loop-compiler.js.map +1 -1
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +93 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/session.d.ts +68 -0
- package/dist/mcp/session.d.ts.map +1 -0
- package/dist/mcp/session.js +343 -0
- package/dist/mcp/session.js.map +1 -0
- package/dist/mcp/tools.d.ts +128 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +237 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/mcp-server.d.ts +12 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +14 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/policy.d.ts +8 -0
- package/dist/policy.d.ts.map +1 -1
- package/dist/policy.js +7 -0
- package/dist/policy.js.map +1 -1
- package/dist/protocol.d.ts +68 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +9 -1
- package/dist/protocol.js.map +1 -1
- package/dist/runtime.d.ts +57 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +414 -0
- package/dist/runtime.js.map +1 -0
- package/dist/tests/_helpers.d.ts +25 -0
- package/dist/tests/_helpers.d.ts.map +1 -0
- package/dist/tests/_helpers.js +47 -0
- package/dist/tests/_helpers.js.map +1 -0
- package/dist/tests/generate-schema.test.js +2 -2
- package/dist/tests/generate-schema.test.js.map +1 -1
- package/dist/tests/loop-compiler.test.js +21 -0
- package/dist/tests/loop-compiler.test.js.map +1 -1
- package/dist/tests/mcp.test.d.ts +7 -0
- package/dist/tests/mcp.test.d.ts.map +1 -0
- package/dist/tests/mcp.test.js +398 -0
- package/dist/tests/mcp.test.js.map +1 -0
- package/dist/tests/replay.test.js +69 -41
- package/dist/tests/replay.test.js.map +1 -1
- package/dist/tests/runtime.test.d.ts +7 -0
- package/dist/tests/runtime.test.d.ts.map +1 -0
- package/dist/tests/runtime.test.js +323 -0
- package/dist/tests/runtime.test.js.map +1 -0
- package/loop_policy.json +7 -0
- package/package.json +8 -6
- package/skills/perception/SKILL.md +194 -0
- package/skills/prompt-techniques/SKILL.md +52 -0
- package/skills/prompt-techniques/references/chain-of-thought.md +207 -0
- package/skills/prompt-techniques/references/few-shot.md +174 -0
- package/skills/prompt-techniques/references/least-to-most.md +182 -0
- package/skills/prompt-techniques/references/step-back.md +160 -0
- package/skills/prompt-techniques/references/tree-of-thought.md +191 -0
- package/skills/prompt-techniques/references/zero-shot.md +97 -0
- package/dist/autonomous.d.ts +0 -84
- package/dist/autonomous.d.ts.map +0 -1
- package/dist/autonomous.js +0 -250
- package/dist/autonomous.js.map +0 -1
- package/dist/backends/ai.d.ts +0 -37
- package/dist/backends/ai.d.ts.map +0 -1
- package/dist/backends/ai.js +0 -98
- package/dist/backends/ai.js.map +0 -1
- package/dist/tests/autonomous.test.d.ts +0 -7
- package/dist/tests/autonomous.test.d.ts.map +0 -1
- package/dist/tests/autonomous.test.js +0 -294
- package/dist/tests/autonomous.test.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.test.js","sourceRoot":"","sources":["../../src/tests/replay.test.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"replay.test.js","sourceRoot":"","sources":["../../src/tests/replay.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.test.d.ts","sourceRoot":"","sources":["../../src/tests/runtime.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
|
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
/** LoopForge — Runtime tests (v1.2).
|
|
2
|
+
*
|
|
3
|
+
* Tests: LoopRuntime lifecycle, run() convenience function,
|
|
4
|
+
* heartbeat, timeout, stall, stop(), error handling.
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { LoopRuntime, run } from "../runtime.js";
|
|
9
|
+
import { RuntimeStatus, makeSelfEvaluation } from "../protocol.js";
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// Helpers
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
+
function makeAgentOutput(opts = {}) {
|
|
14
|
+
const se = makeSelfEvaluation({
|
|
15
|
+
success: true,
|
|
16
|
+
output_summary: "Task completed successfully.",
|
|
17
|
+
constraint_violations: [],
|
|
18
|
+
should_continue: true,
|
|
19
|
+
...opts,
|
|
20
|
+
});
|
|
21
|
+
return [
|
|
22
|
+
"## Result",
|
|
23
|
+
"",
|
|
24
|
+
"I completed the task as requested.",
|
|
25
|
+
"",
|
|
26
|
+
"---loopforge-eval",
|
|
27
|
+
JSON.stringify(se, null, 2),
|
|
28
|
+
"---end-loopforge-eval",
|
|
29
|
+
"",
|
|
30
|
+
].join("\n");
|
|
31
|
+
}
|
|
32
|
+
function makeFailingOutput(violations) {
|
|
33
|
+
return makeAgentOutput({
|
|
34
|
+
success: false,
|
|
35
|
+
output_summary: "Task partially completed.",
|
|
36
|
+
constraint_violations: violations,
|
|
37
|
+
should_continue: true,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function mockExecutor(responses) {
|
|
41
|
+
let idx = 0;
|
|
42
|
+
return async (_prompt, _ctx) => {
|
|
43
|
+
if (idx >= responses.length) {
|
|
44
|
+
throw new Error("mockExecutor: no more responses");
|
|
45
|
+
}
|
|
46
|
+
return responses[idx++];
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function slowExecutor(responses, delayMs) {
|
|
50
|
+
let idx = 0;
|
|
51
|
+
return async (_prompt, _ctx) => {
|
|
52
|
+
if (idx >= responses.length) {
|
|
53
|
+
throw new Error("slowExecutor: no more responses");
|
|
54
|
+
}
|
|
55
|
+
await new Promise((r) => setTimeout(r, delayMs));
|
|
56
|
+
return responses[idx++];
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
60
|
+
// run() convenience function
|
|
61
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
62
|
+
describe("run() — convenience function", () => {
|
|
63
|
+
it("completes 3-round loop with auto-generated loopId", async () => {
|
|
64
|
+
const responses = [
|
|
65
|
+
makeAgentOutput({ should_continue: true }),
|
|
66
|
+
makeAgentOutput({ should_continue: true }),
|
|
67
|
+
makeAgentOutput({ should_continue: false }),
|
|
68
|
+
];
|
|
69
|
+
const result = await run({
|
|
70
|
+
task: "Test task for minimal config",
|
|
71
|
+
execute: mockExecutor(responses),
|
|
72
|
+
maxRounds: 10,
|
|
73
|
+
});
|
|
74
|
+
assert.equal(result.stopReason, "task_complete");
|
|
75
|
+
assert.equal(result.success, true);
|
|
76
|
+
assert.equal(result.roundsCompleted, 3);
|
|
77
|
+
assert.equal(result.qualityTrajectory.length, 3);
|
|
78
|
+
// All rounds should have quality 5 (success + no violations)
|
|
79
|
+
for (const q of result.qualityTrajectory) {
|
|
80
|
+
assert.equal(q, 5);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
it("stops on task_complete when should_continue=false", async () => {
|
|
84
|
+
const result = await run({
|
|
85
|
+
task: "Test task complete",
|
|
86
|
+
execute: mockExecutor([
|
|
87
|
+
makeAgentOutput({ should_continue: false }),
|
|
88
|
+
]),
|
|
89
|
+
maxRounds: 10,
|
|
90
|
+
});
|
|
91
|
+
assert.equal(result.stopReason, "task_complete");
|
|
92
|
+
assert.equal(result.roundsCompleted, 1);
|
|
93
|
+
});
|
|
94
|
+
it("stops on max_rounds when agent always continues", async () => {
|
|
95
|
+
// Use ascending quality to avoid circuit breaker (flat 5,5,5 fires breaker)
|
|
96
|
+
const responses = [
|
|
97
|
+
makeAgentOutput({ success: false, constraint_violations: [], should_continue: true }), // quality 1
|
|
98
|
+
makeAgentOutput({ success: true, constraint_violations: [], should_continue: true }), // quality 5
|
|
99
|
+
makeAgentOutput({ success: true, constraint_violations: [], should_continue: true }), // quality 5
|
|
100
|
+
];
|
|
101
|
+
const result = await run({
|
|
102
|
+
task: "Test max rounds",
|
|
103
|
+
execute: mockExecutor(responses),
|
|
104
|
+
maxRounds: 3,
|
|
105
|
+
});
|
|
106
|
+
assert.equal(result.stopReason, "max_rounds");
|
|
107
|
+
assert.equal(result.roundsCompleted, 3);
|
|
108
|
+
});
|
|
109
|
+
it("stops on executor_failure after consecutive errors", async () => {
|
|
110
|
+
let calls = 0;
|
|
111
|
+
const result = await run({
|
|
112
|
+
task: "Test executor failure",
|
|
113
|
+
execute: async () => {
|
|
114
|
+
calls++;
|
|
115
|
+
throw new Error("API key expired");
|
|
116
|
+
},
|
|
117
|
+
maxRounds: 10,
|
|
118
|
+
maxConsecutiveErrors: 3,
|
|
119
|
+
});
|
|
120
|
+
assert.equal(result.stopReason, "executor_failure");
|
|
121
|
+
assert.equal(calls, 3);
|
|
122
|
+
});
|
|
123
|
+
it("recovers from a single execute error", async () => {
|
|
124
|
+
let calls = 0;
|
|
125
|
+
const result = await run({
|
|
126
|
+
task: "Test recover from error",
|
|
127
|
+
execute: async () => {
|
|
128
|
+
calls++;
|
|
129
|
+
if (calls === 1)
|
|
130
|
+
throw new Error("transient error");
|
|
131
|
+
return makeAgentOutput({ should_continue: false });
|
|
132
|
+
},
|
|
133
|
+
maxRounds: 10,
|
|
134
|
+
});
|
|
135
|
+
// Should succeed — only 1 error, not 3 consecutive
|
|
136
|
+
assert.equal(result.stopReason, "task_complete");
|
|
137
|
+
assert.equal(calls, 2);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
141
|
+
// LoopRuntime class
|
|
142
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
143
|
+
describe("LoopRuntime", () => {
|
|
144
|
+
it("status transitions: IDLE → RUNNING → STOPPED", async () => {
|
|
145
|
+
const rt = new LoopRuntime({
|
|
146
|
+
task: "Test status transitions",
|
|
147
|
+
execute: mockExecutor([
|
|
148
|
+
makeAgentOutput({ should_continue: false }),
|
|
149
|
+
]),
|
|
150
|
+
});
|
|
151
|
+
assert.equal(rt.status, "idle");
|
|
152
|
+
const result = await rt.start();
|
|
153
|
+
assert.equal(result.stopReason, "task_complete");
|
|
154
|
+
// After start() resolves, runtime is stopped
|
|
155
|
+
const finalStatus = rt.status;
|
|
156
|
+
assert.notEqual(finalStatus, RuntimeStatus.RUNNING);
|
|
157
|
+
assert.notEqual(finalStatus, RuntimeStatus.IDLE);
|
|
158
|
+
});
|
|
159
|
+
it("stop() mid-loop stops gracefully", async () => {
|
|
160
|
+
const rt = new LoopRuntime({
|
|
161
|
+
task: "Test stop mid-loop",
|
|
162
|
+
execute: mockExecutor([
|
|
163
|
+
makeAgentOutput({ should_continue: true }),
|
|
164
|
+
makeAgentOutput({ should_continue: true }),
|
|
165
|
+
makeAgentOutput({ should_continue: true }),
|
|
166
|
+
]),
|
|
167
|
+
maxRounds: 10,
|
|
168
|
+
onRoundComplete: (info) => {
|
|
169
|
+
if (info.round === 2) {
|
|
170
|
+
rt.stop();
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
const result = await rt.start();
|
|
175
|
+
assert.equal(result.stopReason, "stopped");
|
|
176
|
+
// stop() is called in round 2's onRoundComplete; the for-loop
|
|
177
|
+
// increments to round 3 before checking status, so roundsCompleted
|
|
178
|
+
// reflects the incremented counter
|
|
179
|
+
assert.ok(result.roundsCompleted <= 3);
|
|
180
|
+
});
|
|
181
|
+
it("getCurrentRound and getQualityTrajectory work", async () => {
|
|
182
|
+
const rt = new LoopRuntime({
|
|
183
|
+
task: "Test accessors",
|
|
184
|
+
execute: mockExecutor([
|
|
185
|
+
makeAgentOutput({ should_continue: true }),
|
|
186
|
+
makeAgentOutput({ should_continue: false }),
|
|
187
|
+
]),
|
|
188
|
+
maxRounds: 10,
|
|
189
|
+
});
|
|
190
|
+
assert.equal(rt.getCurrentRound(), 1); // before start
|
|
191
|
+
assert.equal(rt.getQualityTrajectory().length, 0);
|
|
192
|
+
await rt.start();
|
|
193
|
+
assert.equal(rt.getQualityTrajectory().length, 2);
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
197
|
+
// Heartbeat & timeout
|
|
198
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
199
|
+
describe("Heartbeat & timeout", () => {
|
|
200
|
+
it("heartbeat events fire during slow execute", async () => {
|
|
201
|
+
const heartbeats = [];
|
|
202
|
+
const result = await run({
|
|
203
|
+
task: "Test heartbeat",
|
|
204
|
+
execute: slowExecutor([makeAgentOutput({ should_continue: false })], 150),
|
|
205
|
+
heartbeatIntervalMs: 50,
|
|
206
|
+
roundTimeoutMs: 5000,
|
|
207
|
+
maxRounds: 10,
|
|
208
|
+
onHeartbeat: (info) => {
|
|
209
|
+
heartbeats.push(info);
|
|
210
|
+
},
|
|
211
|
+
});
|
|
212
|
+
assert.equal(result.stopReason, "task_complete");
|
|
213
|
+
// Should have received at least one heartbeat during the 150ms delay
|
|
214
|
+
assert.ok(heartbeats.length >= 1, `expected >=1 heartbeats, got ${heartbeats.length}`);
|
|
215
|
+
});
|
|
216
|
+
it("timeout sets signal.aborted", async () => {
|
|
217
|
+
let signalWasAborted = false;
|
|
218
|
+
const result = await run({
|
|
219
|
+
task: "Test timeout",
|
|
220
|
+
execute: async (_prompt, ctx) => {
|
|
221
|
+
// Sleep past the timeout
|
|
222
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
223
|
+
if (ctx && ctx.signal.aborted) {
|
|
224
|
+
signalWasAborted = true;
|
|
225
|
+
}
|
|
226
|
+
return makeAgentOutput({ should_continue: false });
|
|
227
|
+
},
|
|
228
|
+
roundTimeoutMs: 50,
|
|
229
|
+
heartbeatIntervalMs: 25,
|
|
230
|
+
stallGraceMs: 5000,
|
|
231
|
+
maxRounds: 10,
|
|
232
|
+
});
|
|
233
|
+
assert.equal(result.stopReason, "task_complete");
|
|
234
|
+
assert.ok(signalWasAborted, "signal.aborted should be true after timeout");
|
|
235
|
+
});
|
|
236
|
+
it("interactive mode does not trigger timeout", async () => {
|
|
237
|
+
let timeoutFired = false;
|
|
238
|
+
const result = await run({
|
|
239
|
+
task: "Test interactive",
|
|
240
|
+
execute: async (_prompt, _ctx) => {
|
|
241
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
242
|
+
return makeAgentOutput({ should_continue: false });
|
|
243
|
+
},
|
|
244
|
+
interactive: true,
|
|
245
|
+
roundTimeoutMs: 50,
|
|
246
|
+
heartbeatIntervalMs: 25,
|
|
247
|
+
maxRounds: 10,
|
|
248
|
+
onTimeout: () => {
|
|
249
|
+
timeoutFired = true;
|
|
250
|
+
},
|
|
251
|
+
});
|
|
252
|
+
assert.equal(result.stopReason, "task_complete");
|
|
253
|
+
assert.equal(timeoutFired, false);
|
|
254
|
+
});
|
|
255
|
+
it("reportProgress resets stall timer", async () => {
|
|
256
|
+
let reported = false;
|
|
257
|
+
const result = await run({
|
|
258
|
+
task: "Test reportProgress",
|
|
259
|
+
execute: async (_prompt, ctx) => {
|
|
260
|
+
ctx?.reportProgress("still working...");
|
|
261
|
+
reported = true;
|
|
262
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
263
|
+
return makeAgentOutput({ should_continue: false });
|
|
264
|
+
},
|
|
265
|
+
roundTimeoutMs: 5000,
|
|
266
|
+
heartbeatIntervalMs: 20,
|
|
267
|
+
maxRounds: 10,
|
|
268
|
+
});
|
|
269
|
+
assert.equal(result.stopReason, "task_complete");
|
|
270
|
+
assert.ok(reported);
|
|
271
|
+
});
|
|
272
|
+
});
|
|
273
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
274
|
+
// Circuit breaker & extraction failure
|
|
275
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
276
|
+
describe("Circuit breaker & extraction", () => {
|
|
277
|
+
it("circuit breaker triggers after consecutive low quality", async () => {
|
|
278
|
+
// Generate failing outputs for 5+ rounds to trigger circuit breaker
|
|
279
|
+
const responses = Array.from({ length: 10 }, () => makeFailingOutput(["violated constraint X"]));
|
|
280
|
+
const result = await run({
|
|
281
|
+
task: "Test circuit breaker",
|
|
282
|
+
execute: mockExecutor(responses),
|
|
283
|
+
maxRounds: 10,
|
|
284
|
+
});
|
|
285
|
+
// Either circuit_breaker or max_rounds — depends on policy
|
|
286
|
+
assert.ok(result.stopReason === "circuit_breaker" ||
|
|
287
|
+
result.stopReason === "max_rounds", `expected circuit_breaker or max_rounds, got ${result.stopReason}`);
|
|
288
|
+
});
|
|
289
|
+
it("stops on extraction failure (no eval block)", async () => {
|
|
290
|
+
const result = await run({
|
|
291
|
+
task: "Test extraction failure",
|
|
292
|
+
execute: mockExecutor([
|
|
293
|
+
makeAgentOutput({ should_continue: true }),
|
|
294
|
+
"No structured eval block here, still need to continue working on more tasks.", // heuristic will detect "remaining" → should_continue=true, but extraction is heuristic → stalled
|
|
295
|
+
]),
|
|
296
|
+
maxRounds: 10,
|
|
297
|
+
});
|
|
298
|
+
// Extraction via heuristic → extractionSucceeded=false → stalled
|
|
299
|
+
assert.equal(result.stopReason, "stalled");
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
303
|
+
// Stall detection
|
|
304
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
305
|
+
describe("Stall detection", () => {
|
|
306
|
+
it("stalls when execute exceeds timeout + stall grace", async () => {
|
|
307
|
+
const result = await run({
|
|
308
|
+
task: "Test stall",
|
|
309
|
+
execute: async (_prompt, _ctx) => {
|
|
310
|
+
// Sleep past timeout + stall grace
|
|
311
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
312
|
+
return makeAgentOutput({ should_continue: false });
|
|
313
|
+
},
|
|
314
|
+
roundTimeoutMs: 50,
|
|
315
|
+
heartbeatIntervalMs: 25,
|
|
316
|
+
stallGraceMs: 50,
|
|
317
|
+
maxRounds: 10,
|
|
318
|
+
});
|
|
319
|
+
// Should be stalled (status was set to STALLED but execute returned)
|
|
320
|
+
assert.ok(["stalled", "task_complete"].includes(result.stopReason), `expected stalled or task_complete, got ${result.stopReason}`);
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
//# sourceMappingURL=runtime.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.test.js","sourceRoot":"","sources":["../../src/tests/runtime.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AASnE,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,eAAe,CACtB,OAAgC,EAAE;IAElC,MAAM,EAAE,GAAG,kBAAkB,CAAC;QAC5B,OAAO,EAAE,IAAI;QACb,cAAc,EAAE,8BAA8B;QAC9C,qBAAqB,EAAE,EAAE;QACzB,eAAe,EAAE,IAAI;QACrB,GAAG,IAAI;KACR,CAAC,CAAC;IACH,OAAO;QACL,WAAW;QACX,EAAE;QACF,oCAAoC;QACpC,EAAE;QACF,mBAAmB;QACnB,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3B,uBAAuB;QACvB,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAoB;IAC7C,OAAO,eAAe,CAAC;QACrB,OAAO,EAAE,KAAK;QACd,cAAc,EAAE,2BAA2B;QAC3C,qBAAqB,EAAE,UAAU;QACjC,eAAe,EAAE,IAAI;KACtB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CACnB,SAAmB;IAEnB,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CACnB,SAAmB,EACnB,OAAe;IAEf,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QAC7B,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACjD,OAAO,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,SAAS,GAAG;YAChB,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;YAC1C,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;YAC1C,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;SAC5C,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,8BAA8B;YACpC,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC;YAChC,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACnC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjD,6DAA6D;QAC7D,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACzC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACrB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,YAAY,CAAC;gBACpB,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;aAC5C,CAAC;YACF,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,4EAA4E;QAC5E,MAAM,SAAS,GAAG;YAChB,eAAe,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAG,YAAY;YACpG,eAAe,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAI,YAAY;YACpG,eAAe,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,EAAI,YAAY;SACrG,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,iBAAiB;YACvB,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC;YAChC,SAAS,EAAE,CAAC;SACb,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,KAAK,EAAE,CAAC;gBACR,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;YACD,SAAS,EAAE,EAAE;YACb,oBAAoB,EAAE,CAAC;SACxB,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,KAAK,IAAI,EAAE;gBAClB,KAAK,EAAE,CAAC;gBACR,IAAI,KAAK,KAAK,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACpD,OAAO,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC;YACzB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,YAAY,CAAC;gBACpB,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;aAC5C,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAEjD,6CAA6C;QAC7C,MAAM,WAAW,GAAG,EAAE,CAAC,MAAM,CAAC;QAC9B,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC;YACzB,IAAI,EAAE,oBAAoB;YAC1B,OAAO,EAAE,YAAY,CAAC;gBACpB,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC1C,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC1C,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;aAC3C,CAAC;YACF,SAAS,EAAE,EAAE;YACb,eAAe,EAAE,CAAC,IAAuB,EAAE,EAAE;gBAC3C,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;oBACrB,EAAE,CAAC,IAAI,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC3C,8DAA8D;QAC9D,mEAAmE;QACnE,mCAAmC;QACnC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,KAAK,IAAI,EAAE;QAC7D,MAAM,EAAE,GAAG,IAAI,WAAW,CAAC;YACzB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,YAAY,CAAC;gBACpB,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC1C,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;aAC5C,CAAC;YACF,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe;QACtD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAElD,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QAEjB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,sBAAsB;AACtB,8EAA8E;AAE9E,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,UAAU,GAAoB,EAAE,CAAC;QAEvC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,YAAY,CACnB,CAAC,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC,EAC7C,GAAG,CACJ;YACD,mBAAmB,EAAE,EAAE;YACvB,cAAc,EAAE,IAAI;YACpB,SAAS,EAAE,EAAE;YACb,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE;gBACpB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxB,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,qEAAqE;QACrE,MAAM,CAAC,EAAE,CACP,UAAU,CAAC,MAAM,IAAI,CAAC,EACtB,gCAAgC,UAAU,CAAC,MAAM,EAAE,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,IAAI,gBAAgB,GAAG,KAAK,CAAC;QAE7B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;gBAC9B,yBAAyB;gBACzB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBAC7C,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC9B,gBAAgB,GAAG,IAAI,CAAC;gBAC1B,CAAC;gBACD,OAAO,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,cAAc,EAAE,EAAE;YAClB,mBAAmB,EAAE,EAAE;YACvB,YAAY,EAAE,IAAI;YAClB,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,gBAAgB,EAAE,6CAA6C,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;gBAC/B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBAC7C,OAAO,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,WAAW,EAAE,IAAI;YACjB,cAAc,EAAE,EAAE;YAClB,mBAAmB,EAAE,EAAE;YACvB,SAAS,EAAE,EAAE;YACb,SAAS,EAAE,GAAG,EAAE;gBACd,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,qBAAqB;YAC3B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE;gBAC9B,GAAG,EAAE,cAAc,CAAC,kBAAkB,CAAC,CAAC;gBACxC,QAAQ,GAAG,IAAI,CAAC;gBAChB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBAC5C,OAAO,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,cAAc,EAAE,IAAI;YACpB,mBAAmB,EAAE,EAAE;YACvB,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QACjD,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;QACtE,oEAAoE;QACpE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,CAChD,iBAAiB,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAC7C,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,YAAY,CAAC,SAAS,CAAC;YAChC,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,2DAA2D;QAC3D,MAAM,CAAC,EAAE,CACP,MAAM,CAAC,UAAU,KAAK,iBAAiB;YACrC,MAAM,CAAC,UAAU,KAAK,YAAY,EACpC,+CAA+C,MAAM,CAAC,UAAU,EAAE,CACnE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;QAC3D,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,yBAAyB;YAC/B,OAAO,EAAE,YAAY,CAAC;gBACpB,eAAe,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;gBAC1C,8EAA8E,EAAE,kGAAkG;aACnL,CAAC;YACF,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,iEAAiE;QACjE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC/B,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC;YACvB,IAAI,EAAE,YAAY;YAClB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;gBAC/B,mCAAmC;gBACnC,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;gBAC7C,OAAO,eAAe,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,cAAc,EAAE,EAAE;YAClB,mBAAmB,EAAE,EAAE;YACvB,YAAY,EAAE,EAAE;YAChB,SAAS,EAAE,EAAE;SACd,CAAC,CAAC;QAEH,qEAAqE;QACrE,MAAM,CAAC,EAAE,CACP,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EACxD,0CAA0C,MAAM,CAAC,UAAU,EAAE,CAC9D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/loop_policy.json
CHANGED
|
@@ -37,6 +37,13 @@
|
|
|
37
37
|
"feedback_flush_interval": 5,
|
|
38
38
|
"max_circuit_breaker": 3
|
|
39
39
|
},
|
|
40
|
+
"runtime": {
|
|
41
|
+
"max_rounds": 20,
|
|
42
|
+
"round_timeout_ms": 600000,
|
|
43
|
+
"heartbeat_interval_ms": 30000,
|
|
44
|
+
"stall_grace_ms": 300000,
|
|
45
|
+
"max_consecutive_errors": 3
|
|
46
|
+
},
|
|
40
47
|
"backend": {
|
|
41
48
|
"vault_path": ".promptcraft/prompt_vault.json",
|
|
42
49
|
"global_vault_path": "~/.promptcraft/global_vault.json"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "loopforge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Loop-Time Intelligence Layer for AI coding agents — per-iteration prompt compiler with structured memory, constraint inheritance, and drift correction.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,23 +18,25 @@
|
|
|
18
18
|
"import": "./dist/replay.js",
|
|
19
19
|
"types": "./dist/replay.d.ts"
|
|
20
20
|
},
|
|
21
|
-
"./
|
|
22
|
-
"import": "./dist/
|
|
23
|
-
"types": "./dist/
|
|
21
|
+
"./mcp": {
|
|
22
|
+
"import": "./dist/mcp/server.js",
|
|
23
|
+
"types": "./dist/mcp/server.d.ts"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"bin": {
|
|
27
|
-
"loopforge": "./dist/cli.js"
|
|
27
|
+
"loopforge": "./dist/cli.js",
|
|
28
|
+
"loopforge-mcp": "./dist/mcp-server.js"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"dist",
|
|
32
|
+
"skills",
|
|
31
33
|
"loop_policy.json",
|
|
32
34
|
"LICENSE"
|
|
33
35
|
],
|
|
34
36
|
"scripts": {
|
|
35
37
|
"build": "tsc && node dist/generate-schema.js",
|
|
36
38
|
"generate-schema": "tsc && node dist/generate-schema.js",
|
|
37
|
-
"test": "tsc && node dist/generate-schema.js && node --test dist/tests/*.test.js",
|
|
39
|
+
"test": "tsc && node dist/generate-schema.js && node --test dist/tests/*.test.js && node -e \"require('fs').rmSync('.promptcraft',{recursive:true,force:true})\"",
|
|
38
40
|
"test:watch": "tsc && node --test --watch dist/tests/*.test.js",
|
|
39
41
|
"check": "tsc --noEmit"
|
|
40
42
|
},
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: perception
|
|
3
|
+
description: Multi-round autonomous loop driver powered by LoopForge MCP. Compiles context-aware prompts per iteration, tracks quality, inherits constraints, and stops when work is done — not when rounds run out.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Perception — Loop-Time Intelligence Skill
|
|
7
|
+
|
|
8
|
+
**Perception** turns any AI agent into a self-aware multi-round executor. It
|
|
9
|
+
drives the LoopForge MCP server (`loopforge-mcp`) to compile per-iteration
|
|
10
|
+
prompts from running quality trajectory, constraint inheritance, and drift
|
|
11
|
+
detection — maintaining cognitive stability across long-horizon loops.
|
|
12
|
+
|
|
13
|
+
Works with Claude Code, Codex, and any MCP-capable host. Zero configuration
|
|
14
|
+
beyond having `loopforge-mcp` registered as an MCP server.
|
|
15
|
+
|
|
16
|
+
## When to Activate
|
|
17
|
+
|
|
18
|
+
Activate when the user says any of:
|
|
19
|
+
- `/loop <task>` — start an autonomous multi-round loop
|
|
20
|
+
- "do this in a loop", "keep going until done", "iterate on this"
|
|
21
|
+
- Any task that clearly needs 3+ rounds (audit, refactor, migrate, review-and-fix cycles)
|
|
22
|
+
|
|
23
|
+
Also activate implicitly when the user's request is too large for a single
|
|
24
|
+
round (e.g. "audit the entire codebase and fix every issue").
|
|
25
|
+
|
|
26
|
+
## Core Workflow
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
┌─────────────────────────────────────────────────────┐
|
|
30
|
+
│ 1. loopforge_start(task, constraints, maxRounds) │
|
|
31
|
+
│ → sessionId + Round 1 prompt │
|
|
32
|
+
│ │
|
|
33
|
+
│ 2. Execute the prompt (read, write, test, fix) │
|
|
34
|
+
│ MUST include ---loopforge-eval block in output │
|
|
35
|
+
│ │
|
|
36
|
+
│ 3. loopforge_next(sessionId, output) │
|
|
37
|
+
│ → if prompt: go to step 2 │
|
|
38
|
+
│ → if prompt=null: loop ended, read stopReason │
|
|
39
|
+
│ │
|
|
40
|
+
│ After restart: loopforge_resume(loopId) │
|
|
41
|
+
│ → picks up from last saved round │
|
|
42
|
+
└─────────────────────────────────────────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Step-by-step
|
|
46
|
+
|
|
47
|
+
**Step 1 — Start the loop:**
|
|
48
|
+
```
|
|
49
|
+
Call loopforge_start with:
|
|
50
|
+
task: required — the full task description
|
|
51
|
+
maxRounds: optional — default 20 from policy
|
|
52
|
+
constraints: optional — hard constraints as string[]
|
|
53
|
+
domain: optional — domain hint (solidity, react, rust…)
|
|
54
|
+
|
|
55
|
+
Keep the returned sessionId — you will need it for every subsequent call.
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
**Step 2 — Execute the round:**
|
|
59
|
+
Execute the compiled prompt exactly as you would any user task. Read files,
|
|
60
|
+
write code, run tests, fix bugs. The prompt already contains the task scope,
|
|
61
|
+
constraints, and quality expectations for this specific round.
|
|
62
|
+
|
|
63
|
+
**CRITICAL: Every round's output MUST end with a self-evaluation block:**
|
|
64
|
+
```
|
|
65
|
+
---loopforge-eval
|
|
66
|
+
{
|
|
67
|
+
"success": true,
|
|
68
|
+
"output_summary": "Fixed 3 reentrancy bugs in withdraw() and deposit(). All 12 tests pass.",
|
|
69
|
+
"constraint_violations": [],
|
|
70
|
+
"should_continue": true
|
|
71
|
+
}
|
|
72
|
+
---end-loopforge-eval
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
**Field rules:**
|
|
76
|
+
|
|
77
|
+
| Field | Type | Rule |
|
|
78
|
+
|-------|------|------|
|
|
79
|
+
| `success` | boolean | `true` ONLY if all hard constraints met AND the task goal achieved |
|
|
80
|
+
| `output_summary` | string | Specific, actionable. What was DONE this round — not what was attempted |
|
|
81
|
+
| `constraint_violations` | string[] | Constraints the agent actually violated this round. Be honest — hiding violations corrupts the quality signal and defeats the circuit breaker |
|
|
82
|
+
| `should_continue` | boolean | `false` ONLY when the ENTIRE task is complete. Partial progress = `true` |
|
|
83
|
+
|
|
84
|
+
**Why this matters:** Without a valid `---loopforge-eval` block, extraction
|
|
85
|
+
fails and the loop stops with `stopReason: stalled`. The circuit breaker
|
|
86
|
+
uses `success` + `violations` to compute quality scores — lying here defeats
|
|
87
|
+
the only mechanism that prevents infinite loops.
|
|
88
|
+
|
|
89
|
+
**Step 3 — Advance to next round:**
|
|
90
|
+
```
|
|
91
|
+
Call loopforge_next with:
|
|
92
|
+
sessionId: from loopforge_start
|
|
93
|
+
output: your FULL output from this round (including the eval block)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
If the result has `prompt: null`, the loop has ended. Read `stopReason`:
|
|
97
|
+
- `task_complete` — you reported should_continue=false. Work is done.
|
|
98
|
+
- `circuit_breaker` — quality flat or declining for 3+ rounds. Review your approach.
|
|
99
|
+
- `max_rounds` — hit the round limit. Decide whether to extend or accept.
|
|
100
|
+
- `stalled` — no valid self-eval block found. Check your output format.
|
|
101
|
+
|
|
102
|
+
If the result has a non-null `prompt`, execute it and repeat from Step 2.
|
|
103
|
+
|
|
104
|
+
## Tool Reference
|
|
105
|
+
|
|
106
|
+
| Tool | When to call | Key input | Key output |
|
|
107
|
+
|------|-------------|-----------|------------|
|
|
108
|
+
| `loopforge_start` | Beginning of every loop | `task`, `maxRounds?`, `constraints?` | `sessionId`, round 1 `prompt` |
|
|
109
|
+
| `loopforge_next` | After executing every round | `sessionId`, `output` (with eval block) | next `prompt` or `null` + `stopReason` |
|
|
110
|
+
| `loopforge_status` | Mid-loop checkpoint, user asks "how's it going" | `sessionId` | `round`, `qualityTrajectory`, `status`, `technique` |
|
|
111
|
+
| `loopforge_stop` | User wants to abort, fatal error | `sessionId` | `roundsCompleted`, final trajectory |
|
|
112
|
+
| `loopforge_list` | User asks "what loops are running" | — | `sessions[]` (includes vault-persisted) |
|
|
113
|
+
| `loopforge_replay` | After loop ends, user asks "show me what happened" | `sessionId` | `timeline[]` with all rounds |
|
|
114
|
+
| `loopforge_resume` | Resume a loop after process restart | `loopId` | next `prompt` or `null` + `stopReason` |
|
|
115
|
+
| `loopforge_health` | Check loop health mid-run | `loopId` | goal alignment, constraint integrity, drift, strategy |
|
|
116
|
+
|
|
117
|
+
## Quality Signals (Read the Room)
|
|
118
|
+
|
|
119
|
+
The prompt changes between rounds based on your trajectory. Pay attention to:
|
|
120
|
+
|
|
121
|
+
- **Compile level** — `l0` (cached, fast path), `l1` (patched, mild drift),
|
|
122
|
+
`l2` (full recompile, significant change). L2 means the compiler detected a
|
|
123
|
+
major shift — read the prompt carefully.
|
|
124
|
+
- **Warnings** — constraint violations accumulating, task drift, quality
|
|
125
|
+
decline. These are the compiler begging you to course-correct.
|
|
126
|
+
- **Technique rotation** — the compiler may switch from `zero-shot-cot` to
|
|
127
|
+
`tree-of-thought` if quality drops. Follow the new technique.
|
|
128
|
+
|
|
129
|
+
## Stop Condition Matrix
|
|
130
|
+
|
|
131
|
+
| Condition | stopReason | What to do |
|
|
132
|
+
|-----------|-----------|------------|
|
|
133
|
+
| You set `should_continue: false` | `task_complete` | Report final results to user |
|
|
134
|
+
| 3+ rounds of flat/declining quality | `circuit_breaker` | Tell user the approach is stuck, suggest a different strategy |
|
|
135
|
+
| Round count reached `maxRounds` | `max_rounds` | Summarize progress, ask user whether to extend |
|
|
136
|
+
| No `---loopforge-eval` block found | `stalled` | Fix your output format and restart |
|
|
137
|
+
| User interrupts or fatal error | (call `loopforge_stop`) | Clean stop with trajectory preserved |
|
|
138
|
+
|
|
139
|
+
## Rules
|
|
140
|
+
|
|
141
|
+
1. **Never skip the eval block.** No exceptions. If you forget, the loop stalls.
|
|
142
|
+
2. **Be honest in self-evaluation.** Lying about success or hiding violations
|
|
143
|
+
produces a false quality signal. The circuit breaker exists to stop bad
|
|
144
|
+
loops — if you fake quality=5 every round, it fires anyway.
|
|
145
|
+
3. **One loop per task.** Don't reuse a sessionId across different tasks.
|
|
146
|
+
4. **Execute the prompt you're given.** The compiler may change technique or
|
|
147
|
+
narrow scope between rounds. Trust it — it sees the trajectory.
|
|
148
|
+
5. **Call loopforge_next within the same turn.** Don't leave a round hanging
|
|
149
|
+
across conversation turns. The MCP server is in-memory.
|
|
150
|
+
6. **After process restart, use loopforge_resume.** The session state is saved
|
|
151
|
+
to vault every round. Call `loopforge_resume` with the original `loopId` to
|
|
152
|
+
pick up where you left off — no need to restart from round 1.
|
|
153
|
+
|
|
154
|
+
## Example
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
User: /loop "Audit the ERC20 token in contracts/Token.sol for security issues"
|
|
158
|
+
|
|
159
|
+
Agent:
|
|
160
|
+
→ loopforge_start({ task: "Audit ERC20 token in contracts/Token.sol for security issues",
|
|
161
|
+
domain: "solidity",
|
|
162
|
+
constraints: ["must not break existing tests", "follow check-effects-interactions"] })
|
|
163
|
+
← { sessionId: "abc-123", round: 1, prompt: "## LoopForge Loop Compile — Round 1\n...", level: "l2" }
|
|
164
|
+
|
|
165
|
+
[Executes prompt: reads Token.sol, identifies 4 issues, writes audit notes]
|
|
166
|
+
|
|
167
|
+
Output ends with:
|
|
168
|
+
---loopforge-eval
|
|
169
|
+
{"success":false,"output_summary":"Found 4 potential issues: 2 reentrancy, 1 overflow, 1 access control. Not yet fixed.","constraint_violations":[],"should_continue":true}
|
|
170
|
+
---end-loopforge-eval
|
|
171
|
+
|
|
172
|
+
→ loopforge_next({ sessionId: "abc-123", output: <full output> })
|
|
173
|
+
← { sessionId: "abc-123", round: 2, prompt: "## LoopForge Loop Compile — Round 2\n...", level: "l1" }
|
|
174
|
+
|
|
175
|
+
[Executes prompt: fixes 3 issues, 1 needs more investigation]
|
|
176
|
+
|
|
177
|
+
---loopforge-eval
|
|
178
|
+
{"success":false,"output_summary":"Fixed reentrancy in withdraw() and overflow in calcReward(). Access control issue in setOwner() needs design discussion.","constraint_violations":[],"should_continue":true}
|
|
179
|
+
---end-loopforge-eval
|
|
180
|
+
|
|
181
|
+
→ loopforge_next({ sessionId: "abc-123", output: <full output> })
|
|
182
|
+
← { sessionId: "abc-123", round: 3, prompt: "## LoopForge Loop Compile — Round 3\n...", level: "l0" }
|
|
183
|
+
|
|
184
|
+
[Executes prompt: documents access control issue for user decision, all fixes pass tests]
|
|
185
|
+
|
|
186
|
+
---loopforge-eval
|
|
187
|
+
{"success":true,"output_summary":"All fixable issues resolved. 1 access control design question flagged for user. 24/24 tests pass.","constraint_violations":[],"should_continue":false}
|
|
188
|
+
---end-loopforge-eval
|
|
189
|
+
|
|
190
|
+
→ loopforge_next({ sessionId: "abc-123", output: <full output> })
|
|
191
|
+
← { sessionId: "abc-123", round: 3, prompt: null, stopReason: "task_complete", quality: 5 }
|
|
192
|
+
|
|
193
|
+
Reports to user: "Audit complete in 3 rounds. 3 issues fixed, 1 design question flagged."
|
|
194
|
+
```
|