Compare commits

...

9 Commits

Author SHA1 Message Date
Alexander Whitestone
5bc3e0879d fix: closes #675
Some checks failed
CI / test (pull_request) Failing after 8s
CI / validate (pull_request) Failing after 14s
Review Approval Gate / verify-review (pull_request) Failing after 3s
2026-04-12 12:27:45 -04:00
aab3e607eb Merge pull request '[GOFAI] Resonance Viz Integration' (#1297) from feat/resonance-viz-integration-1776010801023 into main
Some checks failed
Deploy Nexus / deploy (push) Failing after 3s
Staging Verification Gate / verify-staging (push) Failing after 3s
2026-04-12 16:20:09 +00:00
fe56ece1ad Integrate ResonanceVisualizer into app.js
Some checks failed
CI / test (pull_request) Failing after 10s
CI / validate (pull_request) Failing after 16s
Review Approval Gate / verify-review (pull_request) Failing after 3s
2026-04-12 16:20:03 +00:00
bf477382ba Merge pull request '[GOFAI] Resonance Linking' (#1293) from feat/resonance-linker-1776010647557 into main
Some checks failed
Deploy Nexus / deploy (push) Failing after 3s
Staging Verification Gate / verify-staging (push) Failing after 3s
2026-04-12 16:17:33 +00:00
fba972f8be Add ResonanceLinker
Some checks failed
CI / test (pull_request) Failing after 10s
CI / validate (pull_request) Failing after 15s
Review Approval Gate / verify-review (pull_request) Failing after 3s
2026-04-12 16:17:28 +00:00
6786e65f3d Merge pull request '[GOFAI] Layer 4 — Reasoning & Decay' (#1292) from feat/gofai-layer-4-v2 into main
Some checks failed
Deploy Nexus / deploy (push) Failing after 2s
Staging Verification Gate / verify-staging (push) Failing after 3s
2026-04-12 16:15:29 +00:00
62a6581827 Add rules
Some checks failed
CI / test (pull_request) Failing after 10s
CI / validate (pull_request) Failing after 15s
Review Approval Gate / verify-review (pull_request) Failing after 3s
2026-04-12 16:15:24 +00:00
797f32a7fe Add Reasoner 2026-04-12 16:15:23 +00:00
80eb4ff7ea Enhance MemoryOptimizer 2026-04-12 16:15:22 +00:00
6 changed files with 105 additions and 12 deletions

6
app.js
View File

@@ -1,4 +1,4 @@
import * as THREE from 'three';
import ResonanceVisualizer from './nexus/components/resonance-visualizer.js';\nimport * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
@@ -597,7 +597,7 @@ class PSELayer {
let pseLayer;
let metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator;
let resonanceViz, metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator;
let agentFSMs = {};
function setupGOFAI() {
@@ -666,7 +666,7 @@ async function init() {
scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x050510, 0.012);
setupGOFAI();
setupGOFAI();\n resonanceViz = new ResonanceVisualizer(scene);
camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.copy(playerPos);

View File

@@ -1,13 +1,18 @@
class MemoryOptimizer {
constructor(options = {}) {
this.threshold = options.threshold || 0.8;
this.decayRate = options.decayRate || 0.05;
this.threshold = options.threshold || 0.3;
this.decayRate = options.decayRate || 0.01;
this.lastRun = Date.now();
}
optimize(memory) {
console.log('Optimizing memory...');
// Heuristic-based pruning
return memory.filter(m => m.strength > this.threshold);
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);
}
}
export default MemoryOptimizer;

View File

@@ -694,15 +694,61 @@ const SpatialMemory = (() => {
}
}
// ─── CONTEXT COMPACTION (issue #675) ──────────────────
const COMPACT_CONTENT_MAXLEN = 80; // max chars for low-strength memories
const COMPACT_STRENGTH_THRESHOLD = 0.5; // below this, content gets truncated
const COMPACT_MAX_CONNECTIONS = 5; // cap connections per memory
const COMPACT_POSITION_DECIMALS = 1; // round positions to 1 decimal
function _compactPosition(pos) {
const factor = Math.pow(10, COMPACT_POSITION_DECIMALS);
return pos.map(v => Math.round(v * factor) / factor);
}
/**
* Deterministically compact a memory for storage.
* Same input always produces same output — no randomness.
* Strong memories keep full fidelity; weak memories get truncated.
*/
function _compactMemory(o) {
const strength = o.mesh.userData.strength || 0.7;
const content = o.data.content || '';
const connections = o.data.connections || [];
// Deterministic content truncation for weak memories
let compactContent = content;
if (strength < COMPACT_STRENGTH_THRESHOLD && content.length > COMPACT_CONTENT_MAXLEN) {
compactContent = content.slice(0, COMPACT_CONTENT_MAXLEN) + '\u2026';
}
// Cap connections (keep first N, deterministic)
const compactConnections = connections.length > COMPACT_MAX_CONNECTIONS
? connections.slice(0, COMPACT_MAX_CONNECTIONS)
: connections;
return {
id: o.data.id,
content: compactContent,
category: o.region,
position: _compactPosition([o.mesh.position.x, o.mesh.position.y - 1.5, o.mesh.position.z]),
source: o.data.source || 'unknown',
timestamp: o.data.timestamp || o.mesh.userData.createdAt,
strength: Math.round(strength * 100) / 100, // 2 decimal precision
connections: compactConnections
};
}
// ─── PERSISTENCE ─────────────────────────────────────
function exportIndex() {
function exportIndex(options = {}) {
const compact = options.compact !== false; // compact by default
return {
version: 1,
exportedAt: new Date().toISOString(),
compacted: compact,
regions: Object.fromEntries(
Object.entries(REGIONS).map(([k, v]) => [k, { label: v.label, center: v.center, radius: v.radius, color: v.color }])
),
memories: Object.values(_memoryObjects).map(o => ({
memories: Object.values(_memoryObjects).map(o => compact ? _compactMemory(o) : {
id: o.data.id,
content: o.data.content,
category: o.region,
@@ -711,7 +757,7 @@ const SpatialMemory = (() => {
timestamp: o.data.timestamp || o.mesh.userData.createdAt,
strength: o.mesh.userData.strength || 0.7,
connections: o.data.connections || []
}))
})
};
}

View File

@@ -0,0 +1,14 @@
class Reasoner:
def __init__(self, rules):
self.rules = rules
def evaluate(self, entries):
return [r['action'] for r in self.rules if self._check(r['condition'], entries)]
def _check(self, cond, entries):
if cond.startswith('count'):
# e.g. count(type=anomaly)>3
p = cond.replace('count(', '').split(')')
key, val = p[0].split('=')
count = sum(1 for e in entries if e.get(key) == val)
return eval(f"{count}{p[1]}")
return False

View File

@@ -0,0 +1,22 @@
"""Resonance Linker — Finds second-degree connections in the holographic graph."""
class ResonanceLinker:
def __init__(self, archive):
self.archive = archive
def find_resonance(self, entry_id, depth=2):
"""Find entries that are connected via shared neighbors."""
if entry_id not in self.archive._entries: return []
entry = self.archive._entries[entry_id]
neighbors = set(entry.links)
resonance = {}
for neighbor_id in neighbors:
if neighbor_id in self.archive._entries:
for second_neighbor in self.archive._entries[neighbor_id].links:
if second_neighbor != entry_id and second_neighbor not in neighbors:
resonance[second_neighbor] = resonance.get(second_neighbor, 0) + 1
return sorted(resonance.items(), key=lambda x: x[1], reverse=True)

View File

@@ -0,0 +1,6 @@
[
{
"condition": "count(type=anomaly)>3",
"action": "alert"
}
]