@theihtisham/agent-shadow-brain 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +443 -602
- package/dist/brain/adversarial-defense.d.ts +57 -0
- package/dist/brain/adversarial-defense.d.ts.map +1 -0
- package/dist/brain/adversarial-defense.js +303 -0
- package/dist/brain/adversarial-defense.js.map +1 -0
- package/dist/brain/cognitive-load.d.ts +27 -0
- package/dist/brain/cognitive-load.d.ts.map +1 -0
- package/dist/brain/cognitive-load.js +304 -0
- package/dist/brain/cognitive-load.js.map +1 -0
- package/dist/brain/cross-agent-protocol.d.ts +48 -0
- package/dist/brain/cross-agent-protocol.d.ts.map +1 -0
- package/dist/brain/cross-agent-protocol.js +306 -0
- package/dist/brain/cross-agent-protocol.js.map +1 -0
- package/dist/brain/influence-map.d.ts +31 -0
- package/dist/brain/influence-map.d.ts.map +1 -0
- package/dist/brain/influence-map.js +375 -0
- package/dist/brain/influence-map.js.map +1 -0
- package/dist/brain/knowledge-graph.d.ts +56 -0
- package/dist/brain/knowledge-graph.d.ts.map +1 -0
- package/dist/brain/knowledge-graph.js +427 -0
- package/dist/brain/knowledge-graph.js.map +1 -0
- package/dist/brain/learning-engine.d.ts +11 -0
- package/dist/brain/learning-engine.d.ts.map +1 -1
- package/dist/brain/learning-engine.js +44 -1
- package/dist/brain/learning-engine.js.map +1 -1
- package/dist/brain/neural-mesh.d.ts +9 -1
- package/dist/brain/neural-mesh.d.ts.map +1 -1
- package/dist/brain/neural-mesh.js +75 -16
- package/dist/brain/neural-mesh.js.map +1 -1
- package/dist/brain/orchestrator.d.ts +24 -2
- package/dist/brain/orchestrator.d.ts.map +1 -1
- package/dist/brain/orchestrator.js +208 -4
- package/dist/brain/orchestrator.js.map +1 -1
- package/dist/brain/pattern-memory.d.ts +8 -3
- package/dist/brain/pattern-memory.d.ts.map +1 -1
- package/dist/brain/pattern-memory.js +71 -3
- package/dist/brain/pattern-memory.js.map +1 -1
- package/dist/brain/predictive-engine.d.ts +45 -0
- package/dist/brain/predictive-engine.d.ts.map +1 -0
- package/dist/brain/predictive-engine.js +238 -0
- package/dist/brain/predictive-engine.js.map +1 -0
- package/dist/brain/security-audit.d.ts +20 -0
- package/dist/brain/security-audit.d.ts.map +1 -0
- package/dist/brain/security-audit.js +340 -0
- package/dist/brain/security-audit.js.map +1 -0
- package/dist/brain/self-evolution.d.ts +53 -0
- package/dist/brain/self-evolution.d.ts.map +1 -0
- package/dist/brain/self-evolution.js +278 -0
- package/dist/brain/self-evolution.js.map +1 -0
- package/dist/brain/sssp-router.d.ts +58 -0
- package/dist/brain/sssp-router.d.ts.map +1 -0
- package/dist/brain/sssp-router.js +295 -0
- package/dist/brain/sssp-router.js.map +1 -0
- package/dist/brain/swarm-intelligence.d.ts +48 -0
- package/dist/brain/swarm-intelligence.d.ts.map +1 -0
- package/dist/brain/swarm-intelligence.js +215 -0
- package/dist/brain/swarm-intelligence.js.map +1 -0
- package/dist/brain/turbo-memory.d.ts +56 -0
- package/dist/brain/turbo-memory.d.ts.map +1 -0
- package/dist/brain/turbo-memory.js +388 -0
- package/dist/brain/turbo-memory.js.map +1 -0
- package/dist/cli.js +339 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +272 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/dashboard.d.ts.map +1 -1
- package/dist/ui/dashboard.js +20 -3
- package/dist/ui/dashboard.js.map +1 -1
- package/package.json +16 -7
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
// src/brain/self-evolution.ts — Genetic Algorithm Rule Optimizer
|
|
2
|
+
// Rules evolve themselves by measuring which produce accurate insights.
|
|
3
|
+
// Tournament selection, Gaussian mutation, Bayesian meta-learning.
|
|
4
|
+
// v4.0.0 — Hyper-Intelligence Edition
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import * as crypto from 'crypto';
|
|
8
|
+
const EVOLUTION_DIR = path.join(process.env.HOME || process.env.USERPROFILE || '~', '.shadow-brain', 'evolution');
|
|
9
|
+
const DEFAULT_CONFIG = {
|
|
10
|
+
populationSize: 50,
|
|
11
|
+
mutationRate: 0.1,
|
|
12
|
+
crossoverRate: 0.7,
|
|
13
|
+
elitePercent: 0.1,
|
|
14
|
+
fitnessTarget: 0.95,
|
|
15
|
+
maxGenerations: 1000,
|
|
16
|
+
tournamentSize: 5,
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Self-Evolution Engine — rules that write themselves.
|
|
20
|
+
*
|
|
21
|
+
* Genetic Representation:
|
|
22
|
+
* Each rule = chromosome of floats encoding severity weight,
|
|
23
|
+
* confidence threshold, file pattern hash, category encoding, etc.
|
|
24
|
+
*
|
|
25
|
+
* Fitness: accuracy × coverage × (1 / falsePositiveRate)
|
|
26
|
+
* Selection: Tournament (k=5)
|
|
27
|
+
* Crossover: Single-point at random position
|
|
28
|
+
* Mutation: Gaussian noise σ = 0.1 × mutationRate
|
|
29
|
+
*
|
|
30
|
+
* Meta-Learning: Tracks which (rule, project_type, language) combos work best.
|
|
31
|
+
* Bayesian updating of weights per strategy.
|
|
32
|
+
*/
|
|
33
|
+
export class SelfEvolution {
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this.population = [];
|
|
36
|
+
this.generation = 0;
|
|
37
|
+
this.metaLogs = [];
|
|
38
|
+
this.eliteArchive = [];
|
|
39
|
+
this.fitnessHistory = [];
|
|
40
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
41
|
+
this.loadFromDisk();
|
|
42
|
+
}
|
|
43
|
+
// ── Evolution Cycle ─────────────────────────────────────────────────────────
|
|
44
|
+
/** Run one evolution generation */
|
|
45
|
+
async evolve(insights = []) {
|
|
46
|
+
// Initialize population if empty
|
|
47
|
+
if (this.population.length === 0) {
|
|
48
|
+
this.initializePopulation();
|
|
49
|
+
}
|
|
50
|
+
// Evaluate fitness for all rules
|
|
51
|
+
for (const rule of this.population) {
|
|
52
|
+
rule.fitness = this.evaluateFitness(rule, insights);
|
|
53
|
+
}
|
|
54
|
+
// Sort by fitness (descending)
|
|
55
|
+
this.population.sort((a, b) => b.fitness - a.fitness);
|
|
56
|
+
// Track elite
|
|
57
|
+
const eliteCount = Math.max(1, Math.floor(this.config.populationSize * this.config.elitePercent));
|
|
58
|
+
const elites = this.population.slice(0, eliteCount);
|
|
59
|
+
this.eliteArchive = [...this.eliteArchive, ...elites]
|
|
60
|
+
.sort((a, b) => b.fitness - a.fitness)
|
|
61
|
+
.slice(0, eliteCount * 3);
|
|
62
|
+
// Create next generation
|
|
63
|
+
const nextGen = [...elites]; // Elitism: keep best
|
|
64
|
+
while (nextGen.length < this.config.populationSize) {
|
|
65
|
+
const parentA = this.tournamentSelect();
|
|
66
|
+
const parentB = this.tournamentSelect();
|
|
67
|
+
if (Math.random() < this.config.crossoverRate) {
|
|
68
|
+
const [childA, childB] = this.crossover(parentA, parentB);
|
|
69
|
+
nextGen.push(this.mutate(childA));
|
|
70
|
+
if (nextGen.length < this.config.populationSize) {
|
|
71
|
+
nextGen.push(this.mutate(childB));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
nextGen.push(this.mutate({ ...parentA, id: crypto.randomUUID() }));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.population = nextGen;
|
|
79
|
+
this.generation++;
|
|
80
|
+
// Record fitness history
|
|
81
|
+
const bestFitness = elites[0]?.fitness ?? 0;
|
|
82
|
+
const avgFitness = this.population.reduce((s, r) => s + r.fitness, 0) / this.population.length;
|
|
83
|
+
this.fitnessHistory.push({ gen: this.generation, best: bestFitness, avg: avgFitness });
|
|
84
|
+
const snapshot = {
|
|
85
|
+
generation: this.generation,
|
|
86
|
+
bestFitness,
|
|
87
|
+
avgFitness,
|
|
88
|
+
worstFitness: this.population[this.population.length - 1]?.fitness ?? 0,
|
|
89
|
+
population: [...this.population],
|
|
90
|
+
eliteCount,
|
|
91
|
+
timestamp: new Date(),
|
|
92
|
+
};
|
|
93
|
+
await this.saveToDisk();
|
|
94
|
+
return snapshot;
|
|
95
|
+
}
|
|
96
|
+
// ── Fitness Evaluation ──────────────────────────────────────────────────────
|
|
97
|
+
/** Evaluate rule fitness based on insight history */
|
|
98
|
+
evaluateFitness(rule, insights) {
|
|
99
|
+
if (insights.length === 0) {
|
|
100
|
+
// No insights to evaluate against — use chromosome values
|
|
101
|
+
const chrom = rule.chromosome;
|
|
102
|
+
const severityWeight = chrom[0] ?? 0.5;
|
|
103
|
+
const confidenceThreshold = chrom[1] ?? 0.5;
|
|
104
|
+
const coverageScore = chrom[2] ?? 0.5;
|
|
105
|
+
const specificity = chrom[3] ?? 0.5;
|
|
106
|
+
return (severityWeight * 0.3 + confidenceThreshold * 0.3 + coverageScore * 0.2 + specificity * 0.2);
|
|
107
|
+
}
|
|
108
|
+
// Match insights to rule category and measure accuracy
|
|
109
|
+
const matchingInsights = insights.filter(i => {
|
|
110
|
+
const categoryScore = rule.chromosome[3] ?? 0.5;
|
|
111
|
+
return i.confidence !== undefined && i.confidence >= categoryScore * 0.5;
|
|
112
|
+
});
|
|
113
|
+
if (matchingInsights.length === 0)
|
|
114
|
+
return 0.1; // Minimum fitness
|
|
115
|
+
// Count true positives (high confidence insights that match)
|
|
116
|
+
const truePositives = matchingInsights.filter(i => i.priority === 'critical' || i.priority === 'high').length;
|
|
117
|
+
// Count false positives (low confidence insights that fired)
|
|
118
|
+
const falsePositives = matchingInsights.filter(i => i.priority === 'low' && (i.confidence ?? 0) < 0.5).length;
|
|
119
|
+
const accuracy = truePositives / Math.max(matchingInsights.length, 1);
|
|
120
|
+
const coverage = matchingInsights.length / Math.max(insights.length, 1);
|
|
121
|
+
const falsePositiveRate = falsePositives / Math.max(matchingInsights.length, 1);
|
|
122
|
+
return accuracy * 0.4 + coverage * 0.3 + (1 - falsePositiveRate) * 0.3;
|
|
123
|
+
}
|
|
124
|
+
// ── Genetic Operators ───────────────────────────────────────────────────────
|
|
125
|
+
/** Tournament selection (k=5) */
|
|
126
|
+
tournamentSelect() {
|
|
127
|
+
let best = null;
|
|
128
|
+
for (let i = 0; i < this.config.tournamentSize; i++) {
|
|
129
|
+
const candidate = this.population[Math.floor(Math.random() * this.population.length)];
|
|
130
|
+
if (!best || candidate.fitness > best.fitness) {
|
|
131
|
+
best = candidate;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return { ...best, id: crypto.randomUUID() };
|
|
135
|
+
}
|
|
136
|
+
/** Single-point crossover */
|
|
137
|
+
crossover(a, b) {
|
|
138
|
+
const point = Math.floor(Math.random() * Math.min(a.chromosome.length, b.chromosome.length));
|
|
139
|
+
const childAChrom = [...a.chromosome.slice(0, point), ...b.chromosome.slice(point)];
|
|
140
|
+
const childBChrom = [...b.chromosome.slice(0, point), ...a.chromosome.slice(point)];
|
|
141
|
+
return [
|
|
142
|
+
{ id: crypto.randomUUID(), chromosome: childAChrom, fitness: 0, generation: this.generation, mutations: 0, category: a.category, createdAt: new Date() },
|
|
143
|
+
{ id: crypto.randomUUID(), chromosome: childBChrom, fitness: 0, generation: this.generation, mutations: 0, category: b.category, createdAt: new Date() },
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
/** Gaussian mutation */
|
|
147
|
+
mutate(rule) {
|
|
148
|
+
const sigma = 0.1 * this.config.mutationRate;
|
|
149
|
+
const mutated = rule.chromosome.map(gene => {
|
|
150
|
+
if (Math.random() < this.config.mutationRate) {
|
|
151
|
+
// Box-Muller transform for Gaussian noise
|
|
152
|
+
const u1 = Math.random();
|
|
153
|
+
const u2 = Math.random();
|
|
154
|
+
const noise = Math.sqrt(-2 * Math.log(u1 + 1e-10)) * Math.cos(2 * Math.PI * u2) * sigma;
|
|
155
|
+
return Math.max(0, Math.min(1, gene + noise));
|
|
156
|
+
}
|
|
157
|
+
return gene;
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
...rule,
|
|
161
|
+
chromosome: mutated,
|
|
162
|
+
mutations: rule.mutations + 1,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
// ── Population Initialization ───────────────────────────────────────────────
|
|
166
|
+
initializePopulation() {
|
|
167
|
+
const categories = ['security', 'performance', 'quality', 'architecture', 'style'];
|
|
168
|
+
for (let i = 0; i < this.config.populationSize; i++) {
|
|
169
|
+
this.population.push({
|
|
170
|
+
id: crypto.randomUUID(),
|
|
171
|
+
chromosome: Array.from({ length: 10 }, () => Math.random()),
|
|
172
|
+
fitness: 0,
|
|
173
|
+
generation: 0,
|
|
174
|
+
mutations: 0,
|
|
175
|
+
category: categories[i % categories.length],
|
|
176
|
+
createdAt: new Date(),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
// ── Meta-Learning ───────────────────────────────────────────────────────────
|
|
181
|
+
/** Update meta-learning log with strategy outcome */
|
|
182
|
+
updateMetaLearning(strategy, outcome, category = 'general') {
|
|
183
|
+
const existing = this.metaLogs.find(l => l.strategy === strategy && l.category === category);
|
|
184
|
+
if (existing) {
|
|
185
|
+
const totalSamples = existing.sampleCount + 1;
|
|
186
|
+
const successCount = existing.sampleCount * existing.successRate + (outcome ? 1 : 0);
|
|
187
|
+
existing.successRate = successCount / totalSamples;
|
|
188
|
+
existing.avgImprovement = existing.avgImprovement * 0.9 + (outcome ? 0.1 : -0.05);
|
|
189
|
+
existing.sampleCount = totalSamples;
|
|
190
|
+
existing.lastUpdated = new Date();
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
this.metaLogs.push({
|
|
194
|
+
strategy,
|
|
195
|
+
successRate: outcome ? 1 : 0,
|
|
196
|
+
avgImprovement: outcome ? 0.1 : 0,
|
|
197
|
+
sampleCount: 1,
|
|
198
|
+
lastUpdated: new Date(),
|
|
199
|
+
category,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** Get best evolved rules for a category */
|
|
204
|
+
getBestRules(category, topN = 10) {
|
|
205
|
+
const allRules = [...this.eliteArchive, ...this.population]
|
|
206
|
+
.filter(r => category === 'all' || r.category === category)
|
|
207
|
+
.sort((a, b) => b.fitness - a.fitness);
|
|
208
|
+
// Deduplicate by chromosome similarity
|
|
209
|
+
const seen = [];
|
|
210
|
+
for (const rule of allRules) {
|
|
211
|
+
if (seen.length >= topN)
|
|
212
|
+
break;
|
|
213
|
+
const isDuplicate = seen.some(s => s.chromosome.every((gene, i) => Math.abs(gene - rule.chromosome[i]) < 0.05));
|
|
214
|
+
if (!isDuplicate)
|
|
215
|
+
seen.push(rule);
|
|
216
|
+
}
|
|
217
|
+
return seen;
|
|
218
|
+
}
|
|
219
|
+
/** Get current generation info */
|
|
220
|
+
getGeneration() { return this.generation; }
|
|
221
|
+
getPopulationSize() { return this.population.length; }
|
|
222
|
+
getFitnessHistory() { return this.fitnessHistory; }
|
|
223
|
+
/** Get a snapshot of the current evolution state */
|
|
224
|
+
getSnapshot() {
|
|
225
|
+
const fitnesses = this.population.map(r => r.fitness);
|
|
226
|
+
return {
|
|
227
|
+
generation: this.generation,
|
|
228
|
+
bestFitness: fitnesses.length > 0 ? Math.max(...fitnesses) : 0,
|
|
229
|
+
avgFitness: fitnesses.length > 0 ? fitnesses.reduce((a, b) => a + b, 0) / fitnesses.length : 0,
|
|
230
|
+
worstFitness: fitnesses.length > 0 ? Math.min(...fitnesses) : 0,
|
|
231
|
+
population: this.population,
|
|
232
|
+
eliteCount: this.eliteArchive.length,
|
|
233
|
+
timestamp: new Date(),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
// ── Persistence ─────────────────────────────────────────────────────────────
|
|
237
|
+
async saveToDisk() {
|
|
238
|
+
try {
|
|
239
|
+
if (!fs.existsSync(EVOLUTION_DIR)) {
|
|
240
|
+
fs.mkdirSync(EVOLUTION_DIR, { recursive: true });
|
|
241
|
+
}
|
|
242
|
+
const state = {
|
|
243
|
+
generation: this.generation,
|
|
244
|
+
population: this.population,
|
|
245
|
+
eliteArchive: this.eliteArchive,
|
|
246
|
+
metaLogs: this.metaLogs,
|
|
247
|
+
fitnessHistory: this.fitnessHistory,
|
|
248
|
+
config: this.config,
|
|
249
|
+
};
|
|
250
|
+
fs.writeFileSync(path.join(EVOLUTION_DIR, `gen-${this.generation}.json`), JSON.stringify(state));
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
// Non-blocking
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
loadFromDisk() {
|
|
257
|
+
try {
|
|
258
|
+
if (!fs.existsSync(EVOLUTION_DIR))
|
|
259
|
+
return;
|
|
260
|
+
const files = fs.readdirSync(EVOLUTION_DIR)
|
|
261
|
+
.filter(f => f.startsWith('gen-') && f.endsWith('.json'))
|
|
262
|
+
.sort()
|
|
263
|
+
.reverse();
|
|
264
|
+
if (files.length === 0)
|
|
265
|
+
return;
|
|
266
|
+
const latest = JSON.parse(fs.readFileSync(path.join(EVOLUTION_DIR, files[0]), 'utf-8'));
|
|
267
|
+
this.generation = latest.generation ?? 0;
|
|
268
|
+
this.population = latest.population ?? [];
|
|
269
|
+
this.eliteArchive = latest.eliteArchive ?? [];
|
|
270
|
+
this.metaLogs = latest.metaLogs ?? [];
|
|
271
|
+
this.fitnessHistory = latest.fitnessHistory ?? [];
|
|
272
|
+
}
|
|
273
|
+
catch {
|
|
274
|
+
// Fresh start
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
//# sourceMappingURL=self-evolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-evolution.js","sourceRoot":"","sources":["../../src/brain/self-evolution.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { SSSPGraph, SSSPResult, PivotSet } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* SSSP Router implementing the Breaking the Sorting Barrier algorithm.
|
|
4
|
+
*
|
|
5
|
+
* Key insight: For multi-source shortest paths, use pivot-based recursion
|
|
6
|
+
* to achieve O(m log^(2/3) n) instead of Dijkstra's O(m + n log n).
|
|
7
|
+
*
|
|
8
|
+
* Parameters:
|
|
9
|
+
* k = floor(cbrt(log(n))) — pivot threshold
|
|
10
|
+
* t = floor(log(n)^(2/3)) — recursion depth bound
|
|
11
|
+
*
|
|
12
|
+
* FindPivots: Run k rounds of Bellman-Ford relaxation, collect vertices
|
|
13
|
+
* reachable within k hops. Sources with SP tree >= k vertices → pivots.
|
|
14
|
+
* Key property: |P| <= |U|/k, geometric problem reduction.
|
|
15
|
+
*
|
|
16
|
+
* BMSSP: Recursive divide-and-conquer. Base case: |S|=1 or t=0 → Dijkstra.
|
|
17
|
+
* Find pivots → recurse on pivots → inherit distances for remaining.
|
|
18
|
+
*/
|
|
19
|
+
export declare class SSSPRouter {
|
|
20
|
+
private graph;
|
|
21
|
+
private cache;
|
|
22
|
+
/** Build adjacency graph from mesh node connections */
|
|
23
|
+
buildGraph(nodes: Array<{
|
|
24
|
+
id: string;
|
|
25
|
+
connections: Array<{
|
|
26
|
+
targetId: string;
|
|
27
|
+
latency: number;
|
|
28
|
+
}>;
|
|
29
|
+
}>): SSSPGraph;
|
|
30
|
+
/** Add a single edge to the graph */
|
|
31
|
+
addEdge(from: string, to: string, weight: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* FindPivots(G, S, k):
|
|
34
|
+
* 1. Initialize distances for all v ∈ S to 0
|
|
35
|
+
* 2. Run k rounds of Bellman-Ford relaxation (not full BF, just k steps)
|
|
36
|
+
* 3. Collect U = vertices reachable within k hops
|
|
37
|
+
* 4. For each source s: if SP tree covers >= k vertices → mark as pivot
|
|
38
|
+
* 5. Return pivot set P and uncovered vertices
|
|
39
|
+
*/
|
|
40
|
+
findPivots(graph: SSSPGraph, sources: string[], k: number): PivotSet;
|
|
41
|
+
/**
|
|
42
|
+
* BMSSP(G, S, t) — Bounded Multi-Source Shortest Path:
|
|
43
|
+
* 1. If |S| = 1 or t = 0: base case → simple Dijkstra
|
|
44
|
+
* 2. FindPivots(G, S, k) to identify pivot sources
|
|
45
|
+
* 3. Recursively solve SSSP(G, P) with t-1
|
|
46
|
+
* 4. For remaining vertices: inherit distance bounds from nearest pivot
|
|
47
|
+
*/
|
|
48
|
+
bmssp(graph: SSSPGraph, sources: string[], t: number): SSSPResult;
|
|
49
|
+
/** Standard Dijkstra with min-heap for single-source shortest path */
|
|
50
|
+
dijkstra(graph: SSSPGraph, source: string): SSSPResult;
|
|
51
|
+
/** Find optimal route between two nodes */
|
|
52
|
+
route(fromNode: string, toNode: string): string[];
|
|
53
|
+
/** Reconstruct path from predecessor map */
|
|
54
|
+
private reconstructPath;
|
|
55
|
+
/** Clear route cache */
|
|
56
|
+
clearCache(): void;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=sssp-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sssp-router.d.ts","sourceRoot":"","sources":["../../src/brain/sssp-router.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAY,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAExE;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,KAAK,CAAsC;IAEnD,uDAAuD;IACvD,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,GAAG,SAAS;IAiB9G,qCAAqC;IACrC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAgBvD;;;;;;;OAOG;IACH,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,QAAQ;IA0EpE;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU;IAgGjE,sEAAsE;IACtE,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU;IA6CtD,2CAA2C;IAC3C,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAkBjD,4CAA4C;IAC5C,OAAO,CAAC,eAAe;IAevB,wBAAwB;IACxB,UAAU,IAAI,IAAI;CAGnB"}
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
// src/brain/sssp-router.ts — O(m log^(2/3) n) Neural Mesh Router
|
|
2
|
+
// Algorithm: BMSSP (Bounded Multi-Source Shortest Path) from arXiv 2504.17033
|
|
3
|
+
// "Breaking the Sorting Barrier" — first deterministic algorithm faster than Dijkstra
|
|
4
|
+
// v4.0.0 — Hyper-Intelligence Edition
|
|
5
|
+
/**
|
|
6
|
+
* SSSP Router implementing the Breaking the Sorting Barrier algorithm.
|
|
7
|
+
*
|
|
8
|
+
* Key insight: For multi-source shortest paths, use pivot-based recursion
|
|
9
|
+
* to achieve O(m log^(2/3) n) instead of Dijkstra's O(m + n log n).
|
|
10
|
+
*
|
|
11
|
+
* Parameters:
|
|
12
|
+
* k = floor(cbrt(log(n))) — pivot threshold
|
|
13
|
+
* t = floor(log(n)^(2/3)) — recursion depth bound
|
|
14
|
+
*
|
|
15
|
+
* FindPivots: Run k rounds of Bellman-Ford relaxation, collect vertices
|
|
16
|
+
* reachable within k hops. Sources with SP tree >= k vertices → pivots.
|
|
17
|
+
* Key property: |P| <= |U|/k, geometric problem reduction.
|
|
18
|
+
*
|
|
19
|
+
* BMSSP: Recursive divide-and-conquer. Base case: |S|=1 or t=0 → Dijkstra.
|
|
20
|
+
* Find pivots → recurse on pivots → inherit distances for remaining.
|
|
21
|
+
*/
|
|
22
|
+
export class SSSPRouter {
|
|
23
|
+
constructor() {
|
|
24
|
+
this.graph = null;
|
|
25
|
+
this.cache = new Map();
|
|
26
|
+
}
|
|
27
|
+
/** Build adjacency graph from mesh node connections */
|
|
28
|
+
buildGraph(nodes) {
|
|
29
|
+
const adjacency = new Map();
|
|
30
|
+
let edgeCount = 0;
|
|
31
|
+
for (const node of nodes) {
|
|
32
|
+
const edges = [];
|
|
33
|
+
for (const conn of node.connections) {
|
|
34
|
+
edges.push({ to: conn.targetId, weight: conn.latency });
|
|
35
|
+
edgeCount++;
|
|
36
|
+
}
|
|
37
|
+
adjacency.set(node.id, edges);
|
|
38
|
+
}
|
|
39
|
+
this.graph = { adjacency, nodeCount: adjacency.size, edgeCount };
|
|
40
|
+
return this.graph;
|
|
41
|
+
}
|
|
42
|
+
/** Add a single edge to the graph */
|
|
43
|
+
addEdge(from, to, weight) {
|
|
44
|
+
if (!this.graph) {
|
|
45
|
+
this.graph = { adjacency: new Map(), nodeCount: 0, edgeCount: 0 };
|
|
46
|
+
}
|
|
47
|
+
let edges = this.graph.adjacency.get(from);
|
|
48
|
+
if (!edges) {
|
|
49
|
+
edges = [];
|
|
50
|
+
this.graph.adjacency.set(from, edges);
|
|
51
|
+
this.graph.nodeCount++;
|
|
52
|
+
}
|
|
53
|
+
edges.push({ to, weight });
|
|
54
|
+
this.graph.edgeCount++;
|
|
55
|
+
}
|
|
56
|
+
// ── FindPivots Algorithm ────────────────────────────────────────────────────
|
|
57
|
+
/**
|
|
58
|
+
* FindPivots(G, S, k):
|
|
59
|
+
* 1. Initialize distances for all v ∈ S to 0
|
|
60
|
+
* 2. Run k rounds of Bellman-Ford relaxation (not full BF, just k steps)
|
|
61
|
+
* 3. Collect U = vertices reachable within k hops
|
|
62
|
+
* 4. For each source s: if SP tree covers >= k vertices → mark as pivot
|
|
63
|
+
* 5. Return pivot set P and uncovered vertices
|
|
64
|
+
*/
|
|
65
|
+
findPivots(graph, sources, k) {
|
|
66
|
+
const dist = new Map();
|
|
67
|
+
const pred = new Map();
|
|
68
|
+
// Initialize: all sources at distance 0
|
|
69
|
+
for (const s of sources) {
|
|
70
|
+
dist.set(s, 0);
|
|
71
|
+
pred.set(s, null);
|
|
72
|
+
}
|
|
73
|
+
// Track which source each vertex was reached from
|
|
74
|
+
const sourceReach = new Map();
|
|
75
|
+
for (const s of sources) {
|
|
76
|
+
sourceReach.set(s, new Set([s]));
|
|
77
|
+
}
|
|
78
|
+
// Run k rounds of relaxation
|
|
79
|
+
for (let round = 0; round < k; round++) {
|
|
80
|
+
const updated = new Map();
|
|
81
|
+
for (const [node, edges] of graph.adjacency) {
|
|
82
|
+
const currentDist = dist.get(node);
|
|
83
|
+
if (currentDist === undefined)
|
|
84
|
+
continue;
|
|
85
|
+
for (const edge of edges) {
|
|
86
|
+
const newDist = currentDist + edge.weight;
|
|
87
|
+
const existingDist = dist.get(edge.to);
|
|
88
|
+
if (existingDist === undefined || newDist < existingDist) {
|
|
89
|
+
updated.set(edge.to, newDist);
|
|
90
|
+
pred.set(edge.to, node);
|
|
91
|
+
// Track source reachability
|
|
92
|
+
for (const s of sources) {
|
|
93
|
+
const reached = sourceReach.get(s);
|
|
94
|
+
if (reached?.has(node)) {
|
|
95
|
+
reached.add(edge.to);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Apply updates
|
|
102
|
+
for (const [node, d] of updated) {
|
|
103
|
+
dist.set(node, d);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Identify pivots: sources whose SP tree covers >= k vertices
|
|
107
|
+
const pivots = [];
|
|
108
|
+
const covered = new Set();
|
|
109
|
+
for (const s of sources) {
|
|
110
|
+
const reached = sourceReach.get(s);
|
|
111
|
+
if (reached && reached.size >= k) {
|
|
112
|
+
pivots.push(s);
|
|
113
|
+
for (const v of reached) {
|
|
114
|
+
covered.add(v);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const uncovered = Array.from(dist.keys()).filter(v => !covered.has(v));
|
|
119
|
+
return {
|
|
120
|
+
pivots,
|
|
121
|
+
covered: Array.from(covered),
|
|
122
|
+
uncovered,
|
|
123
|
+
k,
|
|
124
|
+
computedAt: new Date(),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// ── BMSSP Algorithm ────────────────────────────────────────────────────────
|
|
128
|
+
/**
|
|
129
|
+
* BMSSP(G, S, t) — Bounded Multi-Source Shortest Path:
|
|
130
|
+
* 1. If |S| = 1 or t = 0: base case → simple Dijkstra
|
|
131
|
+
* 2. FindPivots(G, S, k) to identify pivot sources
|
|
132
|
+
* 3. Recursively solve SSSP(G, P) with t-1
|
|
133
|
+
* 4. For remaining vertices: inherit distance bounds from nearest pivot
|
|
134
|
+
*/
|
|
135
|
+
bmssp(graph, sources, t) {
|
|
136
|
+
const distances = new Map();
|
|
137
|
+
const predecessors = new Map();
|
|
138
|
+
const allPivots = [];
|
|
139
|
+
// Base case: single source or t=0 → Dijkstra
|
|
140
|
+
if (sources.length <= 1 || t <= 0) {
|
|
141
|
+
const source = sources[0] || sources[0];
|
|
142
|
+
return this.dijkstra(graph, source);
|
|
143
|
+
}
|
|
144
|
+
// Calculate k = floor(cbrt(log(n)))
|
|
145
|
+
const n = graph.nodeCount;
|
|
146
|
+
const k = Math.max(2, Math.floor(Math.cbrt(Math.log2(Math.max(n, 2)))));
|
|
147
|
+
// Find pivots
|
|
148
|
+
const pivotSet = this.findPivots(graph, sources, k);
|
|
149
|
+
allPivots.push(...pivotSet.pivots);
|
|
150
|
+
if (pivotSet.pivots.length > 0 && pivotSet.pivots.length < sources.length) {
|
|
151
|
+
// Recursive solve for pivots
|
|
152
|
+
const pivotResult = this.bmssp(graph, pivotSet.pivots, t - 1);
|
|
153
|
+
// Merge pivot distances
|
|
154
|
+
for (const [node, dist] of pivotResult.distances) {
|
|
155
|
+
distances.set(node, dist);
|
|
156
|
+
}
|
|
157
|
+
for (const [node, pred] of pivotResult.predecessors) {
|
|
158
|
+
predecessors.set(node, pred);
|
|
159
|
+
}
|
|
160
|
+
allPivots.push(...pivotResult.pivots);
|
|
161
|
+
// For remaining sources: find shortest path via pivot distances + edge
|
|
162
|
+
for (const source of sources) {
|
|
163
|
+
if (pivotSet.pivots.includes(source))
|
|
164
|
+
continue;
|
|
165
|
+
// Try to reach this source via nearest pivot
|
|
166
|
+
let bestDist = Infinity;
|
|
167
|
+
let bestPred = null;
|
|
168
|
+
for (const [node, nodeDist] of distances) {
|
|
169
|
+
const edges = graph.adjacency.get(node);
|
|
170
|
+
if (!edges)
|
|
171
|
+
continue;
|
|
172
|
+
for (const edge of edges) {
|
|
173
|
+
if (edge.to === source) {
|
|
174
|
+
const candidateDist = nodeDist + edge.weight;
|
|
175
|
+
if (candidateDist < bestDist) {
|
|
176
|
+
bestDist = candidateDist;
|
|
177
|
+
bestPred = node;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (bestDist < Infinity) {
|
|
183
|
+
distances.set(source, bestDist);
|
|
184
|
+
predecessors.set(source, bestPred);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// Fallback: run Dijkstra for this isolated source
|
|
188
|
+
const isolated = this.dijkstra(graph, source);
|
|
189
|
+
for (const [node, dist] of isolated.distances) {
|
|
190
|
+
if (!distances.has(node) || dist < (distances.get(node) ?? Infinity)) {
|
|
191
|
+
distances.set(node, dist);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
for (const [node, pred] of isolated.predecessors) {
|
|
195
|
+
if (!predecessors.has(node)) {
|
|
196
|
+
predecessors.set(node, pred);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// All sources are pivots or none are — fall back to Dijkstra per source
|
|
204
|
+
for (const source of sources) {
|
|
205
|
+
const result = this.dijkstra(graph, source);
|
|
206
|
+
for (const [node, dist] of result.distances) {
|
|
207
|
+
const existing = distances.get(node);
|
|
208
|
+
if (existing === undefined || dist < existing) {
|
|
209
|
+
distances.set(node, dist);
|
|
210
|
+
predecessors.set(node, result.predecessors.get(node) ?? null);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
distances,
|
|
217
|
+
predecessors,
|
|
218
|
+
pivots: allPivots,
|
|
219
|
+
computedAt: new Date(),
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
// ── Dijkstra (base case) ────────────────────────────────────────────────────
|
|
223
|
+
/** Standard Dijkstra with min-heap for single-source shortest path */
|
|
224
|
+
dijkstra(graph, source) {
|
|
225
|
+
const distances = new Map();
|
|
226
|
+
const predecessors = new Map();
|
|
227
|
+
const visited = new Set();
|
|
228
|
+
// Initialize
|
|
229
|
+
distances.set(source, 0);
|
|
230
|
+
predecessors.set(source, null);
|
|
231
|
+
// Simple priority queue via sorted array (adequate for moderate graph sizes)
|
|
232
|
+
const pq = [{ node: source, dist: 0 }];
|
|
233
|
+
while (pq.length > 0) {
|
|
234
|
+
// Extract minimum
|
|
235
|
+
pq.sort((a, b) => a.dist - b.dist);
|
|
236
|
+
const current = pq.shift();
|
|
237
|
+
if (visited.has(current.node))
|
|
238
|
+
continue;
|
|
239
|
+
visited.add(current.node);
|
|
240
|
+
const edges = graph.adjacency.get(current.node) || [];
|
|
241
|
+
for (const edge of edges) {
|
|
242
|
+
if (visited.has(edge.to))
|
|
243
|
+
continue;
|
|
244
|
+
const newDist = current.dist + edge.weight;
|
|
245
|
+
const existingDist = distances.get(edge.to);
|
|
246
|
+
if (existingDist === undefined || newDist < existingDist) {
|
|
247
|
+
distances.set(edge.to, newDist);
|
|
248
|
+
predecessors.set(edge.to, current.node);
|
|
249
|
+
pq.push({ node: edge.to, dist: newDist });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return {
|
|
254
|
+
distances,
|
|
255
|
+
predecessors,
|
|
256
|
+
pivots: [source],
|
|
257
|
+
computedAt: new Date(),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
// ── Public Routing API ──────────────────────────────────────────────────────
|
|
261
|
+
/** Find optimal route between two nodes */
|
|
262
|
+
route(fromNode, toNode) {
|
|
263
|
+
if (!this.graph)
|
|
264
|
+
return [];
|
|
265
|
+
const cacheKey = `${fromNode}->${toNode}`;
|
|
266
|
+
const cached = this.cache.get(cacheKey);
|
|
267
|
+
if (cached) {
|
|
268
|
+
return this.reconstructPath(cached.predecessors, fromNode, toNode);
|
|
269
|
+
}
|
|
270
|
+
const n = this.graph.nodeCount;
|
|
271
|
+
const t = Math.max(1, Math.floor(Math.pow(Math.log2(Math.max(n, 2)), 2 / 3)));
|
|
272
|
+
const result = this.bmssp(this.graph, [fromNode], t);
|
|
273
|
+
this.cache.set(cacheKey, result);
|
|
274
|
+
return this.reconstructPath(result.predecessors, fromNode, toNode);
|
|
275
|
+
}
|
|
276
|
+
/** Reconstruct path from predecessor map */
|
|
277
|
+
reconstructPath(predecessors, from, to) {
|
|
278
|
+
const path = [to];
|
|
279
|
+
let current = to;
|
|
280
|
+
let safety = predecessors.size + 1;
|
|
281
|
+
while (current !== from && safety-- > 0) {
|
|
282
|
+
const pred = predecessors.get(current);
|
|
283
|
+
if (pred === null || pred === undefined)
|
|
284
|
+
return []; // No path
|
|
285
|
+
path.unshift(pred);
|
|
286
|
+
current = pred;
|
|
287
|
+
}
|
|
288
|
+
return current === from ? path : [];
|
|
289
|
+
}
|
|
290
|
+
/** Clear route cache */
|
|
291
|
+
clearCache() {
|
|
292
|
+
this.cache.clear();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
//# sourceMappingURL=sssp-router.js.map
|