53 lines
1.9 KiB
JavaScript
53 lines
1.9 KiB
JavaScript
|
|
class MemoryOptimizer {
|
|
static _lastRun = Date.now();
|
|
|
|
constructor(options = {}) {
|
|
this.threshold = options.threshold || 0.3;
|
|
this.decayRate = options.decayRate || 0.01;
|
|
this.lastRun = Date.now();
|
|
}
|
|
|
|
optimize(memories) {
|
|
const now = Date.now();
|
|
const elapsed = (now - this.lastRun) / 1000;
|
|
this.lastRun = now;
|
|
return memories.map(m => {
|
|
const decay = (m.importance || 1) * this.decayRate * elapsed;
|
|
return { ...m, strength: Math.max(0, (m.strength || 1) - decay) };
|
|
}).filter(m => m.strength > this.threshold || m.locked);
|
|
}
|
|
|
|
/**
|
|
* Static decay pass — updates SpatialMemory crystals in-place.
|
|
* Call as: MemoryOptimizer.decaySpatialMemory(spatialMemoryModule)
|
|
*/
|
|
static decaySpatialMemory(spatialMemory, { decayRate = 0.005, threshold = 0.15 } = {}) {
|
|
const now = Date.now();
|
|
const elapsed = (now - MemoryOptimizer._lastRun) / 1000;
|
|
MemoryOptimizer._lastRun = now;
|
|
|
|
const memEntries = spatialMemory.getAllMemoryEntries();
|
|
if (!memEntries || memEntries.length === 0) return 0;
|
|
|
|
let decayed = 0;
|
|
memEntries.forEach(entry => {
|
|
const currentStrength = entry.mesh?.userData?.strength ?? 0.7;
|
|
const importance = entry.data?.importance || 1;
|
|
const decay = importance * decayRate * elapsed;
|
|
const newStrength = Math.max(0, currentStrength - decay);
|
|
|
|
if (newStrength <= threshold && !entry.data?.locked) {
|
|
spatialMemory.removeMemory(entry.data.id);
|
|
decayed++;
|
|
} else if (entry.mesh) {
|
|
spatialMemory.updateMemory(entry.data.id, { strength: newStrength });
|
|
}
|
|
});
|
|
|
|
console.info(`[MemoryOptimizer] Decay pass: ${decayed} faded, ${memEntries.length - decayed} retained`);
|
|
return decayed;
|
|
}
|
|
}
|
|
export default MemoryOptimizer;
|