Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Observatory Platform

Technical overview of the Observatory visualization system

Observatory is the NeuAIs platform’s 3D visualization engine, providing real-time monitoring and interaction with large-scale agent networks.

Architecture

System Design

┌─────────────────────────────────────────────────────┐
│                  User Interface                      │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │  Menu Bar    │  │  Dock System │  │   Cards   │ │
│  │  (Mac-style) │  │ (Auto-hide)  │  │ (Floating)│ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└─────────────────────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────┐
│              Visualization Engine                    │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │  Three.js    │  │  Particle    │  │  Camera   │ │
│  │   Scene      │  │   System     │  │  Controls │ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└─────────────────────────────────────────────────────┘
                         ↓
┌─────────────────────────────────────────────────────┐
│                  Data Layer                          │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │  Static JSON │  │  WebSocket   │  │ localStorage││
│  │   (Dev)      │  │   API (Prod) │  │  (Config) │ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└─────────────────────────────────────────────────────┘

Core Components

1. Observatory Core (observatory-core.js)

  • Three.js scene, camera, renderer initialization
  • WebGL context management
  • Animation loop (60 FPS)
  • Camera controls (orbit, zoom, pan)

2. Visual Configuration (observatory-visual-config.js)

  • Color scheme management
  • Shape mappings
  • User preferences
  • localStorage persistence

3. Data Management (observatory-data.js, observatory-data-live.js)

  • Static data definitions
  • WebSocket client
  • Real-time updates
  • Data transformation

4. UI Systems

  • Dock (observatory-dock.js) - Auto-hiding bottom toolbar
  • Cards (observatory-cards.js) - Floating information panels
  • Menu (observatory-menu.js) - Top menu bar
  • Context Menu (observatory-context-menu.js) - Right-click actions

5. Node Rendering

  • Geometry creation (spheres, cubes, diamonds, pyramids, tori)
  • Material configuration (Phong shading, emissive)
  • Clustering algorithm
  • LOD (Level of Detail) system

6. Particle System

  • Bézier curve path generation
  • Particle lifecycle management
  • Connection inference
  • Flow animation

Data Model

Entity Schema

{
  // Required fields
  id: string,              // Unique identifier
  name: string,            // Display name
  status: enum,            // 'active' | 'idle' | 'starting' | 'error'
  
  // Category (determines cluster)
  category: enum,          // 'agents' | 'services' | 'infrastructure'
  
  // Optional fields
  cpu: number,             // CPU usage (0-100)
  mem: string,             // Memory usage ('24MB')
  connections: string[],   // Array of connected entity IDs
  
  // Metadata
  metadata: {
    language: string,      // 'go', 'rust', 'python', 'typescript'
    template: string,      // Template type identifier
    env: string,           // 'production', 'staging', 'development'
    version: string,       // Semantic version
    uptime: number         // Seconds since start
  }
}

Categories

