Compare commits

..

1 Commits

Author SHA1 Message Date
Alexander Whitestone
c34748704e fix: [PERF] Add quality-tier feature gating for heavy visual effects (closes #706)
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 2s
2026-04-12 11:51:40 -04:00
6 changed files with 41 additions and 79 deletions

38
app.js
View File

@@ -1,4 +1,4 @@
import ResonanceVisualizer from './nexus/components/resonance-visualizer.js';\nimport * as THREE from 'three'; import * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; import { RenderPass } from 'three/addons/postprocessing/RenderPass.js';
import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js';
@@ -597,7 +597,7 @@ class PSELayer {
let pseLayer; let pseLayer;
let resonanceViz, metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator; let metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator;
let agentFSMs = {}; let agentFSMs = {};
function setupGOFAI() { function setupGOFAI() {
@@ -666,7 +666,7 @@ async function init() {
scene = new THREE.Scene(); scene = new THREE.Scene();
scene.fog = new THREE.FogExp2(0x050510, 0.012); scene.fog = new THREE.FogExp2(0x050510, 0.012);
setupGOFAI();\n resonanceViz = new ResonanceVisualizer(scene); setupGOFAI();
camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000); camera = new THREE.PerspectiveCamera(65, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.copy(playerPos); camera.position.copy(playerPos);
@@ -704,13 +704,13 @@ async function init() {
createParticles(); createParticles();
createDustParticles(); createDustParticles();
updateLoad(85); updateLoad(85);
createAmbientStructures(); if (performanceTier !== "low") createAmbientStructures();
createAgentPresences(); createAgentPresences();
createThoughtStream(); if (performanceTier !== "low") createThoughtStream();
createHarnessPulse(); createHarnessPulse();
createSessionPowerMeter(); createSessionPowerMeter();
createWorkshopTerminal(); createWorkshopTerminal();
createAshStorm(); if (performanceTier !== "low") createAshStorm();
SpatialMemory.init(scene); SpatialMemory.init(scene);
MemoryBirth.init(scene); MemoryBirth.init(scene);
MemoryBirth.wrapSpatialMemory(SpatialMemory); MemoryBirth.wrapSpatialMemory(SpatialMemory);
@@ -730,14 +730,20 @@ async function init() {
fetchGiteaData(); fetchGiteaData();
setInterval(fetchGiteaData, 30000); // Refresh every 30s setInterval(fetchGiteaData, 30000); // Refresh every 30s
composer = new EffectComposer(renderer); // Quality-tier feature gating: only enable heavy post-processing on medium/high
composer.addPass(new RenderPass(scene, camera)); if (performanceTier !== 'low') {
const bloom = new UnrealBloomPass( composer = new EffectComposer(renderer);
new THREE.Vector2(window.innerWidth, window.innerHeight), composer.addPass(new RenderPass(scene, camera));
0.6, 0.4, 0.85 const bloomStrength = performanceTier === 'high' ? 0.6 : 0.35;
); const bloom = new UnrealBloomPass(
composer.addPass(bloom); new THREE.Vector2(window.innerWidth, window.innerHeight),
composer.addPass(new SMAAPass(window.innerWidth, window.innerHeight)); bloomStrength, 0.4, 0.85
);
composer.addPass(bloom);
composer.addPass(new SMAAPass(window.innerWidth, window.innerHeight));
} else {
composer = null;
}
updateLoad(95); updateLoad(95);
@@ -3127,7 +3133,7 @@ function gameLoop() {
core.material.emissiveIntensity = 1.5 + Math.sin(elapsed * 2) * 0.5; core.material.emissiveIntensity = 1.5 + Math.sin(elapsed * 2) * 0.5;
} }
composer.render(); if (composer) { composer.render(); } else { renderer.render(scene, camera); }
updateAshStorm(delta, elapsed); updateAshStorm(delta, elapsed);
@@ -3166,7 +3172,7 @@ function onResize() {
camera.aspect = w / h; camera.aspect = w / h;
camera.updateProjectionMatrix(); camera.updateProjectionMatrix();
renderer.setSize(w, h); renderer.setSize(w, h);
composer.setSize(w, h); if (composer) composer.setSize(w, h);
} }
// ═══ AGENT SIMULATION ═══ // ═══ AGENT SIMULATION ═══

View File

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

View File

@@ -1,14 +0,0 @@
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

@@ -1,22 +0,0 @@
"""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

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

View File

@@ -48,21 +48,24 @@ async def broadcast_handler(websocket: websockets.WebSocketServerProtocol):
pass pass
# Broadcast to all OTHER clients # Broadcast to all OTHER clients
if not clients:
continue
disconnected = set() disconnected = set()
# Create broadcast tasks paired with their target client # Create broadcast tasks for efficiency
task_client_pairs = [] tasks = []
for client in clients: for client in clients:
if client != websocket and client.open: if client != websocket and client.open:
task = asyncio.create_task(client.send(message)) tasks.append(asyncio.create_task(client.send(message)))
task_client_pairs.append((task, client))
if tasks:
if task_client_pairs:
tasks = [t for t, _ in task_client_pairs]
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(*tasks, return_exceptions=True)
for (task, client), result in zip(task_client_pairs, results): for i, result in enumerate(results):
if isinstance(result, Exception): if isinstance(result, Exception):
logger.error(f"Failed to send to a client {client.remote_address}: {result}") # Find the client that failed
disconnected.add(client) target_client = [c for c in clients if c != websocket][i]
logger.error(f"Failed to send to a client {target_client.remote_address}: {result}")
disconnected.add(target_client)
if disconnected: if disconnected:
clients.difference_update(disconnected) clients.difference_update(disconnected)