@yuaone/core 0.9.8 → 0.9.10
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/__tests__/context-manager.test.js +5 -9
- package/dist/__tests__/context-manager.test.js.map +1 -1
- package/dist/agent-coordinator.d.ts +172 -0
- package/dist/agent-coordinator.d.ts.map +1 -0
- package/dist/agent-coordinator.js +390 -0
- package/dist/agent-coordinator.js.map +1 -0
- package/dist/agent-loop.d.ts +83 -39
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +694 -471
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-reputation.d.ts +72 -0
- package/dist/agent-reputation.d.ts.map +1 -0
- package/dist/agent-reputation.js +222 -0
- package/dist/agent-reputation.js.map +1 -0
- package/dist/arch-summarizer.d.ts +48 -0
- package/dist/arch-summarizer.d.ts.map +1 -0
- package/dist/arch-summarizer.js +239 -0
- package/dist/arch-summarizer.js.map +1 -0
- package/dist/autonomous/explicit-planner.d.ts +45 -0
- package/dist/autonomous/explicit-planner.d.ts.map +1 -0
- package/dist/autonomous/explicit-planner.js +99 -0
- package/dist/autonomous/explicit-planner.js.map +1 -0
- package/dist/autonomous/incident-debugger.d.ts +78 -0
- package/dist/autonomous/incident-debugger.d.ts.map +1 -0
- package/dist/autonomous/incident-debugger.js +324 -0
- package/dist/autonomous/incident-debugger.js.map +1 -0
- package/dist/autonomous/index.d.ts +15 -0
- package/dist/autonomous/index.d.ts.map +1 -0
- package/dist/autonomous/index.js +10 -0
- package/dist/autonomous/index.js.map +1 -0
- package/dist/autonomous/patch-tournament.d.ts +82 -0
- package/dist/autonomous/patch-tournament.d.ts.map +1 -0
- package/dist/autonomous/patch-tournament.js +150 -0
- package/dist/autonomous/patch-tournament.js.map +1 -0
- package/dist/autonomous/research-agent.d.ts +66 -0
- package/dist/autonomous/research-agent.d.ts.map +1 -0
- package/dist/autonomous/research-agent.js +210 -0
- package/dist/autonomous/research-agent.js.map +1 -0
- package/dist/autonomous/task-memory.d.ts +63 -0
- package/dist/autonomous/task-memory.d.ts.map +1 -0
- package/dist/autonomous/task-memory.js +143 -0
- package/dist/autonomous/task-memory.js.map +1 -0
- package/dist/budget-governor-v2.d.ts +93 -0
- package/dist/budget-governor-v2.d.ts.map +1 -0
- package/dist/budget-governor-v2.js +345 -0
- package/dist/budget-governor-v2.js.map +1 -0
- package/dist/capability-graph.d.ts +102 -0
- package/dist/capability-graph.d.ts.map +1 -0
- package/dist/capability-graph.js +397 -0
- package/dist/capability-graph.js.map +1 -0
- package/dist/capability-self-model.d.ts +144 -0
- package/dist/capability-self-model.d.ts.map +1 -0
- package/dist/capability-self-model.js +312 -0
- package/dist/capability-self-model.js.map +1 -0
- package/dist/checkpoint-manager.d.ts +94 -0
- package/dist/checkpoint-manager.d.ts.map +1 -0
- package/dist/checkpoint-manager.js +225 -0
- package/dist/checkpoint-manager.js.map +1 -0
- package/dist/continuation-engine.js +1 -1
- package/dist/continuation-engine.js.map +1 -1
- package/dist/dag-orchestrator.d.ts +0 -3
- package/dist/dag-orchestrator.d.ts.map +1 -1
- package/dist/dag-orchestrator.js +0 -1
- package/dist/dag-orchestrator.js.map +1 -1
- package/dist/evidence-chain.d.ts +99 -0
- package/dist/evidence-chain.d.ts.map +1 -0
- package/dist/evidence-chain.js +200 -0
- package/dist/evidence-chain.js.map +1 -0
- package/dist/execution-engine.d.ts.map +1 -1
- package/dist/execution-engine.js +0 -1
- package/dist/execution-engine.js.map +1 -1
- package/dist/failure-signature-memory.d.ts +61 -0
- package/dist/failure-signature-memory.d.ts.map +1 -0
- package/dist/failure-signature-memory.js +278 -0
- package/dist/failure-signature-memory.js.map +1 -0
- package/dist/index.d.ts +52 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -7
- package/dist/index.js.map +1 -1
- package/dist/language-detector.d.ts.map +1 -1
- package/dist/language-detector.js +122 -43
- package/dist/language-detector.js.map +1 -1
- package/dist/llm-client.d.ts +0 -7
- package/dist/llm-client.d.ts.map +1 -1
- package/dist/llm-client.js +29 -113
- package/dist/llm-client.js.map +1 -1
- package/dist/mcp-client.js +1 -1
- package/dist/mcp-client.js.map +1 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +0 -15
- package/dist/memory.js.map +1 -1
- package/dist/meta-learning-collector.d.ts +64 -0
- package/dist/meta-learning-collector.d.ts.map +1 -0
- package/dist/meta-learning-collector.js +169 -0
- package/dist/meta-learning-collector.js.map +1 -0
- package/dist/meta-learning-engine.d.ts +61 -0
- package/dist/meta-learning-engine.d.ts.map +1 -0
- package/dist/meta-learning-engine.js +250 -0
- package/dist/meta-learning-engine.js.map +1 -0
- package/dist/overhead-governor.d.ts +105 -0
- package/dist/overhead-governor.d.ts.map +1 -0
- package/dist/overhead-governor.js +239 -0
- package/dist/overhead-governor.js.map +1 -0
- package/dist/playbook-library.d.ts +75 -0
- package/dist/playbook-library.d.ts.map +1 -0
- package/dist/playbook-library.js +241 -0
- package/dist/playbook-library.js.map +1 -0
- package/dist/project-executive.d.ts +97 -0
- package/dist/project-executive.d.ts.map +1 -0
- package/dist/project-executive.js +223 -0
- package/dist/project-executive.js.map +1 -0
- package/dist/reasoning-adapter.d.ts.map +1 -1
- package/dist/reasoning-adapter.js +11 -36
- package/dist/reasoning-adapter.js.map +1 -1
- package/dist/research-loop.d.ts +79 -0
- package/dist/research-loop.d.ts.map +1 -0
- package/dist/research-loop.js +363 -0
- package/dist/research-loop.js.map +1 -0
- package/dist/resolve-memory-path.d.ts +32 -0
- package/dist/resolve-memory-path.d.ts.map +1 -0
- package/dist/resolve-memory-path.js +97 -0
- package/dist/resolve-memory-path.js.map +1 -0
- package/dist/safe-bounds.d.ts +101 -0
- package/dist/safe-bounds.d.ts.map +1 -0
- package/dist/safe-bounds.js +140 -0
- package/dist/safe-bounds.js.map +1 -0
- package/dist/sandbox-tiers.d.ts +5 -0
- package/dist/sandbox-tiers.d.ts.map +1 -1
- package/dist/sandbox-tiers.js +14 -6
- package/dist/sandbox-tiers.js.map +1 -1
- package/dist/security.d.ts.map +1 -1
- package/dist/security.js +3 -0
- package/dist/security.js.map +1 -1
- package/dist/self-improvement-loop.d.ts +64 -0
- package/dist/self-improvement-loop.d.ts.map +1 -0
- package/dist/self-improvement-loop.js +156 -0
- package/dist/self-improvement-loop.js.map +1 -0
- package/dist/session-persistence.d.ts +5 -0
- package/dist/session-persistence.d.ts.map +1 -1
- package/dist/session-persistence.js +19 -3
- package/dist/session-persistence.js.map +1 -1
- package/dist/skill-loader.d.ts +16 -9
- package/dist/skill-loader.d.ts.map +1 -1
- package/dist/skill-loader.js +52 -116
- package/dist/skill-loader.js.map +1 -1
- package/dist/skill-registry.d.ts +60 -0
- package/dist/skill-registry.d.ts.map +1 -0
- package/dist/skill-registry.js +162 -0
- package/dist/skill-registry.js.map +1 -0
- package/dist/stall-detector.d.ts +56 -0
- package/dist/stall-detector.d.ts.map +1 -0
- package/dist/stall-detector.js +142 -0
- package/dist/stall-detector.js.map +1 -0
- package/dist/strategy-learner.d.ts +57 -0
- package/dist/strategy-learner.d.ts.map +1 -0
- package/dist/strategy-learner.js +160 -0
- package/dist/strategy-learner.js.map +1 -0
- package/dist/strategy-market.d.ts +73 -0
- package/dist/strategy-market.d.ts.map +1 -0
- package/dist/strategy-market.js +200 -0
- package/dist/strategy-market.js.map +1 -0
- package/dist/sub-agent.d.ts +0 -3
- package/dist/sub-agent.d.ts.map +1 -1
- package/dist/sub-agent.js +0 -10
- package/dist/sub-agent.js.map +1 -1
- package/dist/system-prompt.d.ts +0 -2
- package/dist/system-prompt.d.ts.map +1 -1
- package/dist/system-prompt.js +97 -490
- package/dist/system-prompt.js.map +1 -1
- package/dist/task-classifier.d.ts.map +1 -1
- package/dist/task-classifier.js +2 -54
- package/dist/task-classifier.js.map +1 -1
- package/dist/tool-synthesizer.d.ts +149 -0
- package/dist/tool-synthesizer.d.ts.map +1 -0
- package/dist/tool-synthesizer.js +455 -0
- package/dist/tool-synthesizer.js.map +1 -0
- package/dist/trace-pattern-extractor.d.ts +76 -0
- package/dist/trace-pattern-extractor.d.ts.map +1 -0
- package/dist/trace-pattern-extractor.js +321 -0
- package/dist/trace-pattern-extractor.js.map +1 -0
- package/dist/trace-recorder.d.ts +38 -0
- package/dist/trace-recorder.d.ts.map +1 -0
- package/dist/trace-recorder.js +94 -0
- package/dist/trace-recorder.js.map +1 -0
- package/dist/trust-economics.d.ts +50 -0
- package/dist/trust-economics.d.ts.map +1 -0
- package/dist/trust-economics.js +148 -0
- package/dist/trust-economics.js.map +1 -0
- package/dist/types.d.ts +273 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/yuan-md-loader.d.ts +22 -0
- package/dist/yuan-md-loader.d.ts.map +1 -0
- package/dist/yuan-md-loader.js +75 -0
- package/dist/yuan-md-loader.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module skill-registry
|
|
3
|
+
* @description Stores discovered problem-solving patterns as reusable skills.
|
|
4
|
+
*
|
|
5
|
+
* Differentiation from SkillLearner (existing):
|
|
6
|
+
* SkillLearner → learned from ERROR recovery patterns only
|
|
7
|
+
* SkillRegistry → stores ANY successful tool chain pattern (not just error-driven)
|
|
8
|
+
*
|
|
9
|
+
* Storage: ~/.yuan/skills/skill-registry.json
|
|
10
|
+
* Atomic writes.
|
|
11
|
+
*/
|
|
12
|
+
import { EventEmitter } from "events";
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
14
|
+
import { homedir } from "os";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
import { randomUUID } from "crypto";
|
|
17
|
+
// ─── Class ───
|
|
18
|
+
export class SkillRegistry extends EventEmitter {
|
|
19
|
+
storageFile;
|
|
20
|
+
storageDir;
|
|
21
|
+
minSuccessRateToActivate;
|
|
22
|
+
skills;
|
|
23
|
+
constructor(config) {
|
|
24
|
+
super();
|
|
25
|
+
this.storageDir = config?.storageDir ?? join(homedir(), ".yuan", "skills");
|
|
26
|
+
this.storageFile = join(this.storageDir, "skill-registry.json");
|
|
27
|
+
this.minSuccessRateToActivate = config?.minSuccessRateToActivate ?? 0.4;
|
|
28
|
+
this.skills = this._load();
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Register a new skill (or update if same name exists).
|
|
32
|
+
* Emits agent:skill_discovered.
|
|
33
|
+
*/
|
|
34
|
+
register(skill) {
|
|
35
|
+
const existing = this.skills.find((s) => s.name === skill.name);
|
|
36
|
+
let isNew;
|
|
37
|
+
let result;
|
|
38
|
+
if (existing) {
|
|
39
|
+
isNew = false;
|
|
40
|
+
// Update fields but preserve identity and stats
|
|
41
|
+
existing.taskType = skill.taskType;
|
|
42
|
+
existing.pattern = skill.pattern;
|
|
43
|
+
existing.toolSequence = skill.toolSequence;
|
|
44
|
+
existing.triggerKeywords = skill.triggerKeywords;
|
|
45
|
+
existing.successRate = skill.successRate;
|
|
46
|
+
if (skill.sourceSessionId !== undefined) {
|
|
47
|
+
existing.sourceSessionId = skill.sourceSessionId;
|
|
48
|
+
}
|
|
49
|
+
result = existing;
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
isNew = true;
|
|
53
|
+
const now = new Date().toISOString();
|
|
54
|
+
result = {
|
|
55
|
+
id: randomUUID(),
|
|
56
|
+
name: skill.name,
|
|
57
|
+
taskType: skill.taskType,
|
|
58
|
+
pattern: skill.pattern,
|
|
59
|
+
toolSequence: skill.toolSequence,
|
|
60
|
+
triggerKeywords: skill.triggerKeywords,
|
|
61
|
+
successRate: skill.successRate,
|
|
62
|
+
usageCount: 0,
|
|
63
|
+
lastUsed: null,
|
|
64
|
+
deprecated: false,
|
|
65
|
+
createdAt: now,
|
|
66
|
+
sourceSessionId: skill.sourceSessionId,
|
|
67
|
+
};
|
|
68
|
+
this.skills.push(result);
|
|
69
|
+
}
|
|
70
|
+
this._save();
|
|
71
|
+
this.emit("event", {
|
|
72
|
+
kind: "agent:skill_discovered",
|
|
73
|
+
skillId: result.id,
|
|
74
|
+
name: result.name,
|
|
75
|
+
taskType: result.taskType,
|
|
76
|
+
successRate: result.successRate,
|
|
77
|
+
isNew,
|
|
78
|
+
timestamp: Date.now(),
|
|
79
|
+
});
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Record usage outcome. Updates successRate.
|
|
84
|
+
* Deprecates if successRate < 0.2 AND usageCount >= 5.
|
|
85
|
+
* Emits agent:skill_discovered.
|
|
86
|
+
*/
|
|
87
|
+
recordUsage(skillId, success) {
|
|
88
|
+
const skill = this.skills.find((s) => s.id === skillId);
|
|
89
|
+
if (!skill)
|
|
90
|
+
return;
|
|
91
|
+
const n = skill.usageCount + 1;
|
|
92
|
+
skill.successRate = (skill.successRate * (n - 1) + (success ? 1 : 0)) / n;
|
|
93
|
+
skill.usageCount = n;
|
|
94
|
+
skill.lastUsed = new Date().toISOString();
|
|
95
|
+
// Deprecate if successRate drops below 0.2 and has enough data
|
|
96
|
+
if (skill.successRate < 0.2 && skill.usageCount >= 5) {
|
|
97
|
+
skill.deprecated = true;
|
|
98
|
+
}
|
|
99
|
+
this._save();
|
|
100
|
+
this.emit("event", {
|
|
101
|
+
kind: "agent:skill_discovered",
|
|
102
|
+
skillId: skill.id,
|
|
103
|
+
name: skill.name,
|
|
104
|
+
taskType: skill.taskType,
|
|
105
|
+
successRate: skill.successRate,
|
|
106
|
+
isNew: false,
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Find relevant skills by goal text and task type.
|
|
112
|
+
* Returns non-deprecated skills sorted by successRate desc.
|
|
113
|
+
*/
|
|
114
|
+
findRelevant(goal, taskType) {
|
|
115
|
+
const goalLower = goal.toLowerCase();
|
|
116
|
+
return this.skills
|
|
117
|
+
.filter((s) => {
|
|
118
|
+
if (s.deprecated)
|
|
119
|
+
return false;
|
|
120
|
+
if (taskType && s.taskType !== taskType)
|
|
121
|
+
return false;
|
|
122
|
+
// Match any trigger keyword in goal (case-insensitive)
|
|
123
|
+
return s.triggerKeywords.some((kw) => goalLower.includes(kw.toLowerCase()));
|
|
124
|
+
})
|
|
125
|
+
.filter((s) => s.successRate >= this.minSuccessRateToActivate)
|
|
126
|
+
.sort((a, b) => b.successRate - a.successRate);
|
|
127
|
+
}
|
|
128
|
+
/** Get all active (non-deprecated) skills. */
|
|
129
|
+
getActive() {
|
|
130
|
+
return this.skills.filter((s) => !s.deprecated);
|
|
131
|
+
}
|
|
132
|
+
/** Get all skills including deprecated. */
|
|
133
|
+
getAll() {
|
|
134
|
+
return [...this.skills];
|
|
135
|
+
}
|
|
136
|
+
// ─── Internal ───
|
|
137
|
+
_load() {
|
|
138
|
+
try {
|
|
139
|
+
if (!existsSync(this.storageDir)) {
|
|
140
|
+
mkdirSync(this.storageDir, { recursive: true });
|
|
141
|
+
}
|
|
142
|
+
if (!existsSync(this.storageFile))
|
|
143
|
+
return [];
|
|
144
|
+
const raw = readFileSync(this.storageFile, "utf-8");
|
|
145
|
+
return JSON.parse(raw);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
_save() {
|
|
152
|
+
const tmpFile = `${this.storageFile}.tmp`;
|
|
153
|
+
try {
|
|
154
|
+
writeFileSync(tmpFile, JSON.stringify(this.skills, null, 2), "utf-8");
|
|
155
|
+
renameSync(tmpFile, this.storageFile);
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Non-fatal: storage failures should not crash the agent loop
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=skill-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-registry.js","sourceRoot":"","sources":["../src/skill-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module stall-detector
|
|
3
|
+
* @description Detects when an agent task has stalled, based on iteration patterns.
|
|
4
|
+
*
|
|
5
|
+
* Stall types:
|
|
6
|
+
* 1. iteration_overrun: actual iterations > estimated * 2.5
|
|
7
|
+
* 2. repeated_errors: same error signature 3+ times in last 5 iterations
|
|
8
|
+
* 3. no_progress: 5+ consecutive iterations with 0 files changed
|
|
9
|
+
* 4. patch_entropy: same lines modified repeatedly (agent thrashing)
|
|
10
|
+
*
|
|
11
|
+
* Design: purely stateful observer — does NOT affect the main loop.
|
|
12
|
+
* Call check() each iteration. It returns a StallReason or null.
|
|
13
|
+
*/
|
|
14
|
+
export type StallReason = "iteration_overrun" | "repeated_errors" | "no_progress" | "patch_entropy";
|
|
15
|
+
export interface StallCheckResult {
|
|
16
|
+
stalled: boolean;
|
|
17
|
+
reason: StallReason | null;
|
|
18
|
+
detail: string;
|
|
19
|
+
iterationsElapsed: number;
|
|
20
|
+
}
|
|
21
|
+
export interface StallDetectorConfig {
|
|
22
|
+
/** default 2.5 */
|
|
23
|
+
overrunMultiplier?: number;
|
|
24
|
+
/** default 5 iterations */
|
|
25
|
+
repeatedErrorWindow?: number;
|
|
26
|
+
/** default 3 */
|
|
27
|
+
repeatedErrorThreshold?: number;
|
|
28
|
+
/** default 5 iterations */
|
|
29
|
+
noProgressWindow?: number;
|
|
30
|
+
/** default 4 iterations */
|
|
31
|
+
patchEntropyWindow?: number;
|
|
32
|
+
/** default 3 (same file+lines modified 3+ times) */
|
|
33
|
+
patchEntropyThreshold?: number;
|
|
34
|
+
}
|
|
35
|
+
export declare class StallDetector {
|
|
36
|
+
private estimatedIterations;
|
|
37
|
+
private overrunMultiplier;
|
|
38
|
+
private repeatedErrorWindow;
|
|
39
|
+
private repeatedErrorThreshold;
|
|
40
|
+
private noProgressWindow;
|
|
41
|
+
private patchEntropyWindow;
|
|
42
|
+
private patchEntropyThreshold;
|
|
43
|
+
private history;
|
|
44
|
+
constructor(estimatedIterations: number, config?: StallDetectorConfig);
|
|
45
|
+
/**
|
|
46
|
+
* Check for stall at current iteration.
|
|
47
|
+
* @param iteration current 0-based iteration index
|
|
48
|
+
* @param changedFiles files changed this iteration
|
|
49
|
+
* @param errorSignature current repeated error signature (or undefined)
|
|
50
|
+
* @param editedLines optional: Map<filePath, Set<lineNumber>> for patch entropy detection
|
|
51
|
+
*/
|
|
52
|
+
check(iteration: number, changedFiles: string[], errorSignature: string | undefined, editedLines?: Map<string, Set<number>>): StallCheckResult;
|
|
53
|
+
/** Reset state (call when task changes or goal changes) */
|
|
54
|
+
reset(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=stall-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stall-detector.d.ts","sourceRoot":"","sources":["../src/stall-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,WAAW,GACnB,mBAAmB,GACnB,iBAAiB,GACjB,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,mBAAmB;IAClC,kBAAkB;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2BAA2B;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB;IAChB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,2BAA2B;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2BAA2B;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oDAAoD;IACpD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAQD,qBAAa,aAAa;IACxB,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,sBAAsB,CAAS;IACvC,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,qBAAqB,CAAS;IAEtC,OAAO,CAAC,OAAO,CAAyB;gBAE5B,mBAAmB,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,mBAAmB;IAUrE;;;;;;OAMG;IACH,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EAAE,EACtB,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACrC,gBAAgB;IAkHnB,2DAA2D;IAC3D,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module stall-detector
|
|
3
|
+
* @description Detects when an agent task has stalled, based on iteration patterns.
|
|
4
|
+
*
|
|
5
|
+
* Stall types:
|
|
6
|
+
* 1. iteration_overrun: actual iterations > estimated * 2.5
|
|
7
|
+
* 2. repeated_errors: same error signature 3+ times in last 5 iterations
|
|
8
|
+
* 3. no_progress: 5+ consecutive iterations with 0 files changed
|
|
9
|
+
* 4. patch_entropy: same lines modified repeatedly (agent thrashing)
|
|
10
|
+
*
|
|
11
|
+
* Design: purely stateful observer — does NOT affect the main loop.
|
|
12
|
+
* Call check() each iteration. It returns a StallReason or null.
|
|
13
|
+
*/
|
|
14
|
+
export class StallDetector {
|
|
15
|
+
estimatedIterations;
|
|
16
|
+
overrunMultiplier;
|
|
17
|
+
repeatedErrorWindow;
|
|
18
|
+
repeatedErrorThreshold;
|
|
19
|
+
noProgressWindow;
|
|
20
|
+
patchEntropyWindow;
|
|
21
|
+
patchEntropyThreshold;
|
|
22
|
+
history = [];
|
|
23
|
+
constructor(estimatedIterations, config) {
|
|
24
|
+
this.estimatedIterations = estimatedIterations;
|
|
25
|
+
this.overrunMultiplier = config?.overrunMultiplier ?? 2.5;
|
|
26
|
+
this.repeatedErrorWindow = config?.repeatedErrorWindow ?? 5;
|
|
27
|
+
this.repeatedErrorThreshold = config?.repeatedErrorThreshold ?? 3;
|
|
28
|
+
this.noProgressWindow = config?.noProgressWindow ?? 5;
|
|
29
|
+
this.patchEntropyWindow = config?.patchEntropyWindow ?? 4;
|
|
30
|
+
this.patchEntropyThreshold = config?.patchEntropyThreshold ?? 3;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check for stall at current iteration.
|
|
34
|
+
* @param iteration current 0-based iteration index
|
|
35
|
+
* @param changedFiles files changed this iteration
|
|
36
|
+
* @param errorSignature current repeated error signature (or undefined)
|
|
37
|
+
* @param editedLines optional: Map<filePath, Set<lineNumber>> for patch entropy detection
|
|
38
|
+
*/
|
|
39
|
+
check(iteration, changedFiles, errorSignature, editedLines) {
|
|
40
|
+
// Push current iteration record, keep only what we need
|
|
41
|
+
this.history.push({ changedFiles, errorSig: errorSignature, editedLines });
|
|
42
|
+
const maxWindow = Math.max(this.repeatedErrorWindow, this.noProgressWindow, this.patchEntropyWindow);
|
|
43
|
+
if (this.history.length > maxWindow) {
|
|
44
|
+
this.history = this.history.slice(this.history.length - maxWindow);
|
|
45
|
+
}
|
|
46
|
+
// 1. iteration_overrun
|
|
47
|
+
const limit = this.estimatedIterations * this.overrunMultiplier;
|
|
48
|
+
if (iteration > limit) {
|
|
49
|
+
return {
|
|
50
|
+
stalled: true,
|
|
51
|
+
reason: "iteration_overrun",
|
|
52
|
+
detail: `Iteration ${iteration} exceeds estimated ${this.estimatedIterations} × ${this.overrunMultiplier} = ${limit}`,
|
|
53
|
+
iterationsElapsed: iteration,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// 2. repeated_errors
|
|
57
|
+
const errorWindow = this.history.slice(-this.repeatedErrorWindow);
|
|
58
|
+
if (errorSignature !== undefined) {
|
|
59
|
+
const errorCount = errorWindow.filter((r) => r.errorSig !== undefined && r.errorSig === errorSignature).length;
|
|
60
|
+
if (errorCount >= this.repeatedErrorThreshold) {
|
|
61
|
+
return {
|
|
62
|
+
stalled: true,
|
|
63
|
+
reason: "repeated_errors",
|
|
64
|
+
detail: `Error signature "${errorSignature}" appeared ${errorCount} times in last ${this.repeatedErrorWindow} iterations`,
|
|
65
|
+
iterationsElapsed: iteration,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 3. no_progress
|
|
70
|
+
const progressWindow = this.history.slice(-this.noProgressWindow);
|
|
71
|
+
if (progressWindow.length >= this.noProgressWindow &&
|
|
72
|
+
progressWindow.every((r) => r.changedFiles.length === 0)) {
|
|
73
|
+
return {
|
|
74
|
+
stalled: true,
|
|
75
|
+
reason: "no_progress",
|
|
76
|
+
detail: `No files changed in last ${this.noProgressWindow} consecutive iterations`,
|
|
77
|
+
iterationsElapsed: iteration,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
// 4. patch_entropy
|
|
81
|
+
const entropyWindow = this.history.slice(-this.patchEntropyWindow);
|
|
82
|
+
if (entropyWindow.length >= this.patchEntropyWindow) {
|
|
83
|
+
// Count how many times each file appeared in the window
|
|
84
|
+
const fileEditCount = new Map();
|
|
85
|
+
for (const record of entropyWindow) {
|
|
86
|
+
for (const f of record.changedFiles) {
|
|
87
|
+
fileEditCount.set(f, (fileEditCount.get(f) ?? 0) + 1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [file, count] of fileEditCount) {
|
|
91
|
+
if (count >= this.patchEntropyThreshold) {
|
|
92
|
+
// Check for overlapping line numbers if editedLines data is available
|
|
93
|
+
const recordsWithLines = entropyWindow.filter((r) => r.editedLines !== undefined && r.editedLines.has(file));
|
|
94
|
+
if (recordsWithLines.length >= 2) {
|
|
95
|
+
// Find overlapping line numbers across successive edits
|
|
96
|
+
let hasOverlap = false;
|
|
97
|
+
for (let i = 0; i < recordsWithLines.length - 1; i++) {
|
|
98
|
+
const linesA = recordsWithLines[i].editedLines.get(file);
|
|
99
|
+
const linesB = recordsWithLines[i + 1].editedLines.get(file);
|
|
100
|
+
for (const line of linesA) {
|
|
101
|
+
if (linesB.has(line)) {
|
|
102
|
+
hasOverlap = true;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (hasOverlap)
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
if (hasOverlap) {
|
|
110
|
+
return {
|
|
111
|
+
stalled: true,
|
|
112
|
+
reason: "patch_entropy",
|
|
113
|
+
detail: `File "${file}" edited ${count} times in last ${this.patchEntropyWindow} iterations with overlapping line numbers (agent thrashing)`,
|
|
114
|
+
iterationsElapsed: iteration,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// No line info: stall purely on edit frequency
|
|
120
|
+
return {
|
|
121
|
+
stalled: true,
|
|
122
|
+
reason: "patch_entropy",
|
|
123
|
+
detail: `File "${file}" edited ${count} times in last ${this.patchEntropyWindow} iterations (no line data; frequency threshold exceeded)`,
|
|
124
|
+
iterationsElapsed: iteration,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
stalled: false,
|
|
132
|
+
reason: null,
|
|
133
|
+
detail: "",
|
|
134
|
+
iterationsElapsed: iteration,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** Reset state (call when task changes or goal changes) */
|
|
138
|
+
reset() {
|
|
139
|
+
this.history = [];
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=stall-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stall-detector.js","sourceRoot":"","sources":["../src/stall-detector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module strategy-learner
|
|
3
|
+
* @description Tracks playbook performance metrics and ranks strategies.
|
|
4
|
+
* Complements PlaybookLibrary (which stores templates) by tracking runtime metrics.
|
|
5
|
+
*
|
|
6
|
+
* Differentiation from SelfImprovementLoop:
|
|
7
|
+
* SelfImprovementLoop → strategy outcome proposals
|
|
8
|
+
* StrategyLearner → playbook performance metrics + ranking
|
|
9
|
+
*
|
|
10
|
+
* Storage: ~/.yuan/strategy/strategy-metrics.json
|
|
11
|
+
* Atomic writes (.tmp → renameSync).
|
|
12
|
+
*/
|
|
13
|
+
import { EventEmitter } from "events";
|
|
14
|
+
export interface StrategyMetric {
|
|
15
|
+
playbookId: string;
|
|
16
|
+
taskType: string;
|
|
17
|
+
successCount: number;
|
|
18
|
+
failureCount: number;
|
|
19
|
+
avgIterations: number;
|
|
20
|
+
avgTokensUsed: number;
|
|
21
|
+
lastUsedAt: string;
|
|
22
|
+
confidence: number;
|
|
23
|
+
}
|
|
24
|
+
export interface StrategyRanking {
|
|
25
|
+
playbookId: string;
|
|
26
|
+
taskType: string;
|
|
27
|
+
rank: number;
|
|
28
|
+
score: number;
|
|
29
|
+
recommendation: string;
|
|
30
|
+
}
|
|
31
|
+
export interface StrategyLearnerConfig {
|
|
32
|
+
storageDir?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare class StrategyLearner extends EventEmitter {
|
|
35
|
+
private readonly storageFile;
|
|
36
|
+
private readonly storageDir;
|
|
37
|
+
private metrics;
|
|
38
|
+
constructor(config?: StrategyLearnerConfig);
|
|
39
|
+
/** Record a successful playbook run. Updates avgIterations with running avg. */
|
|
40
|
+
recordSuccess(playbookId: string, taskType: string, iterations: number, tokensUsed: number): void;
|
|
41
|
+
/** Record a failed playbook run. */
|
|
42
|
+
recordFailure(playbookId: string, taskType: string, iterations: number, tokensUsed: number): void;
|
|
43
|
+
/**
|
|
44
|
+
* Rank playbooks for a task type by composite score.
|
|
45
|
+
* Score = confidence * (1 / (normalizedAvgIter + 0.1))
|
|
46
|
+
* Emits agent:strategy_metric_update.
|
|
47
|
+
*/
|
|
48
|
+
rankPlaybooks(taskType?: string): StrategyRanking[];
|
|
49
|
+
/** Get metric for a specific playbook. */
|
|
50
|
+
getMetric(playbookId: string): StrategyMetric | null;
|
|
51
|
+
/** Get all metrics. */
|
|
52
|
+
getAll(): StrategyMetric[];
|
|
53
|
+
private _getOrCreate;
|
|
54
|
+
private _load;
|
|
55
|
+
private _save;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=strategy-learner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-learner.d.ts","sourceRoot":"","sources":["../src/strategy-learner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAOtC,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAuBD,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,OAAO,CAAmB;gBAEtB,MAAM,CAAC,EAAE,qBAAqB;IAO1C,gFAAgF;IAChF,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI;IAWP,oCAAoC;IACpC,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI;IAWP;;;;OAIG;IACH,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE;IA0CnD,0CAA0C;IAC1C,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAIpD,uBAAuB;IACvB,MAAM,IAAI,cAAc,EAAE;IAM1B,OAAO,CAAC,YAAY;IAkBpB,OAAO,CAAC,KAAK;IAab,OAAO,CAAC,KAAK;CASd"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module strategy-learner
|
|
3
|
+
* @description Tracks playbook performance metrics and ranks strategies.
|
|
4
|
+
* Complements PlaybookLibrary (which stores templates) by tracking runtime metrics.
|
|
5
|
+
*
|
|
6
|
+
* Differentiation from SelfImprovementLoop:
|
|
7
|
+
* SelfImprovementLoop → strategy outcome proposals
|
|
8
|
+
* StrategyLearner → playbook performance metrics + ranking
|
|
9
|
+
*
|
|
10
|
+
* Storage: ~/.yuan/strategy/strategy-metrics.json
|
|
11
|
+
* Atomic writes (.tmp → renameSync).
|
|
12
|
+
*/
|
|
13
|
+
import { EventEmitter } from "events";
|
|
14
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
|
|
15
|
+
import { homedir } from "os";
|
|
16
|
+
import { join } from "path";
|
|
17
|
+
// ─── Helpers ───
|
|
18
|
+
function computeConfidence(successCount, failureCount) {
|
|
19
|
+
// Laplace smoothing
|
|
20
|
+
return successCount / (successCount + failureCount + 1);
|
|
21
|
+
}
|
|
22
|
+
function computeScore(confidence, avgIterations) {
|
|
23
|
+
// Penalizes high iteration count; normalizing by 20
|
|
24
|
+
return confidence * (1 / (avgIterations / 20 + 0.1));
|
|
25
|
+
}
|
|
26
|
+
function buildRecommendation(ranking) {
|
|
27
|
+
if (ranking.score >= 5)
|
|
28
|
+
return `Highly recommended (score: ${ranking.score.toFixed(2)})`;
|
|
29
|
+
if (ranking.score >= 2)
|
|
30
|
+
return `Good candidate (score: ${ranking.score.toFixed(2)})`;
|
|
31
|
+
if (ranking.score >= 0.5)
|
|
32
|
+
return `Use with caution (score: ${ranking.score.toFixed(2)})`;
|
|
33
|
+
return `Low confidence — consider alternatives (score: ${ranking.score.toFixed(2)})`;
|
|
34
|
+
}
|
|
35
|
+
// ─── Class ───
|
|
36
|
+
export class StrategyLearner extends EventEmitter {
|
|
37
|
+
storageFile;
|
|
38
|
+
storageDir;
|
|
39
|
+
metrics;
|
|
40
|
+
constructor(config) {
|
|
41
|
+
super();
|
|
42
|
+
this.storageDir = config?.storageDir ?? join(homedir(), ".yuan", "strategy");
|
|
43
|
+
this.storageFile = join(this.storageDir, "strategy-metrics.json");
|
|
44
|
+
this.metrics = this._load();
|
|
45
|
+
}
|
|
46
|
+
/** Record a successful playbook run. Updates avgIterations with running avg. */
|
|
47
|
+
recordSuccess(playbookId, taskType, iterations, tokensUsed) {
|
|
48
|
+
const metric = this._getOrCreate(playbookId, taskType);
|
|
49
|
+
const n = metric.successCount + metric.failureCount + 1;
|
|
50
|
+
metric.avgIterations = (metric.avgIterations * (n - 1) + iterations) / n;
|
|
51
|
+
metric.avgTokensUsed = (metric.avgTokensUsed * (n - 1) + tokensUsed) / n;
|
|
52
|
+
metric.successCount += 1;
|
|
53
|
+
metric.confidence = computeConfidence(metric.successCount, metric.failureCount);
|
|
54
|
+
metric.lastUsedAt = new Date().toISOString();
|
|
55
|
+
this._save();
|
|
56
|
+
}
|
|
57
|
+
/** Record a failed playbook run. */
|
|
58
|
+
recordFailure(playbookId, taskType, iterations, tokensUsed) {
|
|
59
|
+
const metric = this._getOrCreate(playbookId, taskType);
|
|
60
|
+
const n = metric.successCount + metric.failureCount + 1;
|
|
61
|
+
metric.avgIterations = (metric.avgIterations * (n - 1) + iterations) / n;
|
|
62
|
+
metric.avgTokensUsed = (metric.avgTokensUsed * (n - 1) + tokensUsed) / n;
|
|
63
|
+
metric.failureCount += 1;
|
|
64
|
+
metric.confidence = computeConfidence(metric.successCount, metric.failureCount);
|
|
65
|
+
metric.lastUsedAt = new Date().toISOString();
|
|
66
|
+
this._save();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Rank playbooks for a task type by composite score.
|
|
70
|
+
* Score = confidence * (1 / (normalizedAvgIter + 0.1))
|
|
71
|
+
* Emits agent:strategy_metric_update.
|
|
72
|
+
*/
|
|
73
|
+
rankPlaybooks(taskType) {
|
|
74
|
+
const candidates = taskType
|
|
75
|
+
? this.metrics.filter((m) => m.taskType === taskType)
|
|
76
|
+
: [...this.metrics];
|
|
77
|
+
if (candidates.length === 0)
|
|
78
|
+
return [];
|
|
79
|
+
// Compute scores
|
|
80
|
+
const scored = candidates.map((m) => ({
|
|
81
|
+
playbookId: m.playbookId,
|
|
82
|
+
taskType: m.taskType,
|
|
83
|
+
score: computeScore(m.confidence, m.avgIterations),
|
|
84
|
+
}));
|
|
85
|
+
// Sort descending by score
|
|
86
|
+
scored.sort((a, b) => b.score - a.score);
|
|
87
|
+
const rankings = scored.map((s, idx) => {
|
|
88
|
+
const partial = { playbookId: s.playbookId, taskType: s.taskType, rank: idx + 1, score: s.score };
|
|
89
|
+
return {
|
|
90
|
+
...partial,
|
|
91
|
+
recommendation: buildRecommendation(partial),
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
// Emit event for the top metric in the ranking
|
|
95
|
+
if (rankings.length > 0) {
|
|
96
|
+
const top = rankings[0];
|
|
97
|
+
const topMetric = this.metrics.find((m) => m.playbookId === top.playbookId);
|
|
98
|
+
this.emit("event", {
|
|
99
|
+
kind: "agent:strategy_metric_update",
|
|
100
|
+
playbookId: top.playbookId,
|
|
101
|
+
taskType: top.taskType,
|
|
102
|
+
confidence: topMetric?.confidence ?? 0,
|
|
103
|
+
avgIterations: topMetric?.avgIterations ?? 0,
|
|
104
|
+
timestamp: Date.now(),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
return rankings;
|
|
108
|
+
}
|
|
109
|
+
/** Get metric for a specific playbook. */
|
|
110
|
+
getMetric(playbookId) {
|
|
111
|
+
return this.metrics.find((m) => m.playbookId === playbookId) ?? null;
|
|
112
|
+
}
|
|
113
|
+
/** Get all metrics. */
|
|
114
|
+
getAll() {
|
|
115
|
+
return [...this.metrics];
|
|
116
|
+
}
|
|
117
|
+
// ─── Internal ───
|
|
118
|
+
_getOrCreate(playbookId, taskType) {
|
|
119
|
+
let metric = this.metrics.find((m) => m.playbookId === playbookId);
|
|
120
|
+
if (!metric) {
|
|
121
|
+
metric = {
|
|
122
|
+
playbookId,
|
|
123
|
+
taskType,
|
|
124
|
+
successCount: 0,
|
|
125
|
+
failureCount: 0,
|
|
126
|
+
avgIterations: 0,
|
|
127
|
+
avgTokensUsed: 0,
|
|
128
|
+
lastUsedAt: new Date().toISOString(),
|
|
129
|
+
confidence: 0,
|
|
130
|
+
};
|
|
131
|
+
this.metrics.push(metric);
|
|
132
|
+
}
|
|
133
|
+
return metric;
|
|
134
|
+
}
|
|
135
|
+
_load() {
|
|
136
|
+
try {
|
|
137
|
+
if (!existsSync(this.storageDir)) {
|
|
138
|
+
mkdirSync(this.storageDir, { recursive: true });
|
|
139
|
+
}
|
|
140
|
+
if (!existsSync(this.storageFile))
|
|
141
|
+
return [];
|
|
142
|
+
const raw = readFileSync(this.storageFile, "utf-8");
|
|
143
|
+
return JSON.parse(raw);
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
_save() {
|
|
150
|
+
const tmpFile = `${this.storageFile}.tmp`;
|
|
151
|
+
try {
|
|
152
|
+
writeFileSync(tmpFile, JSON.stringify(this.metrics, null, 2), "utf-8");
|
|
153
|
+
renameSync(tmpFile, this.storageFile);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Non-fatal: storage failures should not crash the agent loop
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=strategy-learner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strategy-learner.js","sourceRoot":"","sources":["../src/strategy-learner.ts"],"names":[],"mappings":"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"}
|