loopforge 1.0.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.
- package/LICENSE +21 -0
- package/README.md +75 -0
- package/dist/adapter.d.ts +17 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +228 -0
- package/dist/adapter.js.map +1 -0
- package/dist/backends/fs.d.ts +31 -0
- package/dist/backends/fs.d.ts.map +1 -0
- package/dist/backends/fs.js +308 -0
- package/dist/backends/fs.js.map +1 -0
- package/dist/backends/interface.d.ts +42 -0
- package/dist/backends/interface.d.ts.map +1 -0
- package/dist/backends/interface.js +7 -0
- package/dist/backends/interface.js.map +1 -0
- package/dist/builder.d.ts +17 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +205 -0
- package/dist/builder.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +360 -0
- package/dist/cli.js.map +1 -0
- package/dist/engine.d.ts +42 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +595 -0
- package/dist/engine.js.map +1 -0
- package/dist/generate-schema.d.ts +12 -0
- package/dist/generate-schema.d.ts.map +1 -0
- package/dist/generate-schema.js +278 -0
- package/dist/generate-schema.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/loop-compiler.d.ts +37 -0
- package/dist/loop-compiler.d.ts.map +1 -0
- package/dist/loop-compiler.js +1232 -0
- package/dist/loop-compiler.js.map +1 -0
- package/dist/policy.d.ts +44 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +111 -0
- package/dist/policy.js.map +1 -0
- package/dist/protocol.d.ts +167 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +198 -0
- package/dist/protocol.js.map +1 -0
- package/dist/replay.d.ts +19 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +198 -0
- package/dist/replay.js.map +1 -0
- package/dist/tests/adapter.test.d.ts +2 -0
- package/dist/tests/adapter.test.d.ts.map +1 -0
- package/dist/tests/adapter.test.js +104 -0
- package/dist/tests/adapter.test.js.map +1 -0
- package/dist/tests/builder.test.d.ts +2 -0
- package/dist/tests/builder.test.d.ts.map +1 -0
- package/dist/tests/builder.test.js +122 -0
- package/dist/tests/builder.test.js.map +1 -0
- package/dist/tests/engine.test.d.ts +2 -0
- package/dist/tests/engine.test.d.ts.map +1 -0
- package/dist/tests/engine.test.js +200 -0
- package/dist/tests/engine.test.js.map +1 -0
- package/dist/tests/generate-schema.test.d.ts +8 -0
- package/dist/tests/generate-schema.test.d.ts.map +1 -0
- package/dist/tests/generate-schema.test.js +196 -0
- package/dist/tests/generate-schema.test.js.map +1 -0
- package/dist/tests/loop-compiler.test.d.ts +2 -0
- package/dist/tests/loop-compiler.test.d.ts.map +1 -0
- package/dist/tests/loop-compiler.test.js +387 -0
- package/dist/tests/loop-compiler.test.js.map +1 -0
- package/dist/tests/policy.test.d.ts +2 -0
- package/dist/tests/policy.test.d.ts.map +1 -0
- package/dist/tests/policy.test.js +59 -0
- package/dist/tests/policy.test.js.map +1 -0
- package/dist/tests/protocol.test.d.ts +2 -0
- package/dist/tests/protocol.test.d.ts.map +1 -0
- package/dist/tests/protocol.test.js +63 -0
- package/dist/tests/protocol.test.js.map +1 -0
- package/dist/tests/replay.test.d.ts +2 -0
- package/dist/tests/replay.test.d.ts.map +1 -0
- package/dist/tests/replay.test.js +194 -0
- package/dist/tests/replay.test.js.map +1 -0
- package/loop_policy.json +44 -0
- package/package.json +58 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAMxE,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;gBAE3B,OAAO,EAAE,YAAY;IAMjC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IA8C7D,MAAM,CACJ,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GACtC,UAAU,EAAE;IAkBf,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;IAuBnD,IAAI,CACF,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAsG1B,OAAO,CAAC,QAAQ;CAsBjB"}
|
package/dist/replay.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/** ReplayBackend — time-travel queries over vault lineage.
|
|
2
|
+
*
|
|
3
|
+
* Depends on VaultBackend interface — no direct filesystem access.
|
|
4
|
+
* Enables audit, comparison, and timeline analysis of loop rounds.
|
|
5
|
+
*/
|
|
6
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
7
|
+
// ReplayBackend
|
|
8
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
9
|
+
export class ReplayBackend {
|
|
10
|
+
backend;
|
|
11
|
+
constructor(backend) {
|
|
12
|
+
this.backend = backend;
|
|
13
|
+
}
|
|
14
|
+
// ── Single-round lookup ────────────────────────────────────────────────
|
|
15
|
+
getRound(loopId, roundNum) {
|
|
16
|
+
const prefix = `loop:${loopId}:r${roundNum}`;
|
|
17
|
+
const entries = this.backend.queryEntries({ prefix });
|
|
18
|
+
const lineageEntries = entries.filter((e) => !String(e.task_id ?? "").endsWith(":feedback"));
|
|
19
|
+
if (!lineageEntries.length) {
|
|
20
|
+
// Try Markdown fallback
|
|
21
|
+
const mdResults = this.backend.scanLineageMd(loopId);
|
|
22
|
+
for (const entry of mdResults) {
|
|
23
|
+
const lineage = entry.loop_lineage ?? {};
|
|
24
|
+
if (lineage.round === roundNum)
|
|
25
|
+
return entry;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const entry = { ...lineageEntries[0] };
|
|
30
|
+
// Enrich with full prompt from Markdown
|
|
31
|
+
if (!entry.full_prompt) {
|
|
32
|
+
const mdContent = this.backend.readLineageMd(loopId, roundNum);
|
|
33
|
+
if (mdContent)
|
|
34
|
+
entry.full_prompt = mdContent;
|
|
35
|
+
}
|
|
36
|
+
// Merge feedback quality_score
|
|
37
|
+
const fbEntries = this.backend.queryEntries({
|
|
38
|
+
prefix,
|
|
39
|
+
feedbackOnly: true,
|
|
40
|
+
});
|
|
41
|
+
if (fbEntries.length) {
|
|
42
|
+
const fbScore = fbEntries[0].quality_score ?? 0;
|
|
43
|
+
if (fbScore) {
|
|
44
|
+
entry.quality_score = fbScore;
|
|
45
|
+
const lineage = (entry.loop_lineage ?? {});
|
|
46
|
+
lineage.quality_score = fbScore;
|
|
47
|
+
entry.loop_lineage = lineage;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return entry;
|
|
51
|
+
}
|
|
52
|
+
// ── Multi-round replay ─────────────────────────────────────────────────
|
|
53
|
+
replay(loopId, opts) {
|
|
54
|
+
const start = opts?.start ?? 1;
|
|
55
|
+
let end = opts?.end;
|
|
56
|
+
if (end === undefined) {
|
|
57
|
+
end = this.maxRound(loopId);
|
|
58
|
+
if (end === 0)
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
const results = [];
|
|
62
|
+
for (let rnd = start; rnd <= end; rnd++) {
|
|
63
|
+
const entry = this.getRound(loopId, rnd);
|
|
64
|
+
if (entry)
|
|
65
|
+
results.push(entry);
|
|
66
|
+
}
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
// ── Timeline ──────────────────────────────────────────────────────────
|
|
70
|
+
timeline(loopId) {
|
|
71
|
+
const entries = this.replay(loopId);
|
|
72
|
+
const timeline = [];
|
|
73
|
+
for (const entry of entries) {
|
|
74
|
+
const lineage = (entry.loop_lineage ?? {});
|
|
75
|
+
timeline.push({
|
|
76
|
+
round: lineage.round ?? 0,
|
|
77
|
+
recompile_level: lineage.recompile_level ?? "l2",
|
|
78
|
+
technique_used: entry.technique_used ?? lineage.technique_used ?? "",
|
|
79
|
+
quality_score: entry.quality_score ?? lineage.quality_score ?? 0,
|
|
80
|
+
task: lineage.task ?? entry.task ?? "",
|
|
81
|
+
goal_id: lineage.goal_id ?? "",
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
timeline.sort((a, b) => a.round - b.round);
|
|
85
|
+
return timeline;
|
|
86
|
+
}
|
|
87
|
+
// ── Diff ───────────────────────────────────────────────────────────────
|
|
88
|
+
diff(loopId, roundA, roundB) {
|
|
89
|
+
const entryA = this.getRound(loopId, roundA);
|
|
90
|
+
const entryB = this.getRound(loopId, roundB);
|
|
91
|
+
if (entryA === null && entryB === null) {
|
|
92
|
+
return {
|
|
93
|
+
round_a: roundA,
|
|
94
|
+
round_b: roundB,
|
|
95
|
+
changes: [],
|
|
96
|
+
unchanged: [],
|
|
97
|
+
missing: "both",
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (entryA === null) {
|
|
101
|
+
return {
|
|
102
|
+
round_a: roundA,
|
|
103
|
+
round_b: roundB,
|
|
104
|
+
changes: [],
|
|
105
|
+
unchanged: [],
|
|
106
|
+
missing: "round_a",
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (entryB === null) {
|
|
110
|
+
return {
|
|
111
|
+
round_a: roundA,
|
|
112
|
+
round_b: roundB,
|
|
113
|
+
changes: [],
|
|
114
|
+
unchanged: [],
|
|
115
|
+
missing: "round_b",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const lineageA = (entryA.loop_lineage ?? {});
|
|
119
|
+
const lineageB = (entryB.loop_lineage ?? {});
|
|
120
|
+
const fields = [
|
|
121
|
+
["goal_id", "Goal ID"],
|
|
122
|
+
["recompile_level", "Recompile Level"],
|
|
123
|
+
["technique_used", "Technique"],
|
|
124
|
+
["quality_score", "Quality Score"],
|
|
125
|
+
["task", "Task"],
|
|
126
|
+
];
|
|
127
|
+
const changes = [];
|
|
128
|
+
const unchanged = [];
|
|
129
|
+
for (const [fieldKey, fieldLabel] of fields) {
|
|
130
|
+
const valA = fieldKey in lineageA
|
|
131
|
+
? lineageA[fieldKey]
|
|
132
|
+
: entryA[fieldKey];
|
|
133
|
+
const valB = fieldKey in lineageB
|
|
134
|
+
? lineageB[fieldKey]
|
|
135
|
+
: entryB[fieldKey];
|
|
136
|
+
if (valA !== valB) {
|
|
137
|
+
changes.push({
|
|
138
|
+
field: fieldKey,
|
|
139
|
+
label: fieldLabel,
|
|
140
|
+
before: valA,
|
|
141
|
+
after: valB,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
unchanged.push(fieldKey);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Compare constraints
|
|
149
|
+
const constraintsA = lineageA.constraints_active ?? [];
|
|
150
|
+
const constraintsB = lineageB.constraints_active ?? [];
|
|
151
|
+
const added = constraintsB.filter((c) => !constraintsA.includes(c));
|
|
152
|
+
const removed = constraintsA.filter((c) => !constraintsB.includes(c));
|
|
153
|
+
if (added.length || removed.length) {
|
|
154
|
+
changes.push({
|
|
155
|
+
field: "constraints_active",
|
|
156
|
+
label: "Active Constraints",
|
|
157
|
+
before: constraintsA,
|
|
158
|
+
after: constraintsB,
|
|
159
|
+
added,
|
|
160
|
+
removed,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
else if (JSON.stringify(constraintsA) === JSON.stringify(constraintsB)) {
|
|
164
|
+
unchanged.push("constraints_active");
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
round_a: roundA,
|
|
168
|
+
round_b: roundB,
|
|
169
|
+
changes,
|
|
170
|
+
unchanged,
|
|
171
|
+
missing: null,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
// ── Helpers ─────────────────────────────────────────────────────────────
|
|
175
|
+
maxRound(loopId) {
|
|
176
|
+
const prefix = `loop:${loopId}:r`;
|
|
177
|
+
const entries = this.backend.queryEntries({ prefix });
|
|
178
|
+
let maxR = 0;
|
|
179
|
+
for (const e of entries) {
|
|
180
|
+
const lineage = (e.loop_lineage ?? {});
|
|
181
|
+
const rnd = lineage.round;
|
|
182
|
+
if (typeof rnd === "number" && rnd > maxR)
|
|
183
|
+
maxR = rnd;
|
|
184
|
+
}
|
|
185
|
+
// Also check Markdown fallback
|
|
186
|
+
if (maxR === 0) {
|
|
187
|
+
const mdEntries = this.backend.scanLineageMd(loopId);
|
|
188
|
+
for (const e of mdEntries) {
|
|
189
|
+
const lineage = (e.loop_lineage ?? {});
|
|
190
|
+
const rnd = lineage.round;
|
|
191
|
+
if (typeof rnd === "number" && rnd > maxR)
|
|
192
|
+
maxR = rnd;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return maxR;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../src/replay.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.d.ts","sourceRoot":"","sources":["../../src/tests/adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Tests for adapter: mode routing, input parsing, health line. */
|
|
2
|
+
import { describe, it, beforeEach } from "node:test";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { handle } from "../adapter.js";
|
|
5
|
+
import { createEngine } from "../engine.js";
|
|
6
|
+
import { resetPolicy } from "../policy.js";
|
|
7
|
+
describe("Adapter — handle()", () => {
|
|
8
|
+
beforeEach(() => resetPolicy());
|
|
9
|
+
it("returns error for unknown mode", () => {
|
|
10
|
+
const result = handle('{"task":"audit","mode":"unknown_mode"}');
|
|
11
|
+
const parsed = JSON.parse(result);
|
|
12
|
+
assert.equal(parsed.status, "error");
|
|
13
|
+
assert.ok(parsed.result.error.includes("Unknown mode"));
|
|
14
|
+
});
|
|
15
|
+
it("returns error for empty task", () => {
|
|
16
|
+
const result = handle('{"task":"","mode":"build"}');
|
|
17
|
+
const parsed = JSON.parse(result);
|
|
18
|
+
assert.equal(parsed.status, "error");
|
|
19
|
+
assert.ok(parsed.result.error.includes("Task is required"));
|
|
20
|
+
});
|
|
21
|
+
it("handles build mode", () => {
|
|
22
|
+
const result = handle('{"task":"Audit ERC20","mode":"build"}');
|
|
23
|
+
const parsed = JSON.parse(result);
|
|
24
|
+
assert.equal(parsed.status, "ok");
|
|
25
|
+
assert.ok(parsed.result.prompt_or_overlay.includes("LoopForge Build"));
|
|
26
|
+
assert.ok(parsed.health.startsWith("[PC:"));
|
|
27
|
+
});
|
|
28
|
+
it("handles loop_compile mode", () => {
|
|
29
|
+
const result = handle(JSON.stringify({
|
|
30
|
+
task: "Audit ERC20 token",
|
|
31
|
+
mode: "loop_compile",
|
|
32
|
+
loop_id: "audit-erc20",
|
|
33
|
+
round: 1,
|
|
34
|
+
goal_id: "audit-erc20",
|
|
35
|
+
}));
|
|
36
|
+
const parsed = JSON.parse(result);
|
|
37
|
+
assert.equal(parsed.status, "ok");
|
|
38
|
+
assert.ok(parsed.result.prompt_or_overlay.includes("L2 Compile"));
|
|
39
|
+
assert.ok(parsed.health.includes("PC:"));
|
|
40
|
+
});
|
|
41
|
+
it("handles feedback mode", () => {
|
|
42
|
+
const result = handle(JSON.stringify({
|
|
43
|
+
task: "Audit ERC20",
|
|
44
|
+
mode: "feedback",
|
|
45
|
+
feedback: {
|
|
46
|
+
success: true,
|
|
47
|
+
constraint_violations: [],
|
|
48
|
+
manual_fixes_needed: "",
|
|
49
|
+
output: "All tests passed",
|
|
50
|
+
},
|
|
51
|
+
}));
|
|
52
|
+
const parsed = JSON.parse(result);
|
|
53
|
+
assert.equal(parsed.status, "ok");
|
|
54
|
+
assert.ok(parsed.result.prompt_or_overlay.includes("Feedback Recorded"));
|
|
55
|
+
assert.ok(parsed.result.prompt_or_overlay.includes("5/5"));
|
|
56
|
+
});
|
|
57
|
+
it("returns error for feedback without payload", () => {
|
|
58
|
+
const result = handle('{"task":"Audit","mode":"feedback"}');
|
|
59
|
+
const parsed = JSON.parse(result);
|
|
60
|
+
assert.equal(parsed.status, "error");
|
|
61
|
+
});
|
|
62
|
+
it("handles dict input (not just JSON string)", () => {
|
|
63
|
+
const result = handle({
|
|
64
|
+
task: "Rename function",
|
|
65
|
+
mode: "build",
|
|
66
|
+
});
|
|
67
|
+
const parsed = JSON.parse(result);
|
|
68
|
+
assert.equal(parsed.status, "ok");
|
|
69
|
+
});
|
|
70
|
+
it("health line shows STALLED when circuit breaker tripped", () => {
|
|
71
|
+
// Run enough feedback rounds to trigger circuit breaker
|
|
72
|
+
const result = handle(JSON.stringify({
|
|
73
|
+
task: "Test",
|
|
74
|
+
mode: "feedback",
|
|
75
|
+
feedback: { success: false, constraint_violations: ["error"], manual_fixes_needed: "", output: "failed" },
|
|
76
|
+
}));
|
|
77
|
+
const parsed = JSON.parse(result);
|
|
78
|
+
assert.ok(parsed.health.startsWith("[PC:"));
|
|
79
|
+
});
|
|
80
|
+
it("accepts engine reuse across calls", () => {
|
|
81
|
+
const engine = createEngine();
|
|
82
|
+
const r1 = handle('{"task":"Test 1","mode":"build"}', engine);
|
|
83
|
+
const p1 = JSON.parse(r1);
|
|
84
|
+
assert.equal(p1.status, "ok");
|
|
85
|
+
const r2 = handle('{"task":"Test 2","mode":"build"}', engine);
|
|
86
|
+
const p2 = JSON.parse(r2);
|
|
87
|
+
assert.equal(p2.status, "ok");
|
|
88
|
+
// Engine state persists
|
|
89
|
+
assert.equal(engine.state.call_count, 0); // build doesn't increment call_count
|
|
90
|
+
});
|
|
91
|
+
it("output size guard truncates at 32KB", () => {
|
|
92
|
+
// Generate a large request that produces a large prompt
|
|
93
|
+
const largeTask = "Audit " + "the contract ".repeat(50) + "for security";
|
|
94
|
+
const result = handle(JSON.stringify({
|
|
95
|
+
task: largeTask,
|
|
96
|
+
mode: "build",
|
|
97
|
+
}));
|
|
98
|
+
const parsed = JSON.parse(result);
|
|
99
|
+
const promptLen = parsed.result.prompt_or_overlay.length;
|
|
100
|
+
// Should be under 32KB + some overhead
|
|
101
|
+
assert.ok(promptLen <= 33_000);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=adapter.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.test.js","sourceRoot":"","sources":["../../src/tests/adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.test.d.ts","sourceRoot":"","sources":["../../src/tests/builder.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/** Tests for technique routing and quality scoring. */
|
|
2
|
+
import { describe, it, beforeEach } from "node:test";
|
|
3
|
+
import assert from "node:assert/strict";
|
|
4
|
+
import { routeTechnique, routeTechniqueAdaptive, scoreQuality, extractGlobalConstraints, } from "../builder.js";
|
|
5
|
+
import { resetPolicy } from "../policy.js";
|
|
6
|
+
describe("Builder — Route Technique", () => {
|
|
7
|
+
beforeEach(() => resetPolicy());
|
|
8
|
+
it("routes audit tasks to tree-of-thought (independent, high load)", () => {
|
|
9
|
+
// "audit" is HIGH_LOAD but not CONTINUOUS → independent + high → tree-of-thought
|
|
10
|
+
const analysis = routeTechnique("Audit the ERC20 token for security vulnerabilities");
|
|
11
|
+
assert.equal(analysis.technique, "tree-of-thought");
|
|
12
|
+
assert.equal(analysis.independence, "independent");
|
|
13
|
+
assert.equal(analysis.cognitive_load, "high");
|
|
14
|
+
});
|
|
15
|
+
it("routes rename tasks to zero-shot (independent, low load)", () => {
|
|
16
|
+
const analysis = routeTechnique("Rename getCwd to getCurrentWorkingDirectory");
|
|
17
|
+
assert.equal(analysis.technique, "zero-shot");
|
|
18
|
+
assert.equal(analysis.independence, "independent");
|
|
19
|
+
assert.equal(analysis.cognitive_load, "low");
|
|
20
|
+
});
|
|
21
|
+
it("routes fix tasks to zero-shot (continuous, low load, short task)", () => {
|
|
22
|
+
const analysis = routeTechnique("Fix the bug"); // only 3 words → load low
|
|
23
|
+
assert.equal(analysis.technique, "zero-shot");
|
|
24
|
+
assert.equal(analysis.independence, "continuous");
|
|
25
|
+
});
|
|
26
|
+
it("routes crypto tasks to few-shot-cot (continuous, high)", () => {
|
|
27
|
+
const analysis = routeTechnique("Fix the encryption protocol memory leak in the concurrent handler");
|
|
28
|
+
assert.equal(analysis.technique, "few-shot-cot");
|
|
29
|
+
assert.equal(analysis.independence, "continuous");
|
|
30
|
+
assert.equal(analysis.cognitive_load, "high");
|
|
31
|
+
});
|
|
32
|
+
it("routes simple independent tasks to zero-shot", () => {
|
|
33
|
+
const analysis = routeTechnique("Write a README for the project with basic setup instructions");
|
|
34
|
+
assert.equal(analysis.technique, "zero-shot");
|
|
35
|
+
assert.equal(analysis.independence, "independent");
|
|
36
|
+
assert.equal(analysis.cognitive_load, "low");
|
|
37
|
+
});
|
|
38
|
+
it("includes reference_file in analysis", () => {
|
|
39
|
+
const analysis = routeTechnique("Fix the encryption protocol");
|
|
40
|
+
assert.ok(analysis.reference_file.includes("chain-of-thought"));
|
|
41
|
+
});
|
|
42
|
+
it("defaults to zero-shot on unrecognised combination", () => {
|
|
43
|
+
const analysis = routeTechnique(""); // empty task
|
|
44
|
+
assert.equal(analysis.technique, "zero-shot");
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe("Builder — Score Quality", () => {
|
|
48
|
+
it("returns 5 for success with no violations or fixes", () => {
|
|
49
|
+
assert.equal(scoreQuality({ success: true, constraint_violations: [], manual_fixes_needed: "" }), 5);
|
|
50
|
+
});
|
|
51
|
+
it("returns 4 for success with manual fixes needed but no violations", () => {
|
|
52
|
+
assert.equal(scoreQuality({ success: true, constraint_violations: [], manual_fixes_needed: "fix formatting" }), 4);
|
|
53
|
+
});
|
|
54
|
+
it("returns 3 for success with constraint violations", () => {
|
|
55
|
+
assert.equal(scoreQuality({ success: true, constraint_violations: ["missing check"] }), 3);
|
|
56
|
+
});
|
|
57
|
+
it("returns 2 for failure with constraint violations", () => {
|
|
58
|
+
assert.equal(scoreQuality({ success: false, constraint_violations: ["XSS vulnerability"] }), 2);
|
|
59
|
+
});
|
|
60
|
+
it("returns 1 for failure with no constraint violations", () => {
|
|
61
|
+
assert.equal(scoreQuality({ success: false, constraint_violations: [] }), 1);
|
|
62
|
+
});
|
|
63
|
+
it("returns 0 for null feedback", () => {
|
|
64
|
+
assert.equal(scoreQuality(null), 0);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
describe("Builder — Adaptive routing", () => {
|
|
68
|
+
it("falls back to keyword heuristic when no vault context", () => {
|
|
69
|
+
// "Audit" + "fix" → continuous + high → few-shot-cot
|
|
70
|
+
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", null, "");
|
|
71
|
+
assert.equal(analysis.technique, "few-shot-cot");
|
|
72
|
+
assert.equal(analysis.was_rotated, false);
|
|
73
|
+
});
|
|
74
|
+
it("falls back to keyword heuristic when no loop_id", () => {
|
|
75
|
+
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", { results: [] }, "");
|
|
76
|
+
assert.equal(analysis.technique, "few-shot-cot");
|
|
77
|
+
assert.equal(analysis.was_rotated, false);
|
|
78
|
+
});
|
|
79
|
+
it("does not rotate when quality scores are high", () => {
|
|
80
|
+
const vaultContext = {
|
|
81
|
+
results: [
|
|
82
|
+
{
|
|
83
|
+
loop_lineage: {
|
|
84
|
+
loop_id: "test-loop",
|
|
85
|
+
round: 1,
|
|
86
|
+
quality_score: 5,
|
|
87
|
+
},
|
|
88
|
+
technique_used: "few-shot-cot",
|
|
89
|
+
quality_score: 5,
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
const analysis = routeTechniqueAdaptive("Fix the encryption protocol security audit", vaultContext, "test-loop");
|
|
94
|
+
assert.equal(analysis.technique, "few-shot-cot");
|
|
95
|
+
assert.equal(analysis.was_rotated, false);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe("Builder — Extract Global Constraints", () => {
|
|
99
|
+
it("returns empty array for null input", () => {
|
|
100
|
+
assert.deepEqual(extractGlobalConstraints(null), []);
|
|
101
|
+
});
|
|
102
|
+
it("extracts constraints from global_entries", () => {
|
|
103
|
+
const hydrateResults = {
|
|
104
|
+
global_entries: [
|
|
105
|
+
{ hard_constraints_added: ["no external deps", "stdlib only"] },
|
|
106
|
+
{ hard_constraints_added: ["must pass CI"] },
|
|
107
|
+
],
|
|
108
|
+
};
|
|
109
|
+
const constraints = extractGlobalConstraints(hydrateResults);
|
|
110
|
+
assert.deepEqual(constraints, ["no external deps", "stdlib only", "must pass CI"]);
|
|
111
|
+
});
|
|
112
|
+
it("deduplicates constraints", () => {
|
|
113
|
+
const hydrateResults = {
|
|
114
|
+
global_entries: [
|
|
115
|
+
{ hard_constraints_added: ["no external deps"] },
|
|
116
|
+
{ hard_constraints_added: ["no external deps"] },
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
assert.deepEqual(extractGlobalConstraints(hydrateResults), ["no external deps"]);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=builder.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.test.js","sourceRoot":"","sources":["../../src/tests/builder.test.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACL,cAAc,EACd,sBAAsB,EACtB,YAAY,EACZ,wBAAwB,GAEzB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,UAAU,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IAEhC,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,iFAAiF;QACjF,MAAM,QAAQ,GAAG,cAAc,CAAC,oDAAoD,CAAC,CAAC;QACtF,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;QACpD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,MAAM,QAAQ,GAAG,cAAc,CAAC,6CAA6C,CAAC,CAAC;QAC/E,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,QAAQ,GAAG,cAAc,CAAC,aAAa,CAAC,CAAC,CAAE,0BAA0B;QAC3E,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,QAAQ,GAAG,cAAc,CAAC,mEAAmE,CAAC,CAAC;QACrG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,QAAQ,GAAG,cAAc,CAAC,8DAA8D,CAAC,CAAC;QAChG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,QAAQ,GAAG,cAAc,CAAC,6BAA6B,CAAC,CAAC;QAC/D,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC,CAAE,aAAa;QACnD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACvG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAClG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,qBAAqB,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,qDAAqD;QACrD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,4CAA4C,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAChG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,4CAA4C,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3G,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,YAAY,GAAG;YACnB,OAAO,EAAE;gBACP;oBACE,YAAY,EAAE;wBACZ,OAAO,EAAE,WAAW;wBACpB,KAAK,EAAE,CAAC;wBACR,aAAa,EAAE,CAAC;qBACjB;oBACD,cAAc,EAAE,cAAc;oBAC9B,aAAa,EAAE,CAAC;iBACjB;aACF;SACF,CAAC;QACF,MAAM,QAAQ,GAAG,sBAAsB,CAAC,4CAA4C,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QACjH,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,cAAc,GAAG;YACrB,cAAc,EAAE;gBACd,EAAE,sBAAsB,EAAE,CAAC,kBAAkB,EAAE,aAAa,CAAC,EAAE;gBAC/D,EAAE,sBAAsB,EAAE,CAAC,cAAc,CAAC,EAAE;aAC7C;SACF,CAAC;QACF,MAAM,WAAW,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAC;QAC7D,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,kBAAkB,EAAE,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,cAAc,GAAG;YACrB,cAAc,EAAE;gBACd,EAAE,sBAAsB,EAAE,CAAC,kBAAkB,CAAC,EAAE;gBAChD,EAAE,sBAAsB,EAAE,CAAC,kBAAkB,CAAC,EAAE;aACjD;SACF,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,wBAAwB,CAAC,cAAc,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACnF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.test.d.ts","sourceRoot":"","sources":["../../src/tests/engine.test.ts"],"names":[],"mappings":""}
|