@yuaone/core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent-loop.d.ts +40 -0
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +182 -4
- package/dist/agent-loop.js.map +1 -1
- package/dist/benchmark-runner.d.ts +141 -0
- package/dist/benchmark-runner.d.ts.map +1 -0
- package/dist/benchmark-runner.js +526 -0
- package/dist/benchmark-runner.js.map +1 -0
- package/dist/codebase-context.d.ts +49 -0
- package/dist/codebase-context.d.ts.map +1 -1
- package/dist/codebase-context.js +146 -0
- package/dist/codebase-context.js.map +1 -1
- package/dist/cost-optimizer.d.ts +159 -0
- package/dist/cost-optimizer.d.ts.map +1 -0
- package/dist/cost-optimizer.js +406 -0
- package/dist/cost-optimizer.js.map +1 -0
- package/dist/execution-policy-engine.d.ts +133 -0
- package/dist/execution-policy-engine.d.ts.map +1 -0
- package/dist/execution-policy-engine.js +367 -0
- package/dist/execution-policy-engine.js.map +1 -0
- package/dist/failure-recovery.d.ts +228 -0
- package/dist/failure-recovery.d.ts.map +1 -0
- package/dist/failure-recovery.js +664 -0
- package/dist/failure-recovery.js.map +1 -0
- package/dist/hierarchical-planner.d.ts +69 -1
- package/dist/hierarchical-planner.d.ts.map +1 -1
- package/dist/hierarchical-planner.js +117 -0
- package/dist/hierarchical-planner.js.map +1 -1
- package/dist/impact-analyzer.d.ts +92 -0
- package/dist/impact-analyzer.d.ts.map +1 -0
- package/dist/impact-analyzer.js +615 -0
- package/dist/impact-analyzer.js.map +1 -0
- package/dist/index.d.ts +14 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -1
- package/dist/world-state.d.ts +87 -0
- package/dist/world-state.d.ts.map +1 -0
- package/dist/world-state.js +435 -0
- package/dist/world-state.js.map +1 -0
- package/package.json +11 -21
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module execution-policy-engine
|
|
3
|
+
* @description 실행 정책 엔진 — `.yuan/policy.json` 또는 YUAN.md에서 정책을 로드하여
|
|
4
|
+
* 에이전트의 모든 모듈을 단일 소스에서 구성.
|
|
5
|
+
*
|
|
6
|
+
* 로드 순서: DEFAULT_POLICY → .yuan/policy.json → YUAN.md 오버라이드
|
|
7
|
+
*/
|
|
8
|
+
import { readFile, writeFile, mkdir, rename, access, constants } from "node:fs/promises";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
// ─── Defaults ───
|
|
11
|
+
export const DEFAULT_POLICY = {
|
|
12
|
+
planning: {
|
|
13
|
+
enabled: true,
|
|
14
|
+
threshold: "moderate",
|
|
15
|
+
maxDepth: 3,
|
|
16
|
+
autoReplan: true,
|
|
17
|
+
},
|
|
18
|
+
speculation: {
|
|
19
|
+
enabled: false,
|
|
20
|
+
maxApproaches: 3,
|
|
21
|
+
minComplexity: "complex",
|
|
22
|
+
},
|
|
23
|
+
debate: {
|
|
24
|
+
enabled: false,
|
|
25
|
+
rounds: 3,
|
|
26
|
+
roles: ["coder", "reviewer", "verifier"],
|
|
27
|
+
minComplexity: "moderate",
|
|
28
|
+
},
|
|
29
|
+
verification: {
|
|
30
|
+
depth: "standard",
|
|
31
|
+
strictness: 0.7,
|
|
32
|
+
autoTest: false,
|
|
33
|
+
autoBuild: true,
|
|
34
|
+
autoLint: true,
|
|
35
|
+
},
|
|
36
|
+
cost: {
|
|
37
|
+
maxTokensPerSession: 500_000,
|
|
38
|
+
maxTokensPerIteration: 50_000,
|
|
39
|
+
budgetPerRole: {},
|
|
40
|
+
preferredModel: "standard",
|
|
41
|
+
},
|
|
42
|
+
safety: {
|
|
43
|
+
sandboxTier: 2,
|
|
44
|
+
approvalLevel: "dangerous",
|
|
45
|
+
blockedCommands: ["rm -rf /", "sudo", "mkfs", "dd if=", ":(){:|:&};:"],
|
|
46
|
+
blockedPaths: ["/etc", "/usr", "/bin", "/sbin", "/boot", "/sys", "/proc"],
|
|
47
|
+
secretDetection: true,
|
|
48
|
+
},
|
|
49
|
+
recovery: {
|
|
50
|
+
maxRetries: 3,
|
|
51
|
+
maxStrategySwitches: 3,
|
|
52
|
+
enableRollback: true,
|
|
53
|
+
enableScopeReduce: true,
|
|
54
|
+
escalateThreshold: 2,
|
|
55
|
+
},
|
|
56
|
+
memory: {
|
|
57
|
+
enabled: true,
|
|
58
|
+
autoSavelearnings: true,
|
|
59
|
+
checkpointThreshold: 0.8,
|
|
60
|
+
maxCheckpoints: 5,
|
|
61
|
+
},
|
|
62
|
+
mcp: {
|
|
63
|
+
enabled: false,
|
|
64
|
+
servers: [],
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
// ─── Utilities ───
|
|
68
|
+
const VALID_THRESHOLDS = new Set(["simple", "moderate", "complex"]);
|
|
69
|
+
const VALID_COMPLEXITY = new Set(["moderate", "complex", "massive"]);
|
|
70
|
+
const VALID_DEPTH = new Set(["shallow", "standard", "deep"]);
|
|
71
|
+
const VALID_APPROVAL = new Set(["none", "dangerous", "all"]);
|
|
72
|
+
/** Deep merge: source values override target. Arrays are replaced, not concatenated. */
|
|
73
|
+
function deepMerge(target, source) {
|
|
74
|
+
const result = { ...target };
|
|
75
|
+
for (const key of Object.keys(source)) {
|
|
76
|
+
const srcVal = source[key];
|
|
77
|
+
const tgtVal = target[key];
|
|
78
|
+
if (srcVal !== null &&
|
|
79
|
+
srcVal !== undefined &&
|
|
80
|
+
typeof srcVal === "object" &&
|
|
81
|
+
!Array.isArray(srcVal) &&
|
|
82
|
+
typeof tgtVal === "object" &&
|
|
83
|
+
!Array.isArray(tgtVal) &&
|
|
84
|
+
tgtVal !== null) {
|
|
85
|
+
result[key] = deepMerge(tgtVal, srcVal);
|
|
86
|
+
}
|
|
87
|
+
else if (srcVal !== undefined) {
|
|
88
|
+
result[key] = srcVal;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
/** Set a nested value using dot-notation path (e.g. "safety.sandboxTier"). */
|
|
94
|
+
function setNestedValue(obj, dotPath, value) {
|
|
95
|
+
const parts = dotPath.split(".");
|
|
96
|
+
let current = obj;
|
|
97
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
98
|
+
const part = parts[i];
|
|
99
|
+
if (typeof current[part] !== "object" || current[part] === null) {
|
|
100
|
+
current[part] = {};
|
|
101
|
+
}
|
|
102
|
+
current = current[part];
|
|
103
|
+
}
|
|
104
|
+
const lastKey = parts[parts.length - 1];
|
|
105
|
+
current[lastKey] = value;
|
|
106
|
+
}
|
|
107
|
+
/** Coerce a string value to the appropriate JS type. */
|
|
108
|
+
function coerceValue(raw) {
|
|
109
|
+
const trimmed = raw.trim();
|
|
110
|
+
if (trimmed === "true")
|
|
111
|
+
return true;
|
|
112
|
+
if (trimmed === "false")
|
|
113
|
+
return false;
|
|
114
|
+
if (/^-?\d+$/.test(trimmed))
|
|
115
|
+
return parseInt(trimmed, 10);
|
|
116
|
+
if (/^-?\d+\.\d+$/.test(trimmed))
|
|
117
|
+
return parseFloat(trimmed);
|
|
118
|
+
// Strip quotes if present
|
|
119
|
+
if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
120
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))) {
|
|
121
|
+
return trimmed.slice(1, -1);
|
|
122
|
+
}
|
|
123
|
+
return trimmed;
|
|
124
|
+
}
|
|
125
|
+
// ─── Engine ───
|
|
126
|
+
export class ExecutionPolicyEngine {
|
|
127
|
+
policy;
|
|
128
|
+
source;
|
|
129
|
+
projectPath;
|
|
130
|
+
constructor(projectPath) {
|
|
131
|
+
this.projectPath = projectPath;
|
|
132
|
+
this.policy = structuredClone(DEFAULT_POLICY);
|
|
133
|
+
this.source = { type: "default", loadedAt: new Date().toISOString() };
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Load policy: DEFAULT → .yuan/policy.json → YUAN.md overrides.
|
|
137
|
+
*/
|
|
138
|
+
async load() {
|
|
139
|
+
let merged = structuredClone(DEFAULT_POLICY);
|
|
140
|
+
let sourceType = "default";
|
|
141
|
+
let sourcePath;
|
|
142
|
+
// 1. Try .yuan/policy.json
|
|
143
|
+
const policyJsonPath = path.join(this.projectPath, ".yuan", "policy.json");
|
|
144
|
+
try {
|
|
145
|
+
await access(policyJsonPath, constants.R_OK);
|
|
146
|
+
const raw = await readFile(policyJsonPath, "utf-8");
|
|
147
|
+
const parsed = JSON.parse(raw);
|
|
148
|
+
merged = deepMerge(merged, parsed);
|
|
149
|
+
sourceType = "file";
|
|
150
|
+
sourcePath = policyJsonPath;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
// No policy.json — continue with defaults
|
|
154
|
+
}
|
|
155
|
+
// 2. Try YUAN.md overrides
|
|
156
|
+
const yuanMdPath = path.join(this.projectPath, "YUAN.md");
|
|
157
|
+
try {
|
|
158
|
+
await access(yuanMdPath, constants.R_OK);
|
|
159
|
+
const md = await readFile(yuanMdPath, "utf-8");
|
|
160
|
+
const overrides = this.parseYuanMd(md);
|
|
161
|
+
if (Object.keys(overrides).length > 0) {
|
|
162
|
+
merged = deepMerge(merged, overrides);
|
|
163
|
+
if (sourceType === "default") {
|
|
164
|
+
sourceType = "yuanmd";
|
|
165
|
+
sourcePath = yuanMdPath;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// No YUAN.md — continue
|
|
171
|
+
}
|
|
172
|
+
// 3. Validate & store
|
|
173
|
+
const { valid, errors } = ExecutionPolicyEngine.validate(merged);
|
|
174
|
+
if (!valid) {
|
|
175
|
+
throw new Error(`Invalid execution policy:\n${errors.join("\n")}`);
|
|
176
|
+
}
|
|
177
|
+
this.policy = merged;
|
|
178
|
+
this.source = {
|
|
179
|
+
type: sourceType,
|
|
180
|
+
path: sourcePath,
|
|
181
|
+
loadedAt: new Date().toISOString(),
|
|
182
|
+
};
|
|
183
|
+
return this.policy;
|
|
184
|
+
}
|
|
185
|
+
/** Get the full current policy. */
|
|
186
|
+
getPolicy() {
|
|
187
|
+
return this.policy;
|
|
188
|
+
}
|
|
189
|
+
/** Get a specific policy section. */
|
|
190
|
+
get(section) {
|
|
191
|
+
return this.policy[section];
|
|
192
|
+
}
|
|
193
|
+
/** Override a section at runtime (in-memory only, call save() to persist). */
|
|
194
|
+
override(section, values) {
|
|
195
|
+
this.policy[section] = {
|
|
196
|
+
...this.policy[section],
|
|
197
|
+
...values,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/** Save current policy to .yuan/policy.json (atomic write via tmp + rename). */
|
|
201
|
+
async save() {
|
|
202
|
+
const dir = path.join(this.projectPath, ".yuan");
|
|
203
|
+
await mkdir(dir, { recursive: true });
|
|
204
|
+
const target = path.join(dir, "policy.json");
|
|
205
|
+
const tmp = path.join(dir, `policy.json.tmp.${Date.now()}`);
|
|
206
|
+
const content = JSON.stringify(this.policy, null, 2) + "\n";
|
|
207
|
+
await writeFile(tmp, content, "utf-8");
|
|
208
|
+
await rename(tmp, target);
|
|
209
|
+
this.source = {
|
|
210
|
+
type: "file",
|
|
211
|
+
path: target,
|
|
212
|
+
loadedAt: new Date().toISOString(),
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/** Get info about where the policy was loaded from. */
|
|
216
|
+
getSource() {
|
|
217
|
+
return this.source;
|
|
218
|
+
}
|
|
219
|
+
// ─── Static helpers ───
|
|
220
|
+
/** Merge a partial policy with defaults. */
|
|
221
|
+
static mergeWithDefaults(partial) {
|
|
222
|
+
return deepMerge(structuredClone(DEFAULT_POLICY), partial);
|
|
223
|
+
}
|
|
224
|
+
/** Validate policy values (ranges, enums). Returns all errors, not just the first. */
|
|
225
|
+
static validate(policy) {
|
|
226
|
+
const errors = [];
|
|
227
|
+
// planning
|
|
228
|
+
if (!VALID_THRESHOLDS.has(policy.planning.threshold)) {
|
|
229
|
+
errors.push(`planning.threshold must be one of: ${[...VALID_THRESHOLDS].join(", ")} (got "${policy.planning.threshold}")`);
|
|
230
|
+
}
|
|
231
|
+
if (policy.planning.maxDepth < 1) {
|
|
232
|
+
errors.push(`planning.maxDepth must be >= 1 (got ${policy.planning.maxDepth})`);
|
|
233
|
+
}
|
|
234
|
+
// speculation
|
|
235
|
+
if (!VALID_COMPLEXITY.has(policy.speculation.minComplexity)) {
|
|
236
|
+
errors.push(`speculation.minComplexity must be one of: ${[...VALID_COMPLEXITY].join(", ")} (got "${policy.speculation.minComplexity}")`);
|
|
237
|
+
}
|
|
238
|
+
// debate
|
|
239
|
+
if (!VALID_COMPLEXITY.has(policy.debate.minComplexity)) {
|
|
240
|
+
errors.push(`debate.minComplexity must be one of: ${[...VALID_COMPLEXITY].join(", ")} (got "${policy.debate.minComplexity}")`);
|
|
241
|
+
}
|
|
242
|
+
if (policy.debate.rounds < 1) {
|
|
243
|
+
errors.push(`debate.rounds must be >= 1 (got ${policy.debate.rounds})`);
|
|
244
|
+
}
|
|
245
|
+
// verification
|
|
246
|
+
if (!VALID_DEPTH.has(policy.verification.depth)) {
|
|
247
|
+
errors.push(`verification.depth must be one of: ${[...VALID_DEPTH].join(", ")} (got "${policy.verification.depth}")`);
|
|
248
|
+
}
|
|
249
|
+
if (policy.verification.strictness < 0 || policy.verification.strictness > 1) {
|
|
250
|
+
errors.push(`verification.strictness must be 0-1 (got ${policy.verification.strictness})`);
|
|
251
|
+
}
|
|
252
|
+
// cost
|
|
253
|
+
if (policy.cost.maxTokensPerSession <= 0) {
|
|
254
|
+
errors.push(`cost.maxTokensPerSession must be > 0 (got ${policy.cost.maxTokensPerSession})`);
|
|
255
|
+
}
|
|
256
|
+
if (policy.cost.maxTokensPerIteration <= 0) {
|
|
257
|
+
errors.push(`cost.maxTokensPerIteration must be > 0 (got ${policy.cost.maxTokensPerIteration})`);
|
|
258
|
+
}
|
|
259
|
+
// safety
|
|
260
|
+
if (policy.safety.sandboxTier < 0 || policy.safety.sandboxTier > 3) {
|
|
261
|
+
errors.push(`safety.sandboxTier must be 0-3 (got ${policy.safety.sandboxTier})`);
|
|
262
|
+
}
|
|
263
|
+
if (!VALID_APPROVAL.has(policy.safety.approvalLevel)) {
|
|
264
|
+
errors.push(`safety.approvalLevel must be one of: ${[...VALID_APPROVAL].join(", ")} (got "${policy.safety.approvalLevel}")`);
|
|
265
|
+
}
|
|
266
|
+
// recovery
|
|
267
|
+
if (policy.recovery.maxRetries < 0) {
|
|
268
|
+
errors.push(`recovery.maxRetries must be >= 0 (got ${policy.recovery.maxRetries})`);
|
|
269
|
+
}
|
|
270
|
+
if (policy.recovery.escalateThreshold < 0) {
|
|
271
|
+
errors.push(`recovery.escalateThreshold must be >= 0 (got ${policy.recovery.escalateThreshold})`);
|
|
272
|
+
}
|
|
273
|
+
// memory
|
|
274
|
+
if (policy.memory.checkpointThreshold < 0 || policy.memory.checkpointThreshold > 1) {
|
|
275
|
+
errors.push(`memory.checkpointThreshold must be 0-1 (got ${policy.memory.checkpointThreshold})`);
|
|
276
|
+
}
|
|
277
|
+
if (policy.memory.maxCheckpoints < 1) {
|
|
278
|
+
errors.push(`memory.maxCheckpoints must be >= 1 (got ${policy.memory.maxCheckpoints})`);
|
|
279
|
+
}
|
|
280
|
+
return { valid: errors.length === 0, errors };
|
|
281
|
+
}
|
|
282
|
+
// ─── Conversion methods ───
|
|
283
|
+
/** Convert policy → GovernorConfig shape. */
|
|
284
|
+
toGovernorConfig() {
|
|
285
|
+
return {
|
|
286
|
+
planTier: this.policy.cost.preferredModel,
|
|
287
|
+
customLimits: {
|
|
288
|
+
tokensPerRequest: this.policy.cost.maxTokensPerIteration,
|
|
289
|
+
maxIterations: Math.ceil(this.policy.cost.maxTokensPerSession / this.policy.cost.maxTokensPerIteration),
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
/** Convert policy → AutoFixConfig shape. */
|
|
294
|
+
toAutoFixConfig() {
|
|
295
|
+
return {
|
|
296
|
+
maxRetries: this.policy.recovery.maxRetries,
|
|
297
|
+
autoLint: this.policy.verification.autoLint,
|
|
298
|
+
autoTest: this.policy.verification.autoTest,
|
|
299
|
+
autoBuild: this.policy.verification.autoBuild,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/** Convert policy → failure recovery config. */
|
|
303
|
+
toFailureRecoveryConfig() {
|
|
304
|
+
return {
|
|
305
|
+
maxStrategySwitches: this.policy.recovery.maxStrategySwitches,
|
|
306
|
+
enableRollback: this.policy.recovery.enableRollback,
|
|
307
|
+
enableScopeReduce: this.policy.recovery.enableScopeReduce,
|
|
308
|
+
escalateThreshold: this.policy.recovery.escalateThreshold,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/** Convert policy → ContextManagerConfig shape. */
|
|
312
|
+
toContextManagerConfig() {
|
|
313
|
+
return {
|
|
314
|
+
maxContextTokens: this.policy.cost.maxTokensPerSession,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/** Convert policy → ExecutionEngineConfig shape (general-purpose). */
|
|
318
|
+
toExecutionEngineConfig() {
|
|
319
|
+
return {
|
|
320
|
+
planning: this.policy.planning,
|
|
321
|
+
speculation: this.policy.speculation,
|
|
322
|
+
debate: this.policy.debate,
|
|
323
|
+
verification: this.policy.verification,
|
|
324
|
+
safety: {
|
|
325
|
+
sandboxTier: this.policy.safety.sandboxTier,
|
|
326
|
+
approvalLevel: this.policy.safety.approvalLevel,
|
|
327
|
+
secretDetection: this.policy.safety.secretDetection,
|
|
328
|
+
},
|
|
329
|
+
memory: this.policy.memory,
|
|
330
|
+
mcp: this.policy.mcp,
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// ─── Private ───
|
|
334
|
+
/**
|
|
335
|
+
* Parse YUAN.md for policy overrides.
|
|
336
|
+
* Looks for a `## Policy` or `## Configuration` section, then extracts
|
|
337
|
+
* lines matching `- dotted.key: value`.
|
|
338
|
+
*/
|
|
339
|
+
parseYuanMd(content) {
|
|
340
|
+
const overrides = {};
|
|
341
|
+
const lines = content.split("\n");
|
|
342
|
+
let inPolicySection = false;
|
|
343
|
+
for (const line of lines) {
|
|
344
|
+
const trimmed = line.trim();
|
|
345
|
+
// Detect section boundaries
|
|
346
|
+
if (/^##\s+(Policy|Configuration)\s*$/i.test(trimmed)) {
|
|
347
|
+
inPolicySection = true;
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
350
|
+
// Any other H2 ends the section
|
|
351
|
+
if (/^##\s+/.test(trimmed) && inPolicySection) {
|
|
352
|
+
inPolicySection = false;
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (!inPolicySection)
|
|
356
|
+
continue;
|
|
357
|
+
// Match lines like: - planning.threshold: complex
|
|
358
|
+
const match = trimmed.match(/^-\s+([\w.]+)\s*:\s*(.+)$/);
|
|
359
|
+
if (match) {
|
|
360
|
+
const [, dotPath, rawValue] = match;
|
|
361
|
+
setNestedValue(overrides, dotPath, coerceValue(rawValue));
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return overrides;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=execution-policy-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-policy-engine.js","sourceRoot":"","sources":["../src/execution-policy-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module failure-recovery
|
|
3
|
+
* @description Intelligent error recovery on top of AutoFixLoop.
|
|
4
|
+
*
|
|
5
|
+
* While AutoFixLoop handles simple retry loops (validate → fix prompt → retry),
|
|
6
|
+
* FailureRecovery classifies root causes and selects from 5 recovery strategies:
|
|
7
|
+
* 1. retry — same approach, try again
|
|
8
|
+
* 2. rollback — undo changes, restore originals
|
|
9
|
+
* 3. approach_change — different implementation approach
|
|
10
|
+
* 4. scope_reduce — simplify the task
|
|
11
|
+
* 5. escalate — ask user for help
|
|
12
|
+
*
|
|
13
|
+
* Flow:
|
|
14
|
+
* error → analyzeRootCause → selectStrategy → buildRecoveryPrompt
|
|
15
|
+
* → (optionally) executeRollback / buildScopeReduction
|
|
16
|
+
*
|
|
17
|
+
* @see auto-fix.ts for the underlying AutoFixLoop
|
|
18
|
+
* @see 설계 문서 Section 6.4
|
|
19
|
+
*/
|
|
20
|
+
/** Extended error categories beyond AutoFixLoop's basic triggers. */
|
|
21
|
+
export type ErrorCategory = "BUILD_FAIL" | "TEST_FAIL" | "LINT_ERROR" | "RUNTIME_ERROR" | "TYPE_ERROR" | "IMPORT_ERROR" | "PERMISSION_ERROR" | "TIMEOUT" | "RESOURCE_ERROR" | "UNKNOWN";
|
|
22
|
+
/** Available recovery strategies, ordered from least to most disruptive. */
|
|
23
|
+
export type RecoveryStrategy = "retry" | "rollback" | "approach_change" | "scope_reduce" | "escalate";
|
|
24
|
+
/** Root cause analysis result. */
|
|
25
|
+
export interface RootCause {
|
|
26
|
+
/** Error classification */
|
|
27
|
+
category: ErrorCategory;
|
|
28
|
+
/** Human-readable error summary */
|
|
29
|
+
message: string;
|
|
30
|
+
/** File where the error originated */
|
|
31
|
+
file?: string;
|
|
32
|
+
/** Line number of the error */
|
|
33
|
+
line?: number;
|
|
34
|
+
/** Suggested fix or next step */
|
|
35
|
+
suggestion?: string;
|
|
36
|
+
/** Confidence in the classification (0–1) */
|
|
37
|
+
confidence: number;
|
|
38
|
+
}
|
|
39
|
+
/** Decision on which recovery strategy to use. */
|
|
40
|
+
export interface RecoveryDecision {
|
|
41
|
+
/** Selected strategy */
|
|
42
|
+
strategy: RecoveryStrategy;
|
|
43
|
+
/** Why this strategy was chosen */
|
|
44
|
+
reason: string;
|
|
45
|
+
/** Additional context for the strategy */
|
|
46
|
+
context: Record<string, unknown>;
|
|
47
|
+
/** LLM prompt for the chosen strategy */
|
|
48
|
+
prompt?: string;
|
|
49
|
+
}
|
|
50
|
+
/** Full context about a failure, used by strategy selection. */
|
|
51
|
+
export interface FailureContext {
|
|
52
|
+
/** Raw error string */
|
|
53
|
+
error: string;
|
|
54
|
+
/** Tool that produced the error */
|
|
55
|
+
toolName?: string;
|
|
56
|
+
/** Raw tool output */
|
|
57
|
+
toolOutput?: string;
|
|
58
|
+
/** Current attempt number (1-based) */
|
|
59
|
+
attemptNumber: number;
|
|
60
|
+
/** Maximum attempts allowed */
|
|
61
|
+
maxAttempts: number;
|
|
62
|
+
/** Files that were changed during this task */
|
|
63
|
+
changedFiles: string[];
|
|
64
|
+
/** Original file contents before changes (file path → content) */
|
|
65
|
+
originalSnapshots: Map<string, string>;
|
|
66
|
+
/** Strategies already tried for this failure */
|
|
67
|
+
previousStrategies: RecoveryStrategy[];
|
|
68
|
+
}
|
|
69
|
+
/** Configuration for the FailureRecovery system. */
|
|
70
|
+
export interface FailureRecoveryConfig {
|
|
71
|
+
/** Maximum number of strategy switches before escalating (default 3) */
|
|
72
|
+
maxStrategySwitches: number;
|
|
73
|
+
/** Whether rollback is allowed (default true) */
|
|
74
|
+
enableRollback: boolean;
|
|
75
|
+
/** Whether scope reduction is allowed (default true) */
|
|
76
|
+
enableScopeReduce: boolean;
|
|
77
|
+
/** Escalate after this many failed strategies (default 2) */
|
|
78
|
+
escalateThreshold: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* FailureRecovery — Intelligent error recovery with root cause analysis
|
|
82
|
+
* and multi-strategy recovery selection.
|
|
83
|
+
*
|
|
84
|
+
* Sits on top of AutoFixLoop to provide higher-level recovery when
|
|
85
|
+
* simple retries are insufficient.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* const recovery = new FailureRecovery({ maxStrategySwitches: 3 });
|
|
90
|
+
*
|
|
91
|
+
* // Analyze the error
|
|
92
|
+
* const rootCause = recovery.analyzeRootCause(errorOutput, 'shell_exec');
|
|
93
|
+
*
|
|
94
|
+
* // Select a strategy
|
|
95
|
+
* const decision = recovery.selectStrategy(rootCause, failureContext);
|
|
96
|
+
*
|
|
97
|
+
* // Get the recovery prompt for LLM
|
|
98
|
+
* const prompt = recovery.buildRecoveryPrompt(decision, failureContext);
|
|
99
|
+
*
|
|
100
|
+
* // If rollback was selected
|
|
101
|
+
* if (decision.strategy === 'rollback') {
|
|
102
|
+
* await recovery.executeRollback(changedFiles, originalSnapshots);
|
|
103
|
+
* }
|
|
104
|
+
*
|
|
105
|
+
* // Record outcome
|
|
106
|
+
* recovery.recordStrategyResult(decision.strategy, wasSuccessful);
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export declare class FailureRecovery {
|
|
110
|
+
private readonly config;
|
|
111
|
+
private readonly history;
|
|
112
|
+
constructor(config?: Partial<FailureRecoveryConfig>);
|
|
113
|
+
/**
|
|
114
|
+
* Analyze an error string and classify its root cause.
|
|
115
|
+
*
|
|
116
|
+
* Checks against known error patterns in priority order and extracts
|
|
117
|
+
* file/line information when available.
|
|
118
|
+
*
|
|
119
|
+
* @param error Raw error string
|
|
120
|
+
* @param toolName Optional tool that produced the error
|
|
121
|
+
* @returns Root cause analysis with category, confidence, and suggestion
|
|
122
|
+
*/
|
|
123
|
+
analyzeRootCause(error: string, toolName?: string): RootCause;
|
|
124
|
+
/**
|
|
125
|
+
* Select the best recovery strategy based on root cause and context.
|
|
126
|
+
*
|
|
127
|
+
* Strategy selection logic:
|
|
128
|
+
* - Attempt 1 + fixable categories → retry
|
|
129
|
+
* - PERMISSION_ERROR / RESOURCE_ERROR → escalate immediately
|
|
130
|
+
* - Attempt 2+ + rollback not tried → rollback
|
|
131
|
+
* - Rollback tried + approach_change not tried → approach_change
|
|
132
|
+
* - TIMEOUT + attempt 2+ → scope_reduce
|
|
133
|
+
* - Too many strategies tried → escalate
|
|
134
|
+
* - Default → approach_change
|
|
135
|
+
*
|
|
136
|
+
* @param rootCause Analyzed root cause
|
|
137
|
+
* @param context Full failure context
|
|
138
|
+
* @returns Recovery decision with strategy, reason, and optional prompt
|
|
139
|
+
*/
|
|
140
|
+
selectStrategy(rootCause: RootCause, context: FailureContext): RecoveryDecision;
|
|
141
|
+
/**
|
|
142
|
+
* Build an LLM prompt tailored to the selected recovery strategy.
|
|
143
|
+
*
|
|
144
|
+
* Each strategy produces a different prompt style:
|
|
145
|
+
* - retry: focused on the specific error with suggestion
|
|
146
|
+
* - rollback: instructs fresh start after file restoration
|
|
147
|
+
* - approach_change: suggests alternative implementations
|
|
148
|
+
* - scope_reduce: narrows down the task scope
|
|
149
|
+
* - escalate: summarizes the situation for the user
|
|
150
|
+
*
|
|
151
|
+
* @param decision Recovery decision from selectStrategy
|
|
152
|
+
* @param context Full failure context
|
|
153
|
+
* @returns Formatted prompt string
|
|
154
|
+
*/
|
|
155
|
+
buildRecoveryPrompt(decision: RecoveryDecision, context: FailureContext): string;
|
|
156
|
+
/**
|
|
157
|
+
* Execute a rollback by restoring original file contents.
|
|
158
|
+
*
|
|
159
|
+
* Uses atomic writes: writes to a .tmp file first, then renames.
|
|
160
|
+
* This prevents partial writes from corrupting files.
|
|
161
|
+
*
|
|
162
|
+
* @param changedFiles List of file paths to restore
|
|
163
|
+
* @param originalSnapshots Map of file path → original content
|
|
164
|
+
* @returns true if all files were successfully restored
|
|
165
|
+
*/
|
|
166
|
+
executeRollback(changedFiles: string[], originalSnapshots: Map<string, string>): Promise<boolean>;
|
|
167
|
+
/**
|
|
168
|
+
* Build a scope-reduced version of the task description.
|
|
169
|
+
*
|
|
170
|
+
* Strips failed aspects from the original goal and produces
|
|
171
|
+
* a simplified task that avoids the problematic areas.
|
|
172
|
+
*
|
|
173
|
+
* @param originalGoal The original task description
|
|
174
|
+
* @param failedAspects Aspects that failed and should be skipped
|
|
175
|
+
* @returns Scope-reduced task description
|
|
176
|
+
*/
|
|
177
|
+
buildScopeReduction(originalGoal: string, failedAspects: string[]): string;
|
|
178
|
+
/**
|
|
179
|
+
* Record the outcome of a strategy attempt.
|
|
180
|
+
*
|
|
181
|
+
* Used to track success rates and inform future strategy selection.
|
|
182
|
+
*
|
|
183
|
+
* @param strategy The strategy that was attempted
|
|
184
|
+
* @param success Whether it resolved the error
|
|
185
|
+
*/
|
|
186
|
+
recordStrategyResult(strategy: RecoveryStrategy, success: boolean): void;
|
|
187
|
+
/**
|
|
188
|
+
* Reset all state for a new task.
|
|
189
|
+
* Clears strategy history and statistics.
|
|
190
|
+
*/
|
|
191
|
+
reset(): void;
|
|
192
|
+
/**
|
|
193
|
+
* Get statistics about strategy usage and success rate.
|
|
194
|
+
*
|
|
195
|
+
* @returns Object with strategies used, success rate, and current attempt count
|
|
196
|
+
*/
|
|
197
|
+
getStats(): {
|
|
198
|
+
strategiesUsed: RecoveryStrategy[];
|
|
199
|
+
successRate: number;
|
|
200
|
+
currentAttempt: number;
|
|
201
|
+
};
|
|
202
|
+
private buildRetryPrompt;
|
|
203
|
+
private buildRollbackPrompt;
|
|
204
|
+
private buildApproachChangePrompt;
|
|
205
|
+
private buildScopeReducePrompt;
|
|
206
|
+
private buildEscalatePrompt;
|
|
207
|
+
/**
|
|
208
|
+
* Extract file path and line number from an error string.
|
|
209
|
+
* Handles common formats: "file.ts(10,5)", "file.ts:10:5", "(file.ts:10)"
|
|
210
|
+
*/
|
|
211
|
+
private extractFileLocation;
|
|
212
|
+
/**
|
|
213
|
+
* Extract a clean error message from raw output.
|
|
214
|
+
* Takes the first meaningful error line.
|
|
215
|
+
*/
|
|
216
|
+
private extractErrorMessage;
|
|
217
|
+
/**
|
|
218
|
+
* Compute confidence score for a category match.
|
|
219
|
+
* Higher confidence when multiple signals align.
|
|
220
|
+
*/
|
|
221
|
+
private computeConfidence;
|
|
222
|
+
/**
|
|
223
|
+
* Suggest alternative approaches based on the root cause category.
|
|
224
|
+
*/
|
|
225
|
+
private suggestAlternatives;
|
|
226
|
+
private truncate;
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=failure-recovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"failure-recovery.d.ts","sourceRoot":"","sources":["../src/failure-recovery.ts"],"names":[],"mappings":"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"}
|