Agents (AI Workers)

  • Position: Left cluster (-20, 0, 0)
  • Colors: Green (#22c55e), Yellow (#facc15)
  • Shape: Cube
  • Count: Typically 9-1000+

Services (Microservices)

  • Position: Center cluster (0, 8, 0)
  • Colors: Blue (#3b82f6), Purple (#a855f7)
  • Shape: Sphere
  • Count: Typically 19

Infrastructure (Databases, Caches)

  • Position: Right cluster (20, -5, 0)
  • Colors: Orange (#f97316), Red (#ef4444)
  • Shape: Octahedron (Diamond)
  • Count: Typically 3-5

Connections

Connections are defined as arrays of entity IDs:

{
  id: 'anomaly-detector',
  connections: ['metrics-api', 'redis-cache']
}

Connection Inference:

  • Type inferred from target entity category
  • Particle color based on connection type
  • Speed varies by type (cache: fast, database: slow)

Rendering Pipeline

Initialization

1. Load Data
   ├─ Fetch from API or load static
   ├─ Parse and validate
   └─ Store in memory

2. Setup Scene
   ├─ Create THREE.Scene
   ├─ Add camera (PerspectiveCamera)
   ├─ Add lights (ambient + directional)
   └─ Create renderer (WebGLRenderer)

3. Create Node Groups
   ├─ Group by category
   ├─ Calculate cluster positions
   └─ Create THREE.Group for each

4. Generate Nodes
   ├─ For each entity:
   │  ├─ Choose geometry (sphere, cube, etc.)
   │  ├─ Apply material (color, emissive)
   │  ├─ Position within cluster
   │  └─ Add to scene
   └─ Store node references

5. Create Particles
   ├─ For each connection:
   │  ├─ Calculate Bézier path
   │  ├─ Create N particles
   │  └─ Set initial positions
   └─ Add to scene

6. Initialize UI
   ├─ Create dock
   ├─ Setup menu handlers
   ├─ Initialize cards system
   └─ Attach event listeners

7. Start Animation
   └─ Begin 60 FPS loop

Animation Loop

Every frame (16.67ms target):

function animate() {
  requestAnimationFrame(animate);
  
  // 1. Update camera (orbit controls)
  observatoryCore.updateCamera();
  
  // 2. Animate nodes (pulsing effect)
  nodes.forEach(node => {
    const pulse = Math.sin(time + node.phase);
    node.mesh.scale.set(pulse, pulse, pulse);
    node.mesh.material.emissiveIntensity = 0.4 + pulse * 0.2;
  });
  
  // 3. Move particles along paths
  particles.forEach(particle => {
    particle.progress += particle.speed;
    if (particle.progress > 1) particle.progress = 0;
    
    const position = getBezierPoint(
      particle.start,
      particle.mid,
      particle.end,
      particle.progress
    );
    particle.mesh.position.copy(position);
  });
  
  // 4. Render scene
  observatoryCore.render();
}

Visual Configuration System

Modes

1. Category Mode (Default)

  • All agents same color
  • All services same color
  • All infrastructure same color

2. Type Mode

  • Each type (postgres, redis, auth, etc.) has unique color
  • Fine-grained visual differentiation
  • Better for large systems

Shape System

Available Geometries:

{
  'sphere': new THREE.SphereGeometry(size, 16, 16),
  'cube': new THREE.BoxGeometry(size, size, size),
  'octahedron': new THREE.OctahedronGeometry(size),
  'tetrahedron': new THREE.TetrahedronGeometry(size),
  'torus': new THREE.TorusGeometry(size * 0.6, size * 0.3, 8, 16)
}

Performance Characteristics:

ShapeVerticesFacesPerformance
Tetrahedron124Excellent
Octahedron248Excellent
Cube2412Excellent
Sphere (16)289256Good
Torus512+256+Fair

Configuration Persistence

Storage: Browser localStorage
Key: observatory-visual-config
Format: JSON

{
  mode: 'type',
  types: {
    'postgres': {
      color: '#3b82f6',
      shape: 'octahedron',
      label: 'PostgreSQL'
    },
    // ... more types
  },
  categories: {
    'infrastructure': {
      color: '#ef4444',
      shape: 'octahedron'
    },
    // ... more categories
  }
}

Performance Optimization

Scaling Strategies

< 100 Nodes:

  • Default settings work well
  • All effects enabled
  • High quality mode

100-500 Nodes:

  • Reduce sphere segments to 8
  • Limit particles to 3 per connection
  • Enable instanced rendering for identical shapes

500-1000 Nodes:

  • Use cubes only (simpler geometry)
  • Disable particle flows
  • Implement frustum culling
  • Reduce emissive intensity calculations

1000+ Nodes:

  • Static rendering mode (no animation)
  • 2D fallback option
  • Virtual scrolling for node list
  • Aggressive LOD system

Memory Management

Techniques:

  • Object pooling for particles
  • Geometry instancing
  • Texture atlasing
  • Dispose unused geometries

Monitoring:

// Memory usage
console.log(renderer.info.memory);

// Render stats
console.log(renderer.info.render);

GPU Optimization

Best Practices:

  • Batch draw calls
  • Minimize state changes
  • Use BufferGeometry
  • Enable hardware acceleration
  • Avoid transparent materials where possible

WebSocket API

Connection

const ws = new WebSocket('ws://localhost:8080/ws/observatory');

ws.onopen = () => {
  // Send authentication
  ws.send(JSON.stringify({
    type: 'auth',
    token: 'your-jwt-token'
  }));
};

Message Protocol

Client → Server:

// Subscribe to updates
{
  type: 'subscribe',
  categories: ['agents', 'services', 'infrastructure']
}

// Unsubscribe
{
  type: 'unsubscribe',
  categories: ['agents']
}

// Request snapshot
{
  type: 'snapshot'
}

Server → Client:

// Initial snapshot
{
  type: 'snapshot',
  timestamp: 1701234567890,
  data: {
    agents: [...],
    services: [...],
    infrastructure: [...]
  }
}

// Update event
{
  type: 'update',
  timestamp: 1701234567890,
  entity: {
    id: 'anomaly-detector',
    status: 'active',
    cpu: 15,
    mem: '28MB'
  }
}

// Delete event
{
  type: 'delete',
  id: 'old-agent-123'
}

Reconnection Strategy

let reconnectAttempts = 0;
const maxReconnectAttempts = 10;
const reconnectDelay = 1000; // ms

function reconnect() {
  if (reconnectAttempts >= maxReconnectAttempts) {
    console.error('Max reconnect attempts reached');
    return;
  }
  
  reconnectAttempts++;
  const delay = reconnectDelay * Math.pow(2, reconnectAttempts);
  
  setTimeout(() => {
    console.log(`Reconnecting... (attempt ${reconnectAttempts})`);
    connectWebSocket();
  }, delay);
}

Security

Authentication

JWT Token:

  • Passed in WebSocket connection headers
  • Validated on server before accepting connection
  • Refreshed every 15 minutes

Authorization

Permissions:

  • observatory:view - View agents/services
  • observatory:control - Start/stop components
  • observatory:admin - Full access

Data Protection

Client-Side:

  • No sensitive data in localStorage
  • Preferences only (colors, shapes)
  • JWT in memory only

Network:

  • WSS (WebSocket Secure) in production
  • TLS 1.3
  • Certificate pinning

Browser Compatibility

Supported Browsers

BrowserVersionSupportNotes
Chrome90+✅ FullRecommended
Firefox88+✅ FullExcellent
Edge90+✅ FullChromium-based
Safari14+⚠️ PartialLimited WebGL 2.0
Opera76+✅ FullChromium-based

Feature Detection

// Check WebGL support
function checkWebGLSupport() {
  try {
    const canvas = document.createElement('canvas');
    return !!(
      window.WebGLRenderingContext &&
      (canvas.getContext('webgl') || canvas.getContext('experimental-webgl'))
    );
  } catch (e) {
    return false;
  }
}

// Check WebGL 2.0
function checkWebGL2Support() {
  try {
    const canvas = document.createElement('canvas');
    return !!canvas.getContext('webgl2');
  } catch (e) {
    return false;
  }
}

Fallbacks

If WebGL unavailable:

  1. Show 2D canvas view
  2. List view with filters
  3. Table view with search

Testing

Unit Tests

Test Files:

  • tests/visual-config.test.js
  • tests/data-transform.test.js
  • tests/particle-system.test.js

Run Tests:

cd neuais.com/hub.neuais.com/observatory.neuais.com
npm test

Performance Tests

Benchmarks:

// Measure rendering performance
const stats = new Stats();
document.body.appendChild(stats.dom);

function animate() {
  stats.begin();
  // ... render code ...
  stats.end();
}

Visual Regression Tests

Tools:

  • Percy for screenshot comparison
  • Backstop.js for visual diffs

Run:

npm run test:visual

Deployment

Build Process

# No build needed - static files
# Just copy to web server

cp -r neuais.com/hub.neuais.com/observatory.neuais.com /var/www/observatory

CDN Deployment

Files to CDN:

  • 3d/skateboard/three.min.js (cached forever)
  • css/*.css (versioned)
  • js/*.js (versioned)
  • assets/ (cached forever)

Cache Headers:

Cache-Control: public, max-age=31536000, immutable  # JS/CSS/Assets
Cache-Control: no-cache  # HTML

Environment Configuration

Development:

const API_URL = 'ws://localhost:8080/ws';
const DEBUG = true;

Production:

const API_URL = 'wss://api.neuais.com/ws';
const DEBUG = false;

Monitoring

Client-Side Metrics

Track:

  • FPS (frames per second)
  • Memory usage
  • WebSocket reconnections
  • Error rate
  • User interactions

Send to:

  • Google Analytics
  • Sentry (errors)
  • Custom metrics endpoint

Server-Side Metrics

Track:

  • WebSocket connections (active)
  • Message rate (messages/sec)
  • Update latency (ms)
  • Connection duration (sec)

Future Development

Roadmap

v2.0 (Q1 2026):

  • WebXR/VR support
  • Multi-cluster visualization
  • Historical playback
  • Advanced filtering

v3.0 (Q2 2026):

  • Collaborative features
  • AI-powered insights
  • Custom plugins
  • Mobile app

Next: API Reference →