Compare commits
2 Commits
main
...
feat/mnemo
| Author | SHA1 | Date | |
|---|---|---|---|
| f9146b40ef | |||
| c1b56571ed |
196
app.js
196
app.js
@@ -41,6 +41,7 @@ let harnessPulseMesh;
|
||||
let powerMeterBars = [];
|
||||
let particles, dustParticles;
|
||||
let debugOverlay;
|
||||
let spatialSchema; // Project Mnemosyne — Spatial Memory Schema
|
||||
let frameCount = 0, lastFPSTime = 0, fps = 0;
|
||||
let chatOpen = true;
|
||||
let loadProgress = 0;
|
||||
@@ -592,6 +593,192 @@ let pseLayer;
|
||||
let metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator;
|
||||
let agentFSMs = {};
|
||||
|
||||
|
||||
// ═══════════════════════════════════════════
|
||||
// PROJECT MNEMOSYNE — SPATIAL MEMORY SCHEMA
|
||||
// ═══════════════════════════════════════════
|
||||
|
||||
/**
|
||||
* SpatialMemorySchema — Maps memory categories to persistent 3D world regions.
|
||||
* Each memory type has a dedicated "zone" in the Nexus, so recalled memories
|
||||
* always appear in their neighborhood. Zones persist via localStorage.
|
||||
*/
|
||||
class SpatialMemorySchema {
|
||||
constructor() {
|
||||
this.zones = new Map();
|
||||
this.zoneVisuals = [];
|
||||
this.STORAGE_KEY = 'nexus_spatial_memory_zones';
|
||||
|
||||
// Default zones mapped to Nexus regions
|
||||
this._defineDefaultZones();
|
||||
this._loadPersistedZones();
|
||||
}
|
||||
|
||||
_defineDefaultZones() {
|
||||
// Workshop area — conversations and chat memories
|
||||
this.registerZone('conversations', new THREE.Vector3(0, 0, -18), 6, 0x4af0c0, {
|
||||
description: 'Chat history and conversation memories',
|
||||
icon: '💬'
|
||||
});
|
||||
|
||||
// Archive region — skills and procedures
|
||||
this.registerZone('skills', new THREE.Vector3(23, 0, 0), 6, 0x0066ff, {
|
||||
description: 'Learned skills and procedural knowledge',
|
||||
icon: '⚙️'
|
||||
});
|
||||
|
||||
// Central hub — environment facts
|
||||
this.registerZone('facts', new THREE.Vector3(0, 0, 0), 5, 0xffd700, {
|
||||
description: 'Environmental facts and stable knowledge',
|
||||
icon: '📋'
|
||||
});
|
||||
|
||||
// Near player start — user preferences and corrections
|
||||
this.registerZone('preferences', new THREE.Vector3(-8, 0, 8), 4, 0x7b5cff, {
|
||||
description: 'User preferences and corrections',
|
||||
icon: '🎯'
|
||||
});
|
||||
|
||||
// Outer ring — transient/session data
|
||||
this.registerZone('transient', new THREE.Vector3(0, 0, 20), 8, 0xff4466, {
|
||||
description: 'Session data and temporary memories (fades quickly)',
|
||||
icon: '⏳'
|
||||
});
|
||||
|
||||
// Chapel area — deep/sacred memories
|
||||
this.registerZone('deep', new THREE.Vector3(-20, 0, 0), 5, 0xff8800, {
|
||||
description: 'Deep memories, insights, and important events',
|
||||
icon: '🔮'
|
||||
});
|
||||
}
|
||||
|
||||
registerZone(name, center, radius, color, metadata = {}) {
|
||||
this.zones.set(name, {
|
||||
name,
|
||||
center: center.clone(),
|
||||
radius,
|
||||
color,
|
||||
metadata,
|
||||
orbCount: 0,
|
||||
createdAt: Date.now()
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Route a memory object to its zone based on type.
|
||||
* @param {object} memoryObj — { type, source, content, score, ... }
|
||||
* @returns {{ zone: string, position: THREE.Vector3, color: number }}
|
||||
*/
|
||||
assignMemory(memoryObj) {
|
||||
const type = (memoryObj.type || 'facts').toLowerCase();
|
||||
const zone = this.zones.get(type) || this.zones.get('facts');
|
||||
zone.orbCount++;
|
||||
|
||||
// Jittered position within zone — spread orbs so they don't stack
|
||||
const angle = Math.random() * Math.PI * 2;
|
||||
const dist = Math.random() * zone.radius * 0.8;
|
||||
const position = new THREE.Vector3(
|
||||
zone.center.x + Math.cos(angle) * dist,
|
||||
1.5 + Math.random() * 2,
|
||||
zone.center.z + Math.sin(angle) * dist
|
||||
);
|
||||
|
||||
return { zone: zone.name, position, color: zone.color };
|
||||
}
|
||||
|
||||
getZonePosition(type) {
|
||||
const zone = this.zones.get(type) || this.zones.get('facts');
|
||||
return zone.center.clone();
|
||||
}
|
||||
|
||||
listZones() {
|
||||
const result = [];
|
||||
this.zones.forEach((z, name) => {
|
||||
result.push({
|
||||
name,
|
||||
center: { x: z.center.x, y: z.center.y, z: z.center.z },
|
||||
radius: z.radius,
|
||||
color: '#' + z.color.toString(16).padStart(6, '0'),
|
||||
orbCount: z.orbCount,
|
||||
description: z.metadata.description
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw subtle ground rings at each zone boundary.
|
||||
* Call once after scene is initialized.
|
||||
*/
|
||||
visualizeZones() {
|
||||
if (typeof scene === 'undefined') return;
|
||||
|
||||
this.zones.forEach((zone, name) => {
|
||||
// Ground ring
|
||||
const ringGeo = new THREE.RingGeometry(zone.radius - 0.15, zone.radius + 0.15, 64);
|
||||
const ringMat = new THREE.MeshBasicMaterial({
|
||||
color: zone.color,
|
||||
transparent: true,
|
||||
opacity: 0.25,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
const ring = new THREE.Mesh(ringGeo, ringMat);
|
||||
ring.rotation.x = -Math.PI / 2;
|
||||
ring.position.copy(zone.center);
|
||||
ring.position.y = 0.02;
|
||||
scene.add(ring);
|
||||
|
||||
// Inner glow disc
|
||||
const discGeo = new THREE.CircleGeometry(zone.radius, 64);
|
||||
const discMat = new THREE.MeshBasicMaterial({
|
||||
color: zone.color,
|
||||
transparent: true,
|
||||
opacity: 0.04,
|
||||
side: THREE.DoubleSide
|
||||
});
|
||||
const disc = new THREE.Mesh(discGeo, discMat);
|
||||
disc.rotation.x = -Math.PI / 2;
|
||||
disc.position.copy(zone.center);
|
||||
disc.position.y = 0.01;
|
||||
scene.add(disc);
|
||||
|
||||
this.zoneVisuals.push(ring, disc);
|
||||
});
|
||||
|
||||
console.info('[Mnemosyne] Zone visualization created for', this.zones.size, 'zones');
|
||||
}
|
||||
|
||||
_persistZones() {
|
||||
try {
|
||||
const data = {};
|
||||
this.zones.forEach((z, name) => {
|
||||
data[name] = {
|
||||
center: { x: z.center.x, y: z.center.y, z: z.center.z },
|
||||
radius: z.radius,
|
||||
orbCount: z.orbCount
|
||||
};
|
||||
});
|
||||
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data));
|
||||
} catch (e) { /* storage full or unavailable */ }
|
||||
}
|
||||
|
||||
_loadPersistedZones() {
|
||||
try {
|
||||
const raw = localStorage.getItem(this.STORAGE_KEY);
|
||||
if (!raw) return;
|
||||
const data = JSON.parse(raw);
|
||||
Object.entries(data).forEach(([name, saved]) => {
|
||||
const zone = this.zones.get(name);
|
||||
if (zone && saved.orbCount) {
|
||||
zone.orbCount = saved.orbCount;
|
||||
}
|
||||
});
|
||||
} catch (e) { /* corrupt or missing */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setupGOFAI() {
|
||||
knowledgeGraph = new KnowledgeGraph();
|
||||
blackboard = new Blackboard();
|
||||
@@ -606,6 +793,10 @@ function setupGOFAI() {
|
||||
pseLayer = new PSELayer();
|
||||
calibrator = new AdaptiveCalibrator('nexus-v1', { base_rate: 0.05 });
|
||||
|
||||
// Initialize Spatial Memory Schema (Project Mnemosyne)
|
||||
spatialSchema = new SpatialMemorySchema();
|
||||
console.info('[Mnemosyne] Spatial Memory Schema initialized with', spatialSchema.zones.size, 'zones');
|
||||
|
||||
// Setup initial facts
|
||||
symbolicEngine.addFact('energy', 100);
|
||||
symbolicEngine.addFact('stability', 1.0);
|
||||
@@ -2936,6 +3127,11 @@ function updateAshStorm(delta, elapsed) {
|
||||
init().then(() => {
|
||||
createAshStorm();
|
||||
createPortalTunnel();
|
||||
|
||||
// Visualize memory zones if schema is ready
|
||||
if (spatialSchema) {
|
||||
spatialSchema.visualizeZones();
|
||||
}
|
||||
fetchGiteaData();
|
||||
setInterval(fetchGiteaData, 30000);
|
||||
runWeeklyAudit();
|
||||
|
||||
312
spatial-memory-schema.json
Normal file
312
spatial-memory-schema.json
Normal file
@@ -0,0 +1,312 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"project": "Mnemosyne",
|
||||
"description": "Spatial memory schema for holographic memory visualization",
|
||||
"rooms": {
|
||||
"library": {
|
||||
"name": "The Library",
|
||||
"category": "user_pref",
|
||||
"description": "User preferences and personal settings",
|
||||
"visual_theme": {
|
||||
"lighting": "soft_ambient",
|
||||
"colors": {
|
||||
"primary": "#8B4513",
|
||||
"secondary": "#DAA520",
|
||||
"accent": "#FFD700",
|
||||
"particle": "#FFE4B5"
|
||||
},
|
||||
"materials": {
|
||||
"floor": "dark_wood",
|
||||
"walls": "bookshelf",
|
||||
"ceiling": "vaulted_stone"
|
||||
},
|
||||
"particle_effects": [
|
||||
"dust_motes",
|
||||
"book_sparkles"
|
||||
]
|
||||
},
|
||||
"spatial_bounds": {
|
||||
"center": [
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"dimensions": [
|
||||
20,
|
||||
10,
|
||||
20
|
||||
],
|
||||
"orb_density": 0.7
|
||||
},
|
||||
"object_types": {
|
||||
"preference": {
|
||||
"shape": "sphere",
|
||||
"base_size": 0.3,
|
||||
"glow_intensity": 0.8
|
||||
},
|
||||
"setting": {
|
||||
"shape": "cube",
|
||||
"base_size": 0.4,
|
||||
"glow_intensity": 0.6
|
||||
}
|
||||
}
|
||||
},
|
||||
"workshop": {
|
||||
"name": "The Workshop",
|
||||
"category": "project",
|
||||
"description": "Active projects and development work",
|
||||
"visual_theme": {
|
||||
"lighting": "bright_work",
|
||||
"colors": {
|
||||
"primary": "#4682B4",
|
||||
"secondary": "#B0C4DE",
|
||||
"accent": "#00BFFF",
|
||||
"particle": "#87CEEB"
|
||||
},
|
||||
"materials": {
|
||||
"floor": "polished_concrete",
|
||||
"walls": "blueprint_paper",
|
||||
"ceiling": "industrial_metal"
|
||||
},
|
||||
"particle_effects": [
|
||||
"blueprint_lines",
|
||||
"tool_sparks"
|
||||
]
|
||||
},
|
||||
"spatial_bounds": {
|
||||
"center": [
|
||||
30,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"dimensions": [
|
||||
25,
|
||||
12,
|
||||
25
|
||||
],
|
||||
"orb_density": 0.8
|
||||
},
|
||||
"object_types": {
|
||||
"project": {
|
||||
"shape": "pyramid",
|
||||
"base_size": 0.5,
|
||||
"glow_intensity": 0.9
|
||||
},
|
||||
"task": {
|
||||
"shape": "cube",
|
||||
"base_size": 0.3,
|
||||
"glow_intensity": 0.7
|
||||
}
|
||||
}
|
||||
},
|
||||
"armory": {
|
||||
"name": "The Armory",
|
||||
"category": "tool",
|
||||
"description": "Tools, skills, and capabilities",
|
||||
"visual_theme": {
|
||||
"lighting": "neon_glow",
|
||||
"colors": {
|
||||
"primary": "#2E8B57",
|
||||
"secondary": "#3CB371",
|
||||
"accent": "#00FF7F",
|
||||
"particle": "#98FB98"
|
||||
},
|
||||
"materials": {
|
||||
"floor": "chrome_grid",
|
||||
"walls": "server_rack",
|
||||
"ceiling": "neon_tube"
|
||||
},
|
||||
"particle_effects": [
|
||||
"data_streams",
|
||||
"circuit_traces"
|
||||
]
|
||||
},
|
||||
"spatial_bounds": {
|
||||
"center": [
|
||||
0,
|
||||
0,
|
||||
30
|
||||
],
|
||||
"dimensions": [
|
||||
15,
|
||||
8,
|
||||
15
|
||||
],
|
||||
"orb_density": 0.6
|
||||
},
|
||||
"object_types": {
|
||||
"tool": {
|
||||
"shape": "octahedron",
|
||||
"base_size": 0.4,
|
||||
"glow_intensity": 1.0
|
||||
},
|
||||
"skill": {
|
||||
"shape": "sphere",
|
||||
"base_size": 0.35,
|
||||
"glow_intensity": 0.85
|
||||
}
|
||||
}
|
||||
},
|
||||
"commons": {
|
||||
"name": "The Commons",
|
||||
"category": "general",
|
||||
"description": "General knowledge and miscellaneous facts",
|
||||
"visual_theme": {
|
||||
"lighting": "natural_daylight",
|
||||
"colors": {
|
||||
"primary": "#9370DB",
|
||||
"secondary": "#BA55D3",
|
||||
"accent": "#DA70D6",
|
||||
"particle": "#E6E6FA"
|
||||
},
|
||||
"materials": {
|
||||
"floor": "grass",
|
||||
"walls": "floating_islands",
|
||||
"ceiling": "open_sky"
|
||||
},
|
||||
"particle_effects": [
|
||||
"floating_pollen",
|
||||
"lightning_bugs"
|
||||
]
|
||||
},
|
||||
"spatial_bounds": {
|
||||
"center": [
|
||||
30,
|
||||
0,
|
||||
30
|
||||
],
|
||||
"dimensions": [
|
||||
30,
|
||||
15,
|
||||
30
|
||||
],
|
||||
"orb_density": 0.5
|
||||
},
|
||||
"object_types": {
|
||||
"fact": {
|
||||
"shape": "sphere",
|
||||
"base_size": 0.25,
|
||||
"glow_intensity": 0.7
|
||||
},
|
||||
"memory": {
|
||||
"shape": "dodecahedron",
|
||||
"base_size": 0.3,
|
||||
"glow_intensity": 0.65
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"object_properties": {
|
||||
"trust_mapping": {
|
||||
"description": "Maps trust score (0.0-1.0) to visual properties",
|
||||
"glow_intensity": {
|
||||
"min": 0.2,
|
||||
"max": 1.0,
|
||||
"curve": "linear"
|
||||
},
|
||||
"opacity": {
|
||||
"min": 0.3,
|
||||
"max": 1.0,
|
||||
"curve": "ease_in_out"
|
||||
}
|
||||
},
|
||||
"importance_mapping": {
|
||||
"description": "Maps importance (relation count) to visual properties",
|
||||
"scale": {
|
||||
"min": 0.2,
|
||||
"max": 2.0,
|
||||
"curve": "logarithmic"
|
||||
},
|
||||
"particle_density": {
|
||||
"min": 10,
|
||||
"max": 100,
|
||||
"curve": "linear"
|
||||
}
|
||||
},
|
||||
"lifecycle_events": {
|
||||
"FACT_CREATED": {
|
||||
"animation": "fade_in",
|
||||
"duration": 1.5,
|
||||
"particle_effect": "spawn_burst"
|
||||
},
|
||||
"FACT_UPDATED": {
|
||||
"animation": "pulse_glow",
|
||||
"duration": 0.8,
|
||||
"particle_effect": "update_ripple"
|
||||
},
|
||||
"FACT_REMOVED": {
|
||||
"animation": "dissolve",
|
||||
"duration": 2.0,
|
||||
"particle_effect": "scatter"
|
||||
},
|
||||
"FACT_RECALLED": {
|
||||
"animation": "beam_light",
|
||||
"duration": 1.0,
|
||||
"particle_effect": "recall_beam"
|
||||
}
|
||||
}
|
||||
},
|
||||
"connections": {
|
||||
"holographic_threads": {
|
||||
"description": "Visual connections between related memory orbs",
|
||||
"material": "transparent_glow",
|
||||
"colors": {
|
||||
"strong_relation": "#00FFFF",
|
||||
"medium_relation": "#00CED1",
|
||||
"weak_relation": "#5F9EA0"
|
||||
},
|
||||
"thickness": {
|
||||
"min": 0.02,
|
||||
"max": 0.1,
|
||||
"curve": "linear"
|
||||
}
|
||||
},
|
||||
"cross_room_portals": {
|
||||
"description": "Portals connecting different memory rooms",
|
||||
"effect": "swirling_vortex",
|
||||
"colors": {
|
||||
"library_workshop": "#FFD700",
|
||||
"workshop_armory": "#00BFFF",
|
||||
"armory_commons": "#00FF7F",
|
||||
"commons_library": "#DA70D6"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rag_integration": {
|
||||
"retrieval_visualization": {
|
||||
"description": "How RAG retrieval results are visualized",
|
||||
"highlight_effect": "golden_glow",
|
||||
"spiral_arrangement": {
|
||||
"radius": 3.0,
|
||||
"height_step": 0.5,
|
||||
"rotation_step": 0.618033988749895
|
||||
},
|
||||
"relevance_scoring": {
|
||||
"high": {
|
||||
"color": "#FFD700",
|
||||
"size_multiplier": 1.5
|
||||
},
|
||||
"medium": {
|
||||
"color": "#FFA500",
|
||||
"size_multiplier": 1.2
|
||||
},
|
||||
"low": {
|
||||
"color": "#FF8C00",
|
||||
"size_multiplier": 1.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"query_beam": {
|
||||
"description": "Beam from user to relevant memory orbs",
|
||||
"color": "#FFFFFF",
|
||||
"opacity": 0.8,
|
||||
"pulse_frequency": 2.0
|
||||
}
|
||||
},
|
||||
"animation_timing": {
|
||||
"orb_spawn_delay": 0.1,
|
||||
"room_transition_duration": 2.0,
|
||||
"connection_draw_speed": 0.5,
|
||||
"particle_fade_time": 1.5
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user