swarm-engine 1.3.0 → 1.38.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/README.md +45 -7
- package/dist/cli/commands/memory.js +117 -0
- package/dist/cli/commands/memory.js.map +1 -1
- package/dist/core/types.d.ts +30 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -1
- package/dist/memory/index.d.ts +37 -0
- package/dist/memory/index.d.ts.map +1 -1
- package/dist/memory/index.js +97 -0
- package/dist/memory/index.js.map +1 -1
- package/dist/runtime/agent-runner.d.ts +10 -0
- package/dist/runtime/agent-runner.d.ts.map +1 -1
- package/dist/runtime/agent-runner.js +71 -3
- package/dist/runtime/agent-runner.js.map +1 -1
- package/dist/runtime/engine.d.ts +18 -0
- package/dist/runtime/engine.d.ts.map +1 -1
- package/dist/runtime/engine.js +306 -2
- package/dist/runtime/engine.js.map +1 -1
- package/dist/runtime/execution-graph.d.ts +86 -0
- package/dist/runtime/execution-graph.d.ts.map +1 -0
- package/dist/runtime/execution-graph.js +441 -0
- package/dist/runtime/execution-graph.js.map +1 -0
- package/dist/runtime/graph-adversarial.d.ts +88 -0
- package/dist/runtime/graph-adversarial.d.ts.map +1 -0
- package/dist/runtime/graph-adversarial.js +378 -0
- package/dist/runtime/graph-adversarial.js.map +1 -0
- package/dist/runtime/graph-analyzer.d.ts +106 -0
- package/dist/runtime/graph-analyzer.d.ts.map +1 -0
- package/dist/runtime/graph-analyzer.js +321 -0
- package/dist/runtime/graph-analyzer.js.map +1 -0
- package/dist/runtime/graph-causal.d.ts +91 -0
- package/dist/runtime/graph-causal.d.ts.map +1 -0
- package/dist/runtime/graph-causal.js +292 -0
- package/dist/runtime/graph-causal.js.map +1 -0
- package/dist/runtime/graph-context-router.d.ts +73 -0
- package/dist/runtime/graph-context-router.d.ts.map +1 -0
- package/dist/runtime/graph-context-router.js +162 -0
- package/dist/runtime/graph-context-router.js.map +1 -0
- package/dist/runtime/graph-discovery.d.ts +71 -0
- package/dist/runtime/graph-discovery.d.ts.map +1 -0
- package/dist/runtime/graph-discovery.js +367 -0
- package/dist/runtime/graph-discovery.js.map +1 -0
- package/dist/runtime/graph-dropout.d.ts +59 -0
- package/dist/runtime/graph-dropout.d.ts.map +1 -0
- package/dist/runtime/graph-dropout.js +196 -0
- package/dist/runtime/graph-dropout.js.map +1 -0
- package/dist/runtime/graph-embeddings.d.ts +58 -0
- package/dist/runtime/graph-embeddings.d.ts.map +1 -0
- package/dist/runtime/graph-embeddings.js +301 -0
- package/dist/runtime/graph-embeddings.js.map +1 -0
- package/dist/runtime/graph-feedback.d.ts +30 -0
- package/dist/runtime/graph-feedback.d.ts.map +1 -0
- package/dist/runtime/graph-feedback.js +82 -0
- package/dist/runtime/graph-feedback.js.map +1 -0
- package/dist/runtime/graph-gnn.d.ts +120 -0
- package/dist/runtime/graph-gnn.d.ts.map +1 -0
- package/dist/runtime/graph-gnn.js +524 -0
- package/dist/runtime/graph-gnn.js.map +1 -0
- package/dist/runtime/graph-learner.d.ts +70 -0
- package/dist/runtime/graph-learner.d.ts.map +1 -0
- package/dist/runtime/graph-learner.js +265 -0
- package/dist/runtime/graph-learner.js.map +1 -0
- package/dist/runtime/graph-meta-adversarial.d.ts +113 -0
- package/dist/runtime/graph-meta-adversarial.d.ts.map +1 -0
- package/dist/runtime/graph-meta-adversarial.js +366 -0
- package/dist/runtime/graph-meta-adversarial.js.map +1 -0
- package/dist/runtime/graph-meta.d.ts +115 -0
- package/dist/runtime/graph-meta.d.ts.map +1 -0
- package/dist/runtime/graph-meta.js +437 -0
- package/dist/runtime/graph-meta.js.map +1 -0
- package/dist/runtime/graph-self-evolve.d.ts +92 -0
- package/dist/runtime/graph-self-evolve.d.ts.map +1 -0
- package/dist/runtime/graph-self-evolve.js +422 -0
- package/dist/runtime/graph-self-evolve.js.map +1 -0
- package/dist/runtime/graph-synthesis.d.ts +47 -0
- package/dist/runtime/graph-synthesis.d.ts.map +1 -0
- package/dist/runtime/graph-synthesis.js +232 -0
- package/dist/runtime/graph-synthesis.js.map +1 -0
- package/dist/runtime/graph-trajectory.d.ts +88 -0
- package/dist/runtime/graph-trajectory.d.ts.map +1 -0
- package/dist/runtime/graph-trajectory.js +339 -0
- package/dist/runtime/graph-trajectory.js.map +1 -0
- package/dist/runtime/learning-engine.d.ts +12 -0
- package/dist/runtime/learning-engine.d.ts.map +1 -1
- package/dist/runtime/learning-engine.js +64 -0
- package/dist/runtime/learning-engine.js.map +1 -1
- package/package.json +2 -2
- package/skills/swarm-output-style/SKILL.md +71 -33
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
// ─── Helpers ──────────────────────────────────────────────────────
|
|
2
|
+
const PRIORITY_ORDER = { high: 0, medium: 1, low: 2 };
|
|
3
|
+
function priorityOrder(p) {
|
|
4
|
+
return PRIORITY_ORDER[p] ?? 3;
|
|
5
|
+
}
|
|
6
|
+
// ─── TaskDiscovery ───────────────────────────────────────────────
|
|
7
|
+
/**
|
|
8
|
+
* Mines the execution knowledge graph for actionable insights that
|
|
9
|
+
* suggest new work — high-failure-rate files, recurring errors,
|
|
10
|
+
* unresolved vulnerabilities, untested co-modification pairs, and
|
|
11
|
+
* architectural risk from high-centrality low-success files.
|
|
12
|
+
*/
|
|
13
|
+
export class TaskDiscovery {
|
|
14
|
+
graph;
|
|
15
|
+
constructor(graph) {
|
|
16
|
+
this.graph = graph;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Mine the graph for all discoverable tasks.
|
|
20
|
+
* Returns tasks sorted by priority (high first).
|
|
21
|
+
*/
|
|
22
|
+
discoverTasks() {
|
|
23
|
+
const tasks = [];
|
|
24
|
+
tasks.push(...this.findHighFailureRateFiles());
|
|
25
|
+
tasks.push(...this.findRecurringErrors());
|
|
26
|
+
tasks.push(...this.findVulnerabilityClusters());
|
|
27
|
+
tasks.push(...this.findUntestedCoModPairs());
|
|
28
|
+
tasks.push(...this.findArchitecturalRisks());
|
|
29
|
+
return tasks.sort((a, b) => priorityOrder(a.priority) - priorityOrder(b.priority));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get detailed risk profile for a specific file.
|
|
33
|
+
*/
|
|
34
|
+
getFileRiskProfile(filePath) {
|
|
35
|
+
const fileId = `file:${filePath}`;
|
|
36
|
+
const node = this.graph.getNode(fileId);
|
|
37
|
+
if (!node) {
|
|
38
|
+
return {
|
|
39
|
+
file: filePath,
|
|
40
|
+
failureRate: 0,
|
|
41
|
+
errorCount: 0,
|
|
42
|
+
coModifiedWith: [],
|
|
43
|
+
lastTouched: 'unknown',
|
|
44
|
+
vulnerabilities: 0,
|
|
45
|
+
totalTouches: 0,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
// Agents that touched this file (touched_file: agent → file)
|
|
49
|
+
const touchEdges = this.graph.getEdges(fileId, 'incoming').filter((e) => e.type === 'touched_file');
|
|
50
|
+
const totalTouches = touchEdges.length;
|
|
51
|
+
let failCount = 0;
|
|
52
|
+
for (const edge of touchEdges) {
|
|
53
|
+
const agentNode = this.graph.getNode(edge.source);
|
|
54
|
+
if (agentNode && (agentNode.properties.status === 'error' || agentNode.properties.status === 'timeout')) {
|
|
55
|
+
failCount++;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const failureRate = totalTouches > 0 ? failCount / totalTouches : 0;
|
|
59
|
+
// Error nodes linked via caused_by (caused_by: error → file)
|
|
60
|
+
const causedByEdges = this.graph.getEdges(fileId, 'incoming').filter((e) => e.type === 'caused_by');
|
|
61
|
+
const errorCount = causedByEdges.length;
|
|
62
|
+
// Vulnerabilities: P0/P1 severity errors
|
|
63
|
+
let vulnerabilities = 0;
|
|
64
|
+
for (const edge of causedByEdges) {
|
|
65
|
+
const errorNode = this.graph.getNode(edge.source);
|
|
66
|
+
if (errorNode) {
|
|
67
|
+
const severity = errorNode.properties.severity;
|
|
68
|
+
if (severity === 'P0' || severity === 'P1') {
|
|
69
|
+
vulnerabilities++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Co-modified files (co_modified edges are bidirectional)
|
|
74
|
+
const coModEdges = this.graph.getEdges(fileId, 'both').filter((e) => e.type === 'co_modified');
|
|
75
|
+
const coModSet = new Set();
|
|
76
|
+
for (const edge of coModEdges) {
|
|
77
|
+
const otherId = edge.source === fileId ? edge.target : edge.source;
|
|
78
|
+
const otherNode = this.graph.getNode(otherId);
|
|
79
|
+
if (otherNode)
|
|
80
|
+
coModSet.add(otherNode.label);
|
|
81
|
+
}
|
|
82
|
+
// lastTouched: node created_at or 'unknown'
|
|
83
|
+
const lastTouched = node.created_at || 'unknown';
|
|
84
|
+
return {
|
|
85
|
+
file: filePath,
|
|
86
|
+
failureRate,
|
|
87
|
+
errorCount,
|
|
88
|
+
coModifiedWith: [...coModSet],
|
|
89
|
+
lastTouched,
|
|
90
|
+
vulnerabilities,
|
|
91
|
+
totalTouches,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Generate prioritized backlog from discovered tasks.
|
|
96
|
+
*/
|
|
97
|
+
generateBacklog(maxItems) {
|
|
98
|
+
return this.discoverTasks().slice(0, maxItems ?? 20);
|
|
99
|
+
}
|
|
100
|
+
// ─── Discovery strategies ───────────────────────────────────────
|
|
101
|
+
/**
|
|
102
|
+
* Files where >40% of agents that touched them failed → refactor task.
|
|
103
|
+
*/
|
|
104
|
+
findHighFailureRateFiles() {
|
|
105
|
+
const tasks = [];
|
|
106
|
+
const fileNodes = this.graph.getNodesByType('file');
|
|
107
|
+
for (const file of fileNodes) {
|
|
108
|
+
const touchEdges = this.graph.getEdges(file.id, 'incoming').filter((e) => e.type === 'touched_file');
|
|
109
|
+
if (touchEdges.length < 2)
|
|
110
|
+
continue; // need minimum sample
|
|
111
|
+
let failCount = 0;
|
|
112
|
+
for (const edge of touchEdges) {
|
|
113
|
+
const agent = this.graph.getNode(edge.source);
|
|
114
|
+
if (agent && (agent.properties.status === 'error' || agent.properties.status === 'timeout')) {
|
|
115
|
+
failCount++;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const failureRate = failCount / touchEdges.length;
|
|
119
|
+
if (failureRate > 0.4) {
|
|
120
|
+
tasks.push({
|
|
121
|
+
title: `Refactor high-failure file: ${file.label}`,
|
|
122
|
+
description: `${file.label} has a ${Math.round(failureRate * 100)}% failure rate across ${touchEdges.length} agent touches. Refactoring may reduce agent failures.`,
|
|
123
|
+
priority: failureRate > 0.7 ? 'high' : 'medium',
|
|
124
|
+
recommendedPattern: 'review-cycle',
|
|
125
|
+
estimatedCost: this.estimateCost('review-cycle', 1),
|
|
126
|
+
evidence: [
|
|
127
|
+
`${failCount}/${touchEdges.length} agents failed when touching this file`,
|
|
128
|
+
`Failure rate: ${Math.round(failureRate * 100)}%`,
|
|
129
|
+
],
|
|
130
|
+
affectedFiles: [file.label],
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return tasks;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Files with 3+ error nodes → recurring error task.
|
|
138
|
+
*/
|
|
139
|
+
findRecurringErrors() {
|
|
140
|
+
const tasks = [];
|
|
141
|
+
const errorNodes = this.graph.getNodesByType('error');
|
|
142
|
+
// Group errors by file via caused_by edges
|
|
143
|
+
const fileErrors = new Map();
|
|
144
|
+
for (const err of errorNodes) {
|
|
145
|
+
const causedByEdges = this.graph.getEdges(err.id, 'outgoing').filter((e) => e.type === 'caused_by');
|
|
146
|
+
for (const edge of causedByEdges) {
|
|
147
|
+
const fileNode = this.graph.getNode(edge.target);
|
|
148
|
+
if (fileNode && fileNode.type === 'file') {
|
|
149
|
+
const existing = fileErrors.get(fileNode.id) || [];
|
|
150
|
+
existing.push(err);
|
|
151
|
+
fileErrors.set(fileNode.id, existing);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
for (const [fileId, errors] of fileErrors) {
|
|
156
|
+
if (errors.length < 3)
|
|
157
|
+
continue;
|
|
158
|
+
const fileNode = this.graph.getNode(fileId);
|
|
159
|
+
const fileName = fileNode?.label || fileId;
|
|
160
|
+
tasks.push({
|
|
161
|
+
title: `Fix recurring errors in: ${fileName}`,
|
|
162
|
+
description: `${fileName} has ${errors.length} error nodes linked to it. Investigate root cause and apply systematic fix.`,
|
|
163
|
+
priority: errors.length >= 5 ? 'high' : 'medium',
|
|
164
|
+
recommendedPattern: 'postmortem',
|
|
165
|
+
estimatedCost: this.estimateCost('postmortem', 1),
|
|
166
|
+
evidence: errors.map((e) => `Error: ${e.label}`),
|
|
167
|
+
affectedFiles: [fileName],
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return tasks;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Error nodes with P0/P1 severity grouped by file.
|
|
174
|
+
* Clusters of 2+ high-severity errors → urgent task.
|
|
175
|
+
*/
|
|
176
|
+
findVulnerabilityClusters() {
|
|
177
|
+
const tasks = [];
|
|
178
|
+
const errorNodes = this.graph.getNodesByType('error');
|
|
179
|
+
// Filter to P0/P1 severity and group by file
|
|
180
|
+
const fileSevereErrors = new Map();
|
|
181
|
+
for (const err of errorNodes) {
|
|
182
|
+
const severity = err.properties.severity;
|
|
183
|
+
if (severity !== 'P0' && severity !== 'P1')
|
|
184
|
+
continue;
|
|
185
|
+
const causedByEdges = this.graph.getEdges(err.id, 'outgoing').filter((e) => e.type === 'caused_by');
|
|
186
|
+
for (const edge of causedByEdges) {
|
|
187
|
+
const fileNode = this.graph.getNode(edge.target);
|
|
188
|
+
if (fileNode && fileNode.type === 'file') {
|
|
189
|
+
const existing = fileSevereErrors.get(fileNode.id) || [];
|
|
190
|
+
existing.push(err);
|
|
191
|
+
fileSevereErrors.set(fileNode.id, existing);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
for (const [fileId, errors] of fileSevereErrors) {
|
|
196
|
+
if (errors.length < 2)
|
|
197
|
+
continue;
|
|
198
|
+
const fileNode = this.graph.getNode(fileId);
|
|
199
|
+
const fileName = fileNode?.label || fileId;
|
|
200
|
+
tasks.push({
|
|
201
|
+
title: `Urgent: vulnerability cluster in ${fileName}`,
|
|
202
|
+
description: `${fileName} has ${errors.length} high-severity (P0/P1) errors. Requires immediate attention.`,
|
|
203
|
+
priority: 'high',
|
|
204
|
+
recommendedPattern: 'red-team',
|
|
205
|
+
estimatedCost: this.estimateCost('red-team', 1),
|
|
206
|
+
evidence: errors.map((e) => `${e.properties.severity}: ${e.label}`),
|
|
207
|
+
affectedFiles: [fileName],
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return tasks;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Co-modified file pairs that never appeared together in a test orchestration.
|
|
214
|
+
* High co-mod count but no joint testing → integration test task.
|
|
215
|
+
*/
|
|
216
|
+
findUntestedCoModPairs() {
|
|
217
|
+
const tasks = [];
|
|
218
|
+
const fileNodes = this.graph.getNodesByType('file');
|
|
219
|
+
// Build map: file → set of orchestration IDs
|
|
220
|
+
const fileToOrchs = new Map();
|
|
221
|
+
const fileToTestOrchs = new Map();
|
|
222
|
+
for (const file of fileNodes) {
|
|
223
|
+
const allOrchs = new Set();
|
|
224
|
+
const testOrchs = new Set();
|
|
225
|
+
const touchEdges = this.graph.getEdges(file.id, 'incoming').filter((e) => e.type === 'touched_file');
|
|
226
|
+
for (const te of touchEdges) {
|
|
227
|
+
// agent ← phase (spawned)
|
|
228
|
+
const spawnEdges = this.graph.getEdges(te.source, 'incoming').filter((e) => e.type === 'spawned');
|
|
229
|
+
for (const se of spawnEdges) {
|
|
230
|
+
// phase ← orchestration (contains)
|
|
231
|
+
const containEdges = this.graph.getEdges(se.source, 'incoming').filter((e) => e.type === 'contains');
|
|
232
|
+
for (const ce of containEdges) {
|
|
233
|
+
allOrchs.add(ce.source);
|
|
234
|
+
// Check if this orchestration used a test pattern
|
|
235
|
+
const orchNode = this.graph.getNode(ce.source);
|
|
236
|
+
if (orchNode) {
|
|
237
|
+
const pattern = orchNode.properties.pattern;
|
|
238
|
+
if (pattern === 'tdd' || pattern === 'test') {
|
|
239
|
+
testOrchs.add(ce.source);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (allOrchs.size > 0)
|
|
246
|
+
fileToOrchs.set(file.id, allOrchs);
|
|
247
|
+
if (testOrchs.size > 0)
|
|
248
|
+
fileToTestOrchs.set(file.id, testOrchs);
|
|
249
|
+
}
|
|
250
|
+
// Find co-modified pairs via co_modified edges
|
|
251
|
+
const coModEdges = this.graph.getEdgesByType('co_modified');
|
|
252
|
+
const seen = new Set();
|
|
253
|
+
for (const edge of coModEdges) {
|
|
254
|
+
const pairKey = [edge.source, edge.target].sort().join('::');
|
|
255
|
+
if (seen.has(pairKey))
|
|
256
|
+
continue;
|
|
257
|
+
seen.add(pairKey);
|
|
258
|
+
// Count co-modifications between this pair
|
|
259
|
+
const coModCount = coModEdges.filter((e) => (e.source === edge.source && e.target === edge.target) ||
|
|
260
|
+
(e.source === edge.target && e.target === edge.source)).length;
|
|
261
|
+
if (coModCount < 2)
|
|
262
|
+
continue;
|
|
263
|
+
// Check if both files appear in a test orchestration together
|
|
264
|
+
const testOrchsA = fileToTestOrchs.get(edge.source) || new Set();
|
|
265
|
+
const testOrchsB = fileToTestOrchs.get(edge.target) || new Set();
|
|
266
|
+
let testedTogether = false;
|
|
267
|
+
for (const orchId of testOrchsA) {
|
|
268
|
+
if (testOrchsB.has(orchId)) {
|
|
269
|
+
testedTogether = true;
|
|
270
|
+
break;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (!testedTogether) {
|
|
274
|
+
const fileA = this.graph.getNode(edge.source);
|
|
275
|
+
const fileB = this.graph.getNode(edge.target);
|
|
276
|
+
const nameA = fileA?.label || edge.source;
|
|
277
|
+
const nameB = fileB?.label || edge.target;
|
|
278
|
+
tasks.push({
|
|
279
|
+
title: `Add integration test: ${nameA} + ${nameB}`,
|
|
280
|
+
description: `${nameA} and ${nameB} are co-modified ${coModCount} times but never tested together.`,
|
|
281
|
+
priority: coModCount >= 5 ? 'medium' : 'low',
|
|
282
|
+
recommendedPattern: 'tdd',
|
|
283
|
+
estimatedCost: this.estimateCost('tdd', 2),
|
|
284
|
+
evidence: [
|
|
285
|
+
`Co-modified ${coModCount} times across orchestrations`,
|
|
286
|
+
`No joint test orchestration found`,
|
|
287
|
+
],
|
|
288
|
+
affectedFiles: [nameA, nameB],
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return tasks;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Files touched by many agents (high degree) but with low success rate.
|
|
296
|
+
* These represent architectural risk — central files that cause failures.
|
|
297
|
+
*/
|
|
298
|
+
findArchitecturalRisks() {
|
|
299
|
+
const tasks = [];
|
|
300
|
+
const fileNodes = this.graph.getNodesByType('file');
|
|
301
|
+
for (const file of fileNodes) {
|
|
302
|
+
const touchEdges = this.graph.getEdges(file.id, 'incoming').filter((e) => e.type === 'touched_file');
|
|
303
|
+
if (touchEdges.length < 4)
|
|
304
|
+
continue; // need meaningful centrality
|
|
305
|
+
let failCount = 0;
|
|
306
|
+
for (const edge of touchEdges) {
|
|
307
|
+
const agent = this.graph.getNode(edge.source);
|
|
308
|
+
if (agent && (agent.properties.status === 'error' || agent.properties.status === 'timeout')) {
|
|
309
|
+
failCount++;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const successRate = 1 - failCount / touchEdges.length;
|
|
313
|
+
if (successRate < 0.5) {
|
|
314
|
+
tasks.push({
|
|
315
|
+
title: `Architectural risk: ${file.label}`,
|
|
316
|
+
description: `${file.label} is touched by ${touchEdges.length} agents but has only a ${Math.round(successRate * 100)}% success rate. This high-centrality, low-success file may need architectural changes.`,
|
|
317
|
+
priority: 'high',
|
|
318
|
+
recommendedPattern: 'discover',
|
|
319
|
+
estimatedCost: this.estimateCost('discover', 1),
|
|
320
|
+
evidence: [
|
|
321
|
+
`Touched by ${touchEdges.length} agents (high centrality)`,
|
|
322
|
+
`Success rate: ${Math.round(successRate * 100)}%`,
|
|
323
|
+
`${failCount} agent failures linked to this file`,
|
|
324
|
+
],
|
|
325
|
+
affectedFiles: [file.label],
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return tasks;
|
|
330
|
+
}
|
|
331
|
+
// ─── Cost estimation ────────────────────────────────────────────
|
|
332
|
+
/**
|
|
333
|
+
* Estimate cost for a task based on historical orchestrations with the same pattern.
|
|
334
|
+
* Falls back to a heuristic if no historical data.
|
|
335
|
+
*/
|
|
336
|
+
estimateCost(pattern, fileCount) {
|
|
337
|
+
const patternId = `pattern:${pattern}`;
|
|
338
|
+
const patternNode = this.graph.getNode(patternId);
|
|
339
|
+
if (!patternNode)
|
|
340
|
+
return 0.05 * fileCount; // fallback: $0.05/file
|
|
341
|
+
// Get orchestrations that used this pattern
|
|
342
|
+
const usedPatternEdges = this.graph.getEdges(patternId, 'incoming').filter((e) => e.type === 'used_pattern');
|
|
343
|
+
const costs = [];
|
|
344
|
+
const fileCounts = [];
|
|
345
|
+
for (const edge of usedPatternEdges) {
|
|
346
|
+
const orchNode = this.graph.getNode(edge.source);
|
|
347
|
+
if (!orchNode)
|
|
348
|
+
continue;
|
|
349
|
+
const usage = orchNode.properties.usage;
|
|
350
|
+
if (usage?.costUsd && usage.costUsd > 0) {
|
|
351
|
+
costs.push(usage.costUsd);
|
|
352
|
+
// Count files in this orchestration via BFS
|
|
353
|
+
const subgraph = this.graph.bfs(orchNode.id, 3);
|
|
354
|
+
const orchFiles = subgraph.nodes.filter((n) => n.type === 'file');
|
|
355
|
+
fileCounts.push(Math.max(orchFiles.length, 1));
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
if (costs.length === 0)
|
|
359
|
+
return 0.05 * fileCount;
|
|
360
|
+
// Average cost per file, then scale by requested fileCount
|
|
361
|
+
const totalCost = costs.reduce((a, b) => a + b, 0);
|
|
362
|
+
const totalFiles = fileCounts.reduce((a, b) => a + b, 0);
|
|
363
|
+
const costPerFile = totalCost / Math.max(totalFiles, 1);
|
|
364
|
+
return Math.round(costPerFile * fileCount * 100) / 100;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=graph-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-discovery.js","sourceRoot":"","sources":["../../src/runtime/graph-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ExecutionGraph } from './execution-graph.js';
|
|
2
|
+
export interface DropoutModel {
|
|
3
|
+
weights: number[];
|
|
4
|
+
bias: number;
|
|
5
|
+
learnRate: number;
|
|
6
|
+
lambda: number;
|
|
7
|
+
positiveCount: number;
|
|
8
|
+
negativeCount: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DropoutRecommendation {
|
|
11
|
+
agentId: string;
|
|
12
|
+
agentType: string;
|
|
13
|
+
predictedContribution: number;
|
|
14
|
+
uncertainty: 'boundary' | 'confident';
|
|
15
|
+
shouldRequestFeedback: boolean;
|
|
16
|
+
shouldDropOut: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface ContributionRecord {
|
|
19
|
+
agentType: string;
|
|
20
|
+
phaseKind: string;
|
|
21
|
+
fileCount: number;
|
|
22
|
+
pattern: string;
|
|
23
|
+
contributed: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface ContributionStats {
|
|
26
|
+
agentType: string;
|
|
27
|
+
totalRuns: number;
|
|
28
|
+
contributions: number;
|
|
29
|
+
contributionRate: number;
|
|
30
|
+
avgPrediction: number;
|
|
31
|
+
}
|
|
32
|
+
export declare class PredictiveDropout {
|
|
33
|
+
private graph;
|
|
34
|
+
private model;
|
|
35
|
+
private records;
|
|
36
|
+
constructor(graph: ExecutionGraph);
|
|
37
|
+
static initModel(): DropoutModel;
|
|
38
|
+
/**
|
|
39
|
+
* Encode features: one-hot(agentType, 10) + one-hot(phaseKind, 6) + log(fileCount+1) + one-hot(pattern, 8) = 25
|
|
40
|
+
* Unknown values → all zeros in that block.
|
|
41
|
+
*/
|
|
42
|
+
static encodeFeatures(agentType: string, phaseKind: string, fileCount: number, pattern: string): number[];
|
|
43
|
+
/** Predict contribution probability: σ(w·x + b) */
|
|
44
|
+
predict(features: number[]): number;
|
|
45
|
+
/** Train on one observation using class-weighted SGD with L2 regularization. */
|
|
46
|
+
train(record: ContributionRecord): void;
|
|
47
|
+
/** Recommend which agents to skip. */
|
|
48
|
+
predictRedundant(agents: Array<{
|
|
49
|
+
id: string;
|
|
50
|
+
agentType: string;
|
|
51
|
+
}>, phaseKind: string, fileCount: number, pattern: string, dropoutThreshold?: number): DropoutRecommendation[];
|
|
52
|
+
/** Record human override feedback (active learning signal). */
|
|
53
|
+
recordFeedback(agentType: string, phaseKind: string, fileCount: number, pattern: string, actuallyContributed: boolean): void;
|
|
54
|
+
/** Get contribution rates per agent type. */
|
|
55
|
+
getContributionStats(): ContributionStats[];
|
|
56
|
+
private saveToGraph;
|
|
57
|
+
private loadFromGraph;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=graph-dropout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-dropout.d.ts","sourceRoot":"","sources":["../../src/runtime/graph-dropout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsB3D,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,WAAW,EAAE,UAAU,GAAG,WAAW,CAAC;IACtC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB;AAoBD,qBAAa,iBAAiB;IAIhB,OAAO,CAAC,KAAK;IAHzB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,OAAO,CAA4B;gBAEvB,KAAK,EAAE,cAAc;IAKzC,MAAM,CAAC,SAAS,IAAI,YAAY;IAWhC;;;OAGG;IACH,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE;IAqBzG,mDAAmD;IACnD,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM;IAInC,gFAAgF;IAChF,KAAK,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI;IA2BvC,sCAAsC;IACtC,gBAAgB,CACd,MAAM,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,EAChD,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,gBAAgB,GAAE,MAA0B,GAC3C,qBAAqB,EAAE;IAiB1B,+DAA+D;IAC/D,cAAc,CACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,OAAO,GAC3B,IAAI;IAUP,6CAA6C;IAC7C,oBAAoB,IAAI,iBAAiB,EAAE;IAkC3C,OAAO,CAAC,WAAW;IAyBnB,OAAO,CAAC,aAAa;CAwBtB"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
// ─── Constants ────────────────────────────────────────────────────
|
|
2
|
+
const AGENT_TYPES = [
|
|
3
|
+
'researcher', 'implementer', 'reviewer', 'tester', 'debugger',
|
|
4
|
+
'documenter', 'planner', 'refactorer', 'integrator', 'devils-advocate',
|
|
5
|
+
];
|
|
6
|
+
const PHASE_KINDS = ['research', 'implement', 'review', 'test', 'reflect', 'integrate'];
|
|
7
|
+
const PATTERNS = ['research', 'tdd', 'red-team', 'review-cycle', 'spike', 'discover', 'dynamic', 'swarm'];
|
|
8
|
+
// Feature dim = 10 + 6 + 1 + 8 = 25
|
|
9
|
+
const FEATURE_DIM = 25;
|
|
10
|
+
const DROPOUT_THRESHOLD = 0.2;
|
|
11
|
+
const BOUNDARY_LOW = 0.3;
|
|
12
|
+
const BOUNDARY_HIGH = 0.7;
|
|
13
|
+
// ─── Helpers ──────────────────────────────────────────────────────
|
|
14
|
+
function sigmoid(x) {
|
|
15
|
+
const clamped = Math.max(-500, Math.min(500, x));
|
|
16
|
+
return 1 / (1 + Math.exp(-clamped));
|
|
17
|
+
}
|
|
18
|
+
function dot(a, b) {
|
|
19
|
+
let sum = 0;
|
|
20
|
+
const len = Math.min(a.length, b.length);
|
|
21
|
+
for (let i = 0; i < len; i++) {
|
|
22
|
+
sum += a[i] * b[i];
|
|
23
|
+
}
|
|
24
|
+
return sum;
|
|
25
|
+
}
|
|
26
|
+
// ─── PredictiveDropout ────────────────────────────────────────────
|
|
27
|
+
export class PredictiveDropout {
|
|
28
|
+
graph;
|
|
29
|
+
model;
|
|
30
|
+
records = [];
|
|
31
|
+
constructor(graph) {
|
|
32
|
+
this.graph = graph;
|
|
33
|
+
this.model = PredictiveDropout.initModel();
|
|
34
|
+
this.loadFromGraph();
|
|
35
|
+
}
|
|
36
|
+
static initModel() {
|
|
37
|
+
return {
|
|
38
|
+
weights: new Array(FEATURE_DIM).fill(0),
|
|
39
|
+
bias: 0.5,
|
|
40
|
+
learnRate: 0.01,
|
|
41
|
+
lambda: 0.001,
|
|
42
|
+
positiveCount: 0,
|
|
43
|
+
negativeCount: 0,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Encode features: one-hot(agentType, 10) + one-hot(phaseKind, 6) + log(fileCount+1) + one-hot(pattern, 8) = 25
|
|
48
|
+
* Unknown values → all zeros in that block.
|
|
49
|
+
*/
|
|
50
|
+
static encodeFeatures(agentType, phaseKind, fileCount, pattern) {
|
|
51
|
+
const features = new Array(FEATURE_DIM).fill(0);
|
|
52
|
+
// One-hot agent type (indices 0-9)
|
|
53
|
+
const agentIdx = AGENT_TYPES.indexOf(agentType);
|
|
54
|
+
if (agentIdx >= 0)
|
|
55
|
+
features[agentIdx] = 1;
|
|
56
|
+
// One-hot phase kind (indices 10-15)
|
|
57
|
+
const phaseIdx = PHASE_KINDS.indexOf(phaseKind);
|
|
58
|
+
if (phaseIdx >= 0)
|
|
59
|
+
features[10 + phaseIdx] = 1;
|
|
60
|
+
// Log file count (index 16)
|
|
61
|
+
features[16] = Math.log(fileCount + 1);
|
|
62
|
+
// One-hot pattern (indices 17-24)
|
|
63
|
+
const patternIdx = PATTERNS.indexOf(pattern);
|
|
64
|
+
if (patternIdx >= 0)
|
|
65
|
+
features[17 + patternIdx] = 1;
|
|
66
|
+
return features;
|
|
67
|
+
}
|
|
68
|
+
/** Predict contribution probability: σ(w·x + b) */
|
|
69
|
+
predict(features) {
|
|
70
|
+
return sigmoid(dot(this.model.weights, features) + this.model.bias);
|
|
71
|
+
}
|
|
72
|
+
/** Train on one observation using class-weighted SGD with L2 regularization. */
|
|
73
|
+
train(record) {
|
|
74
|
+
this.records.push(record);
|
|
75
|
+
if (this.records.length > 1000)
|
|
76
|
+
this.records = this.records.slice(-1000);
|
|
77
|
+
const features = PredictiveDropout.encodeFeatures(record.agentType, record.phaseKind, record.fileCount, record.pattern);
|
|
78
|
+
const label = record.contributed ? 1 : 0;
|
|
79
|
+
const classWeight = record.contributed ? 1.0 : 3.0;
|
|
80
|
+
const prediction = this.predict(features);
|
|
81
|
+
const error = (prediction - label) * classWeight;
|
|
82
|
+
const { learnRate, lambda } = this.model;
|
|
83
|
+
for (let i = 0; i < FEATURE_DIM; i++) {
|
|
84
|
+
this.model.weights[i] -= learnRate * (error * features[i] + lambda * this.model.weights[i]);
|
|
85
|
+
}
|
|
86
|
+
this.model.bias -= learnRate * error;
|
|
87
|
+
if (record.contributed) {
|
|
88
|
+
this.model.positiveCount++;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.model.negativeCount++;
|
|
92
|
+
}
|
|
93
|
+
this.saveToGraph();
|
|
94
|
+
}
|
|
95
|
+
/** Recommend which agents to skip. */
|
|
96
|
+
predictRedundant(agents, phaseKind, fileCount, pattern, dropoutThreshold = DROPOUT_THRESHOLD) {
|
|
97
|
+
return agents.map((agent) => {
|
|
98
|
+
const features = PredictiveDropout.encodeFeatures(agent.agentType, phaseKind, fileCount, pattern);
|
|
99
|
+
const prediction = this.predict(features);
|
|
100
|
+
const inBoundary = prediction >= BOUNDARY_LOW && prediction <= BOUNDARY_HIGH;
|
|
101
|
+
return {
|
|
102
|
+
agentId: agent.id,
|
|
103
|
+
agentType: agent.agentType,
|
|
104
|
+
predictedContribution: prediction,
|
|
105
|
+
uncertainty: inBoundary ? 'boundary' : 'confident',
|
|
106
|
+
shouldRequestFeedback: inBoundary,
|
|
107
|
+
shouldDropOut: prediction < dropoutThreshold,
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
/** Record human override feedback (active learning signal). */
|
|
112
|
+
recordFeedback(agentType, phaseKind, fileCount, pattern, actuallyContributed) {
|
|
113
|
+
this.train({
|
|
114
|
+
agentType,
|
|
115
|
+
phaseKind,
|
|
116
|
+
fileCount,
|
|
117
|
+
pattern,
|
|
118
|
+
contributed: actuallyContributed,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/** Get contribution rates per agent type. */
|
|
122
|
+
getContributionStats() {
|
|
123
|
+
const groups = new Map();
|
|
124
|
+
for (const record of this.records) {
|
|
125
|
+
let entry = groups.get(record.agentType);
|
|
126
|
+
if (!entry) {
|
|
127
|
+
entry = { total: 0, contributions: 0, predictionSum: 0 };
|
|
128
|
+
groups.set(record.agentType, entry);
|
|
129
|
+
}
|
|
130
|
+
entry.total++;
|
|
131
|
+
if (record.contributed)
|
|
132
|
+
entry.contributions++;
|
|
133
|
+
const features = PredictiveDropout.encodeFeatures(record.agentType, record.phaseKind, record.fileCount, record.pattern);
|
|
134
|
+
entry.predictionSum += this.predict(features);
|
|
135
|
+
}
|
|
136
|
+
const stats = [];
|
|
137
|
+
for (const [agentType, entry] of groups) {
|
|
138
|
+
stats.push({
|
|
139
|
+
agentType,
|
|
140
|
+
totalRuns: entry.total,
|
|
141
|
+
contributions: entry.contributions,
|
|
142
|
+
contributionRate: entry.total > 0 ? entry.contributions / entry.total : 0,
|
|
143
|
+
avgPrediction: entry.total > 0 ? entry.predictionSum / entry.total : 0,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return stats;
|
|
147
|
+
}
|
|
148
|
+
// ─── Persistence ────────────────────────────────────────────────
|
|
149
|
+
saveToGraph() {
|
|
150
|
+
this.graph.addNode({
|
|
151
|
+
id: 'dropout:model',
|
|
152
|
+
type: 'heuristic',
|
|
153
|
+
label: 'Predictive Dropout Model',
|
|
154
|
+
properties: {
|
|
155
|
+
weights: this.model.weights,
|
|
156
|
+
bias: this.model.bias,
|
|
157
|
+
learnRate: this.model.learnRate,
|
|
158
|
+
lambda: this.model.lambda,
|
|
159
|
+
positiveCount: this.model.positiveCount,
|
|
160
|
+
negativeCount: this.model.negativeCount,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
this.graph.addNode({
|
|
164
|
+
id: 'dropout:records',
|
|
165
|
+
type: 'heuristic',
|
|
166
|
+
label: 'Predictive Dropout Records',
|
|
167
|
+
properties: {
|
|
168
|
+
records: this.records,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
loadFromGraph() {
|
|
173
|
+
const modelNode = this.graph.getNode('dropout:model');
|
|
174
|
+
if (modelNode) {
|
|
175
|
+
const p = modelNode.properties;
|
|
176
|
+
const weights = p.weights;
|
|
177
|
+
if (weights && Array.isArray(weights) && weights.length === FEATURE_DIM) {
|
|
178
|
+
this.model.weights = weights;
|
|
179
|
+
this.model.bias = p.bias ?? 0.5;
|
|
180
|
+
this.model.learnRate = p.learnRate ?? 0.01;
|
|
181
|
+
this.model.lambda = p.lambda ?? 0.001;
|
|
182
|
+
this.model.positiveCount = p.positiveCount ?? 0;
|
|
183
|
+
this.model.negativeCount = p.negativeCount ?? 0;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const recordsNode = this.graph.getNode('dropout:records');
|
|
187
|
+
if (recordsNode) {
|
|
188
|
+
const p = recordsNode.properties;
|
|
189
|
+
const records = p.records;
|
|
190
|
+
if (records && Array.isArray(records)) {
|
|
191
|
+
this.records = records;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=graph-dropout.js.map
|