@ruso-0/nreki 6.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/CHANGELOG.md +648 -0
- package/LICENSE +21 -0
- package/README.md +425 -0
- package/dist/ast-navigator.d.ts +29 -0
- package/dist/ast-navigator.d.ts.map +1 -0
- package/dist/ast-navigator.js +279 -0
- package/dist/ast-navigator.js.map +1 -0
- package/dist/ast-sandbox.d.ts +74 -0
- package/dist/ast-sandbox.d.ts.map +1 -0
- package/dist/ast-sandbox.js +242 -0
- package/dist/ast-sandbox.js.map +1 -0
- package/dist/chronos-memory.d.ts +69 -0
- package/dist/chronos-memory.d.ts.map +1 -0
- package/dist/chronos-memory.js +247 -0
- package/dist/chronos-memory.js.map +1 -0
- package/dist/circuit-breaker.d.ts +107 -0
- package/dist/circuit-breaker.d.ts.map +1 -0
- package/dist/circuit-breaker.js +330 -0
- package/dist/circuit-breaker.js.map +1 -0
- package/dist/compressor-advanced.d.ts +80 -0
- package/dist/compressor-advanced.d.ts.map +1 -0
- package/dist/compressor-advanced.js +555 -0
- package/dist/compressor-advanced.js.map +1 -0
- package/dist/compressor.d.ts +81 -0
- package/dist/compressor.d.ts.map +1 -0
- package/dist/compressor.js +227 -0
- package/dist/compressor.js.map +1 -0
- package/dist/database.d.ts +169 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +1029 -0
- package/dist/database.js.map +1 -0
- package/dist/embedder.d.ts +73 -0
- package/dist/embedder.d.ts.map +1 -0
- package/dist/embedder.js +165 -0
- package/dist/embedder.js.map +1 -0
- package/dist/engine.d.ts +224 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +582 -0
- package/dist/engine.js.map +1 -0
- package/dist/hologram/harvester.d.ts +41 -0
- package/dist/hologram/harvester.d.ts.map +1 -0
- package/dist/hologram/harvester.js +129 -0
- package/dist/hologram/harvester.js.map +1 -0
- package/dist/hologram/shadow-cache.d.ts +49 -0
- package/dist/hologram/shadow-cache.d.ts.map +1 -0
- package/dist/hologram/shadow-cache.js +165 -0
- package/dist/hologram/shadow-cache.js.map +1 -0
- package/dist/hologram/shadow-generator.d.ts +32 -0
- package/dist/hologram/shadow-generator.d.ts.map +1 -0
- package/dist/hologram/shadow-generator.js +828 -0
- package/dist/hologram/shadow-generator.js.map +1 -0
- package/dist/hooks/preToolUse.d.ts +63 -0
- package/dist/hooks/preToolUse.d.ts.map +1 -0
- package/dist/hooks/preToolUse.js +103 -0
- package/dist/hooks/preToolUse.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +367 -0
- package/dist/index.js.map +1 -0
- package/dist/kernel/kernel-manager.d.ts +52 -0
- package/dist/kernel/kernel-manager.d.ts.map +1 -0
- package/dist/kernel/kernel-manager.js +197 -0
- package/dist/kernel/kernel-manager.js.map +1 -0
- package/dist/kernel/kernel-worker.d.ts +9 -0
- package/dist/kernel/kernel-worker.d.ts.map +1 -0
- package/dist/kernel/kernel-worker.js +76 -0
- package/dist/kernel/kernel-worker.js.map +1 -0
- package/dist/kernel/nreki-kernel.d.ts +244 -0
- package/dist/kernel/nreki-kernel.d.ts.map +1 -0
- package/dist/kernel/nreki-kernel.js +1656 -0
- package/dist/kernel/nreki-kernel.js.map +1 -0
- package/dist/middleware/circuit-breaker.d.ts +32 -0
- package/dist/middleware/circuit-breaker.d.ts.map +1 -0
- package/dist/middleware/circuit-breaker.js +160 -0
- package/dist/middleware/circuit-breaker.js.map +1 -0
- package/dist/middleware/file-lock.d.ts +33 -0
- package/dist/middleware/file-lock.d.ts.map +1 -0
- package/dist/middleware/file-lock.js +55 -0
- package/dist/middleware/file-lock.js.map +1 -0
- package/dist/middleware/validator.d.ts +26 -0
- package/dist/middleware/validator.d.ts.map +1 -0
- package/dist/middleware/validator.js +39 -0
- package/dist/middleware/validator.js.map +1 -0
- package/dist/monitor.d.ts +94 -0
- package/dist/monitor.d.ts.map +1 -0
- package/dist/monitor.js +221 -0
- package/dist/monitor.js.map +1 -0
- package/dist/parser-pool.d.ts +28 -0
- package/dist/parser-pool.d.ts.map +1 -0
- package/dist/parser-pool.js +81 -0
- package/dist/parser-pool.js.map +1 -0
- package/dist/parser.d.ts +91 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +311 -0
- package/dist/parser.js.map +1 -0
- package/dist/pin-memory.d.ts +35 -0
- package/dist/pin-memory.d.ts.map +1 -0
- package/dist/pin-memory.js +161 -0
- package/dist/pin-memory.js.map +1 -0
- package/dist/repo-map.d.ts +81 -0
- package/dist/repo-map.d.ts.map +1 -0
- package/dist/repo-map.js +550 -0
- package/dist/repo-map.js.map +1 -0
- package/dist/router.d.ts +102 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +1989 -0
- package/dist/router.js.map +1 -0
- package/dist/semantic-edit.d.ts +82 -0
- package/dist/semantic-edit.d.ts.map +1 -0
- package/dist/semantic-edit.js +529 -0
- package/dist/semantic-edit.js.map +1 -0
- package/dist/terminal-filter.d.ts +27 -0
- package/dist/terminal-filter.d.ts.map +1 -0
- package/dist/terminal-filter.js +257 -0
- package/dist/terminal-filter.js.map +1 -0
- package/dist/undo.d.ts +21 -0
- package/dist/undo.d.ts.map +1 -0
- package/dist/undo.js +55 -0
- package/dist/undo.js.map +1 -0
- package/dist/utils/code-tokenizer.d.ts +25 -0
- package/dist/utils/code-tokenizer.d.ts.map +1 -0
- package/dist/utils/code-tokenizer.js +52 -0
- package/dist/utils/code-tokenizer.js.map +1 -0
- package/dist/utils/file-filter.d.ts +23 -0
- package/dist/utils/file-filter.d.ts.map +1 -0
- package/dist/utils/file-filter.js +48 -0
- package/dist/utils/file-filter.js.map +1 -0
- package/dist/utils/imports.d.ts +32 -0
- package/dist/utils/imports.d.ts.map +1 -0
- package/dist/utils/imports.js +155 -0
- package/dist/utils/imports.js.map +1 -0
- package/dist/utils/path-jail.d.ts +27 -0
- package/dist/utils/path-jail.d.ts.map +1 -0
- package/dist/utils/path-jail.js +95 -0
- package/dist/utils/path-jail.js.map +1 -0
- package/dist/utils/read-source.d.ts +18 -0
- package/dist/utils/read-source.d.ts.map +1 -0
- package/dist/utils/read-source.js +22 -0
- package/dist/utils/read-source.js.map +1 -0
- package/dist/utils/safe-parse.d.ts +20 -0
- package/dist/utils/safe-parse.d.ts.map +1 -0
- package/dist/utils/safe-parse.js +25 -0
- package/dist/utils/safe-parse.js.map +1 -0
- package/package.json +75 -0
- package/scripts/download-wasm.js +46 -0
- package/wasm/.gitkeep +0 -0
- package/wasm/tree-sitter-go.wasm +0 -0
- package/wasm/tree-sitter-javascript.wasm +0 -0
- package/wasm/tree-sitter-python.wasm +0 -0
- package/wasm/tree-sitter-typescript.wasm +0 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* circuit-breaker.ts - Detects and stops infinite failure loops.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code often enters loops: write bad code → test → fail → fix →
|
|
5
|
+
* test → fail, repeating 20+ times and burning $5+ in tokens.
|
|
6
|
+
*
|
|
7
|
+
* This module monitors tool call patterns and trips a circuit breaker
|
|
8
|
+
* when it detects:
|
|
9
|
+
* Pattern 1: Same error hash 3+ times in last 10 calls
|
|
10
|
+
* Pattern 2: Same file written 5+ times in last 15 calls
|
|
11
|
+
* Pattern 3: Alternating write→test→fail cycle 3+ times
|
|
12
|
+
* Pattern 4: Per-file failure threshold (3+ errors on same file, even across different actions)
|
|
13
|
+
*/
|
|
14
|
+
import crypto from "crypto";
|
|
15
|
+
import path from "path";
|
|
16
|
+
// ─── Constants ───────────────────────────────────────────────────────
|
|
17
|
+
const MAX_HISTORY = 50;
|
|
18
|
+
const SAME_ERROR_THRESHOLD = 3;
|
|
19
|
+
const SAME_ERROR_WINDOW = 10;
|
|
20
|
+
const SAME_FILE_THRESHOLD = 5;
|
|
21
|
+
const SAME_FILE_WINDOW = 15;
|
|
22
|
+
const WRITE_TEST_FAIL_THRESHOLD = 3;
|
|
23
|
+
const PER_FILE_FAILURE_THRESHOLD = 3;
|
|
24
|
+
const MAX_ESCALATION_LEVEL = 3;
|
|
25
|
+
// Average tokens burned per failed loop iteration (write + test + read error)
|
|
26
|
+
const TOKENS_PER_FAILED_ITERATION = 2000;
|
|
27
|
+
// TTL for history entries (5 minutes)
|
|
28
|
+
const HISTORY_TTL_MS = 300_000;
|
|
29
|
+
// ─── Error Hashing ──────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Extract a stable hash from error output.
|
|
32
|
+
* Normalizes line numbers and timestamps so that the "same" error
|
|
33
|
+
* (e.g., same type error in different locations) hashes identically.
|
|
34
|
+
*/
|
|
35
|
+
export function hashError(errorText) {
|
|
36
|
+
// Normalize: strip line/col numbers, timestamps, ANSI codes, addresses
|
|
37
|
+
const normalized = errorText
|
|
38
|
+
.replace(/\x1b\[[0-9;]*[A-Za-z]/g, "") // ANSI
|
|
39
|
+
.replace(/\d{4}-\d{2}-\d{2}T[\d:.]+Z?/g, "[TIME]") // ISO timestamps
|
|
40
|
+
.replace(/:\d+:\d+/g, ":[L]:[C]") // line:col
|
|
41
|
+
.replace(/line \d+/gi, "line N") // "line 42"
|
|
42
|
+
.replace(/\d{13,}/g, "[TS]") // epoch timestamps
|
|
43
|
+
.replace(/0x[a-fA-F0-9]+/gi, "[MEM]") // memory addresses
|
|
44
|
+
.trim();
|
|
45
|
+
return crypto.createHash("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Detect if text contains error patterns.
|
|
49
|
+
* Returns true if the text looks like an error output.
|
|
50
|
+
*/
|
|
51
|
+
export function containsError(text) {
|
|
52
|
+
// High-confidence patterns: a single match is sufficient
|
|
53
|
+
const STRONG_PATTERNS = [
|
|
54
|
+
/error\s+TS\d+/i,
|
|
55
|
+
/npm\s+(?:ERR!|error)/im,
|
|
56
|
+
/(?:FAIL|✕|×|✗)\s+/,
|
|
57
|
+
/ExitCode:\s*[1-9]/,
|
|
58
|
+
/Process exited with code [1-9]/,
|
|
59
|
+
/Command failed/i,
|
|
60
|
+
/Build failed/i,
|
|
61
|
+
/Tests?\s+failed/i,
|
|
62
|
+
];
|
|
63
|
+
if (STRONG_PATTERNS.some((re) => re.test(text)))
|
|
64
|
+
return true;
|
|
65
|
+
// Weak patterns: may appear in comments, strings, or docs - require 2+ matches
|
|
66
|
+
const WEAK_PATTERNS = [
|
|
67
|
+
/^\w*Error:/m,
|
|
68
|
+
/SyntaxError:/,
|
|
69
|
+
/TypeError:/,
|
|
70
|
+
/ReferenceError:/,
|
|
71
|
+
/Cannot find module/,
|
|
72
|
+
/ENOENT/,
|
|
73
|
+
];
|
|
74
|
+
const weakMatches = WEAK_PATTERNS.filter((re) => re.test(text)).length;
|
|
75
|
+
return weakMatches >= 2;
|
|
76
|
+
}
|
|
77
|
+
// ─── Circuit Breaker ────────────────────────────────────────────────
|
|
78
|
+
export class CircuitBreaker {
|
|
79
|
+
state = {
|
|
80
|
+
history: [],
|
|
81
|
+
tripped: false,
|
|
82
|
+
tripReason: null,
|
|
83
|
+
consecutiveFailures: 0,
|
|
84
|
+
perFileFailures: new Map(),
|
|
85
|
+
escalationLevel: 0,
|
|
86
|
+
lastTrippedFile: null,
|
|
87
|
+
lastTrippedSymbol: null,
|
|
88
|
+
lastErrorPattern: null,
|
|
89
|
+
};
|
|
90
|
+
stats = {
|
|
91
|
+
totalToolCalls: 0,
|
|
92
|
+
loopsDetected: 0,
|
|
93
|
+
loopsPrevented: 0,
|
|
94
|
+
estimatedTokensSaved: 0,
|
|
95
|
+
sessionStartTime: Date.now(),
|
|
96
|
+
redirectsIssued: 0,
|
|
97
|
+
redirectsSuccessful: 0,
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Record a tool call and check for loop patterns.
|
|
101
|
+
* Returns a LoopCheckResult indicating whether the breaker tripped.
|
|
102
|
+
*/
|
|
103
|
+
recordToolCall(toolName, result, filePath, symbolName, isError) {
|
|
104
|
+
const hasError = isError ?? containsError(result);
|
|
105
|
+
const errorHash = hasError ? hashError(result) : null;
|
|
106
|
+
// Normalize path to absolute + forward slashes - prevents split counters
|
|
107
|
+
// when the same file arrives as "src/app.ts" vs "/Users/.../src/app.ts"
|
|
108
|
+
const normalizedPath = filePath
|
|
109
|
+
? path.resolve(process.cwd(), filePath).replace(/\\/g, "/")
|
|
110
|
+
: null;
|
|
111
|
+
const record = {
|
|
112
|
+
toolName,
|
|
113
|
+
timestamp: Date.now(),
|
|
114
|
+
errorHash,
|
|
115
|
+
filePath: normalizedPath,
|
|
116
|
+
symbolName: symbolName ?? null,
|
|
117
|
+
};
|
|
118
|
+
// Ring buffer: keep last MAX_HISTORY entries
|
|
119
|
+
this.state.history.push(record);
|
|
120
|
+
if (this.state.history.length > MAX_HISTORY) {
|
|
121
|
+
this.state.history = this.state.history.slice(-MAX_HISTORY);
|
|
122
|
+
}
|
|
123
|
+
this.stats.totalToolCalls++;
|
|
124
|
+
// Track consecutive failures
|
|
125
|
+
if (hasError) {
|
|
126
|
+
this.state.consecutiveFailures++;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.state.consecutiveFailures = 0;
|
|
130
|
+
// Success after a redirect means the redirect worked
|
|
131
|
+
if (this.state.escalationLevel > 0) {
|
|
132
|
+
this.stats.redirectsSuccessful++;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Track per-file failures (prevents bypass via action alternation)
|
|
136
|
+
if (normalizedPath) {
|
|
137
|
+
if (hasError) {
|
|
138
|
+
const current = this.state.perFileFailures.get(normalizedPath) ?? 0;
|
|
139
|
+
this.state.perFileFailures.set(normalizedPath, current + 1);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// Success on a file resets that file's counter
|
|
143
|
+
this.state.perFileFailures.delete(normalizedPath);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Check for loop patterns
|
|
147
|
+
return this.checkForLoop();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Check the history for loop patterns.
|
|
151
|
+
*/
|
|
152
|
+
checkForLoop() {
|
|
153
|
+
// If already tripped, stay tripped
|
|
154
|
+
if (this.state.tripped) {
|
|
155
|
+
return {
|
|
156
|
+
tripped: true,
|
|
157
|
+
reason: this.state.tripReason,
|
|
158
|
+
level: this.state.escalationLevel,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// TTL eviction: remove entries older than 5 minutes
|
|
162
|
+
const now = Date.now();
|
|
163
|
+
this.state.history = this.state.history.filter((r) => now - r.timestamp <= HISTORY_TTL_MS);
|
|
164
|
+
const history = this.state.history;
|
|
165
|
+
// Pattern 1: Same error hash appears 3+ times in last 10 calls
|
|
166
|
+
const recentErrors = history.slice(-SAME_ERROR_WINDOW);
|
|
167
|
+
const errorCounts = new Map();
|
|
168
|
+
for (const record of recentErrors) {
|
|
169
|
+
if (record.errorHash) {
|
|
170
|
+
const entry = errorCounts.get(record.errorHash) || { count: 0, file: null };
|
|
171
|
+
entry.count++;
|
|
172
|
+
if (record.filePath)
|
|
173
|
+
entry.file = record.filePath;
|
|
174
|
+
errorCounts.set(record.errorHash, entry);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
for (const [, entry] of errorCounts) {
|
|
178
|
+
if (entry.count >= SAME_ERROR_THRESHOLD) {
|
|
179
|
+
const fileHint = entry.file ? ` on ${entry.file}` : "";
|
|
180
|
+
return this.trip(`Same error repeated ${entry.count} times${fileHint}. ` +
|
|
181
|
+
`Stop and ask the human for guidance.`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Pattern 2: Same file written 5+ times in last 15 calls
|
|
185
|
+
const recentWrites = history.slice(-SAME_FILE_WINDOW);
|
|
186
|
+
const fileCounts = new Map();
|
|
187
|
+
for (const record of recentWrites) {
|
|
188
|
+
if (record.filePath) {
|
|
189
|
+
fileCounts.set(record.filePath, (fileCounts.get(record.filePath) || 0) + 1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
for (const [file, count] of fileCounts) {
|
|
193
|
+
if (count >= SAME_FILE_THRESHOLD) {
|
|
194
|
+
return this.trip(`File ${file} modified ${count} times in last ${SAME_FILE_WINDOW} calls. ` +
|
|
195
|
+
`Likely stuck in a loop. Stop and ask the human for guidance.`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// Pattern 3: Alternating write→test→fail pattern 3+ times
|
|
199
|
+
const writeTestFailCount = this.countWriteTestFailCycles();
|
|
200
|
+
if (writeTestFailCount >= WRITE_TEST_FAIL_THRESHOLD) {
|
|
201
|
+
return this.trip(`Write→test→fail cycle detected ${writeTestFailCount} times. ` +
|
|
202
|
+
`Stop and ask the human for guidance.`);
|
|
203
|
+
}
|
|
204
|
+
// Pattern 4: Per-file failure threshold (prevents bypass via action alternation)
|
|
205
|
+
for (const [file, count] of this.state.perFileFailures) {
|
|
206
|
+
if (count >= PER_FILE_FAILURE_THRESHOLD) {
|
|
207
|
+
return this.trip(`File ${file} has failed ${count} consecutive times across different tool calls. ` +
|
|
208
|
+
`Stop and ask the human for guidance.`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return { tripped: false, reason: "", level: 0 };
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Count write→test→fail cycles in recent history.
|
|
215
|
+
* A cycle is: a call with a filePath (write), followed by a call
|
|
216
|
+
* that looks like a test/build, followed by a call with an error.
|
|
217
|
+
*/
|
|
218
|
+
countWriteTestFailCycles() {
|
|
219
|
+
const history = this.state.history;
|
|
220
|
+
let cycles = 0;
|
|
221
|
+
let i = 0;
|
|
222
|
+
while (i < history.length - 2) {
|
|
223
|
+
const step1 = history[i];
|
|
224
|
+
const step2 = history[i + 1];
|
|
225
|
+
const step3 = history[i + 2];
|
|
226
|
+
const isWrite = step1.filePath !== null;
|
|
227
|
+
const isTest = this.isTestLikeCall(step2);
|
|
228
|
+
const isFail = step3.errorHash !== null;
|
|
229
|
+
if (isWrite && isTest && isFail) {
|
|
230
|
+
cycles++;
|
|
231
|
+
i += 3; // skip past this cycle
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
i++;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return cycles;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Heuristic: does this tool call look like a test/build invocation?
|
|
241
|
+
*/
|
|
242
|
+
isTestLikeCall(record) {
|
|
243
|
+
const testTools = ["bash", "terminal", "nreki_terminal", "run_command"];
|
|
244
|
+
return testTools.includes(record.toolName.toLowerCase()) || record.errorHash !== null;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Trip the circuit breaker.
|
|
248
|
+
*/
|
|
249
|
+
trip(reason) {
|
|
250
|
+
const newLevel = Math.min(this.state.escalationLevel + 1, MAX_ESCALATION_LEVEL);
|
|
251
|
+
this.state.escalationLevel = newLevel;
|
|
252
|
+
this.state.tripped = true;
|
|
253
|
+
this.state.tripReason = reason;
|
|
254
|
+
this.state.lastErrorPattern = reason;
|
|
255
|
+
// Capture context from the most recent history entry
|
|
256
|
+
const lastEntry = this.state.history[this.state.history.length - 1];
|
|
257
|
+
this.state.lastTrippedFile = lastEntry?.filePath ?? null;
|
|
258
|
+
this.state.lastTrippedSymbol = lastEntry?.symbolName ?? null;
|
|
259
|
+
this.stats.loopsDetected++;
|
|
260
|
+
this.stats.loopsPrevented++;
|
|
261
|
+
if (newLevel < MAX_ESCALATION_LEVEL) {
|
|
262
|
+
this.stats.redirectsIssued++;
|
|
263
|
+
}
|
|
264
|
+
this.stats.estimatedTokensSaved += 5 * TOKENS_PER_FAILED_ITERATION;
|
|
265
|
+
return { tripped: true, reason, level: newLevel };
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Full reset after human intervention or long inactivity.
|
|
269
|
+
* Clears everything including per-file failure tracking.
|
|
270
|
+
*/
|
|
271
|
+
reset() {
|
|
272
|
+
this.state.tripped = false;
|
|
273
|
+
this.state.tripReason = null;
|
|
274
|
+
this.state.consecutiveFailures = 0;
|
|
275
|
+
this.state.history = [];
|
|
276
|
+
this.state.perFileFailures = new Map();
|
|
277
|
+
this.state.escalationLevel = 0;
|
|
278
|
+
this.state.lastTrippedFile = null;
|
|
279
|
+
this.state.lastTrippedSymbol = null;
|
|
280
|
+
this.state.lastErrorPattern = null;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Soft reset: clear tripped state and purge history of the problematic file.
|
|
284
|
+
* This gives Claude a clean slate (3 real attempts) with the new strategy,
|
|
285
|
+
* while preserving escalationLevel so it escalates if the retry also fails.
|
|
286
|
+
*/
|
|
287
|
+
softReset() {
|
|
288
|
+
this.state.tripped = false;
|
|
289
|
+
this.state.tripReason = null;
|
|
290
|
+
if (this.state.lastTrippedFile) {
|
|
291
|
+
// AMNESIA TOTAL: Remove all history entries for the tripped file.
|
|
292
|
+
// This resets Patterns 1, 2, 3, and 4 for that file,
|
|
293
|
+
// giving Claude 3 clean attempts with the new strategy.
|
|
294
|
+
this.state.history = this.state.history.filter((r) => r.filePath !== this.state.lastTrippedFile);
|
|
295
|
+
this.state.perFileFailures.delete(this.state.lastTrippedFile);
|
|
296
|
+
this.state.consecutiveFailures = 0;
|
|
297
|
+
}
|
|
298
|
+
// NOTE: Do NOT clear escalationLevel - it must persist so the next
|
|
299
|
+
// failure escalates to the next level instead of restarting from 1.
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Get circuit breaker statistics.
|
|
303
|
+
*/
|
|
304
|
+
getStats() {
|
|
305
|
+
return { ...this.stats };
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Get current state (for debugging/inspection).
|
|
309
|
+
*/
|
|
310
|
+
getState() {
|
|
311
|
+
return {
|
|
312
|
+
history: [...this.state.history],
|
|
313
|
+
tripped: this.state.tripped,
|
|
314
|
+
tripReason: this.state.tripReason,
|
|
315
|
+
consecutiveFailures: this.state.consecutiveFailures,
|
|
316
|
+
perFileFailures: new Map(this.state.perFileFailures),
|
|
317
|
+
escalationLevel: this.state.escalationLevel,
|
|
318
|
+
lastTrippedFile: this.state.lastTrippedFile,
|
|
319
|
+
lastTrippedSymbol: this.state.lastTrippedSymbol,
|
|
320
|
+
lastErrorPattern: this.state.lastErrorPattern,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Get the number of records in history (for testing ring buffer).
|
|
325
|
+
*/
|
|
326
|
+
getHistoryLength() {
|
|
327
|
+
return this.state.history.length;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit-breaker.js","sourceRoot":"","sources":["../src/circuit-breaker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* compressor-advanced.ts - LLMLingua-2-inspired token-level compression.
|
|
3
|
+
*
|
|
4
|
+
* Three-stage pipeline:
|
|
5
|
+
* Stage 1: Preprocessing (strip comments, console.log, whitespace)
|
|
6
|
+
* Stage 2: Self-information token filtering (remove predictable tokens)
|
|
7
|
+
* Stage 3: Structural compression (strip function bodies via AST)
|
|
8
|
+
*
|
|
9
|
+
* Three compression levels:
|
|
10
|
+
* - light: Stage 1 only (~50% reduction)
|
|
11
|
+
* - medium: Stage 1 + 2 + key body lines (~75%)
|
|
12
|
+
* - aggressive: Stage 1 + 2 + 3 body stripping (~90-95%)
|
|
13
|
+
*
|
|
14
|
+
* Pure TypeScript - zero native dependencies, zero Python.
|
|
15
|
+
*/
|
|
16
|
+
import { ASTParser } from "./parser.js";
|
|
17
|
+
import { Embedder } from "./embedder.js";
|
|
18
|
+
export type CompressionLevel = "light" | "medium" | "aggressive";
|
|
19
|
+
export interface AdvancedCompressionResult {
|
|
20
|
+
/** Compressed output text. */
|
|
21
|
+
compressed: string;
|
|
22
|
+
/** Original size in characters. */
|
|
23
|
+
originalSize: number;
|
|
24
|
+
/** Compressed size in characters. */
|
|
25
|
+
compressedSize: number;
|
|
26
|
+
/** Compression ratio (0.0 - 1.0). Higher = more compression. */
|
|
27
|
+
ratio: number;
|
|
28
|
+
/** Estimated tokens saved. */
|
|
29
|
+
tokensSaved: number;
|
|
30
|
+
/** Compression level used. */
|
|
31
|
+
level: CompressionLevel;
|
|
32
|
+
/** Per-stage breakdown of chars removed. */
|
|
33
|
+
breakdown: {
|
|
34
|
+
preprocessingReduction: number;
|
|
35
|
+
tokenFilterReduction: number;
|
|
36
|
+
structuralReduction: number;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Strip comments, console statements, debugger, normalize whitespace.
|
|
41
|
+
* Returns cleaned text and number of characters removed.
|
|
42
|
+
*/
|
|
43
|
+
declare function preprocess(content: string, filePath: string): {
|
|
44
|
+
cleaned: string;
|
|
45
|
+
removed: number;
|
|
46
|
+
};
|
|
47
|
+
interface ScoredToken {
|
|
48
|
+
token: string;
|
|
49
|
+
score: number;
|
|
50
|
+
protected: boolean;
|
|
51
|
+
lineBreak: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Score each token by self-information + TF-IDF.
|
|
55
|
+
* Higher score = more important = keep.
|
|
56
|
+
*/
|
|
57
|
+
declare function scoreTokens(text: string, alpha: number): ScoredToken[];
|
|
58
|
+
/**
|
|
59
|
+
* Filter tokens below the threshold percentile.
|
|
60
|
+
* Removal percentiles: light=10%, medium=30%, aggressive=50%.
|
|
61
|
+
*/
|
|
62
|
+
declare function filterTokens(scored: ScoredToken[], level: CompressionLevel): string;
|
|
63
|
+
export declare class AdvancedCompressor {
|
|
64
|
+
private parser;
|
|
65
|
+
private embedder;
|
|
66
|
+
constructor(parser: ASTParser, embedder: Embedder);
|
|
67
|
+
/**
|
|
68
|
+
* Compress content through the 3-stage LLMLingua-2-inspired pipeline.
|
|
69
|
+
*/
|
|
70
|
+
compress(filePath: string, content: string, level?: CompressionLevel): Promise<AdvancedCompressionResult>;
|
|
71
|
+
/**
|
|
72
|
+
* Quick estimate of advanced compression savings.
|
|
73
|
+
*/
|
|
74
|
+
static estimateSavings(fileContent: string, level?: CompressionLevel): {
|
|
75
|
+
estimatedRatio: number;
|
|
76
|
+
estimatedTokensSaved: number;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
export { preprocess, scoreTokens, filterTokens };
|
|
80
|
+
//# sourceMappingURL=compressor-advanced.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compressor-advanced.d.ts","sourceRoot":"","sources":["../src/compressor-advanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEjE,MAAM,WAAW,yBAAyB;IACtC,8BAA8B;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,KAAK,EAAE,gBAAgB,CAAC;IACxB,4CAA4C;IAC5C,SAAS,EAAE;QACP,sBAAsB,EAAE,MAAM,CAAC;QAC/B,oBAAoB,EAAE,MAAM,CAAC;QAC7B,mBAAmB,EAAE,MAAM,CAAC;KAC/B,CAAC;CACL;AAwED;;;GAGG;AACH,iBAAS,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CA6D3F;AA8GD,UAAU,WAAW;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACtB;AAED;;;GAGG;AACH,iBAAS,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CA0E/D;AAED;;;GAGG;AACH,iBAAS,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAgC5E;AAuKD,qBAAa,kBAAkB;IAC3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,QAAQ,CAAW;gBAEf,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ;IAKjD;;OAEG;IACG,QAAQ,CACV,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,gBAA2B,GACnC,OAAO,CAAC,yBAAyB,CAAC;IA+DrC;;OAEG;IACH,MAAM,CAAC,eAAe,CAClB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,gBAA2B,GACnC;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE;CAa9D;AAGD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC"}
|