exo-wasm 0.1.0

WASM bindings for EXO-AI 2025 cognitive substrate - browser and edge deployment
Documentation
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EXO-WASM Browser Demo</title>
    <style>
        body {
            font-family: system-ui, -apple-system, sans-serif;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background: #0a0a0a;
            color: #e0e0e0;
        }
        h1 {
            color: #00ff88;
            border-bottom: 2px solid #00ff88;
            padding-bottom: 10px;
        }
        .controls {
            background: #1a1a1a;
            padding: 20px;
            border-radius: 8px;
            margin: 20px 0;
        }
        button {
            background: #00ff88;
            color: #0a0a0a;
            border: none;
            padding: 10px 20px;
            margin: 5px;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
        }
        button:hover {
            background: #00dd77;
        }
        .output {
            background: #1a1a1a;
            border: 1px solid #333;
            border-radius: 8px;
            padding: 15px;
            margin: 10px 0;
            font-family: 'Courier New', monospace;
            font-size: 14px;
            white-space: pre-wrap;
            max-height: 400px;
            overflow-y: auto;
        }
        .status {
            padding: 10px;
            margin: 10px 0;
            border-radius: 4px;
        }
        .status.success { background: #003322; color: #00ff88; }
        .status.error { background: #330000; color: #ff6666; }
        .status.info { background: #001133; color: #6688ff; }
        input {
            background: #2a2a2a;
            border: 1px solid #444;
            color: #e0e0e0;
            padding: 8px;
            border-radius: 4px;
            margin: 5px;
        }
    </style>
</head>
<body>
    <h1>🧠 EXO-AI 2025 WASM Demo</h1>

    <div class="status info" id="status">
        Initializing WASM module...
    </div>

    <div class="controls">
        <h2>Substrate Controls</h2>
        <div>
            <label>Dimensions: <input type="number" id="dimensions" value="128" min="1" max="1024"></label>
            <label>Metric:
                <select id="metric" style="background: #2a2a2a; color: #e0e0e0; padding: 8px; border: 1px solid #444; border-radius: 4px;">
                    <option value="cosine">Cosine</option>
                    <option value="euclidean">Euclidean</option>
                    <option value="dotproduct">Dot Product</option>
                    <option value="manhattan">Manhattan</option>
                </select>
            </label>
            <button onclick="initSubstrate()">Initialize Substrate</button>
        </div>

        <div style="margin-top: 15px;">
            <label>Patterns to generate: <input type="number" id="numPatterns" value="100" min="1" max="10000"></label>
            <button onclick="generatePatterns()">Generate Random Patterns</button>
        </div>

        <div style="margin-top: 15px;">
            <button onclick="querySubstrate()">Query Similar Patterns</button>
            <button onclick="showStats()">Show Statistics</button>
            <button onclick="benchmark()">Run Benchmark</button>
        </div>
    </div>

    <div class="output" id="output">
Waiting for initialization...
    </div>

    <script type="module">
        import init, { ExoSubstrate, Pattern, version, detect_simd } from './pkg/exo_wasm.js';

        let substrate = null;
        let patternIds = [];

        function log(message) {
            const output = document.getElementById('output');
            const timestamp = new Date().toLocaleTimeString();
            output.textContent += `[${timestamp}] ${message}\n`;
            output.scrollTop = output.scrollHeight;
        }

        function setStatus(message, type = 'info') {
            const status = document.getElementById('status');
            status.textContent = message;
            status.className = `status ${type}`;
        }

        async function initialize() {
            try {
                await init();

                const v = version();
                const simd = detect_simd();

                log(` EXO-WASM initialized successfully`);
                log(`  Version: ${v}`);
                log(`  SIMD Support: ${simd ? 'Yes' : 'No'}`);
                log('');

                setStatus('Ready to create substrate', 'success');

                // Auto-initialize with default settings
                window.initSubstrate();
            } catch (error) {
                log(` Initialization failed: ${error}`);
                setStatus('Initialization failed', 'error');
            }
        }

        window.initSubstrate = function() {
            try {
                const dimensions = parseInt(document.getElementById('dimensions').value);
                const metric = document.getElementById('metric').value;

                log(`Creating substrate with ${dimensions} dimensions and ${metric} metric...`);

                substrate = new ExoSubstrate({
                    dimensions: dimensions,
                    distance_metric: metric,
                    use_hnsw: true,
                    enable_temporal: true,
                    enable_causal: true
                });

                log('✓ Substrate created successfully');
                setStatus(`Substrate ready (${dimensions}D, ${metric})`, 'success');
            } catch (error) {
                log(` Failed to create substrate: ${error.message}`);
                setStatus('Substrate creation failed', 'error');
            }
        };

        window.generatePatterns = function() {
            if (!substrate) {
                log('✗ Please initialize substrate first');
                return;
            }

            try {
                const numPatterns = parseInt(document.getElementById('numPatterns').value);
                const dimensions = substrate.dimensions;

                log(`Generating ${numPatterns} random patterns...`);
                const startTime = performance.now();

                patternIds = [];
                for (let i = 0; i < numPatterns; i++) {
                    const embedding = new Float32Array(dimensions);
                    for (let j = 0; j < dimensions; j++) {
                        embedding[j] = Math.random();
                    }

                    const metadata = {
                        index: i,
                        type: i % 2 === 0 ? 'even' : 'odd',
                        timestamp: Date.now()
                    };

                    const pattern = new Pattern(embedding, metadata, []);
                    const id = substrate.store(pattern);
                    patternIds.push(id);
                }

                const elapsed = performance.now() - startTime;
                const rate = (numPatterns / elapsed * 1000).toFixed(0);

                log(` Generated ${numPatterns} patterns in ${elapsed.toFixed(2)}ms`);
                log(`  Rate: ${rate} patterns/second`);
                setStatus(`${numPatterns} patterns stored`, 'success');
            } catch (error) {
                log(` Error generating patterns: ${error.message}`);
                setStatus('Pattern generation failed', 'error');
            }
        };

        window.querySubstrate = async function() {
            if (!substrate || patternIds.length === 0) {
                log('✗ Please generate patterns first');
                return;
            }

            try {
                const dimensions = substrate.dimensions;
                const queryVector = new Float32Array(dimensions);
                for (let i = 0; i < dimensions; i++) {
                    queryVector[i] = Math.random();
                }

                log('Executing similarity search...');
                const startTime = performance.now();

                const results = await substrate.query(queryVector, 10);

                const elapsed = performance.now() - startTime;

                log(` Search completed in ${elapsed.toFixed(2)}ms`);
                log(`  Found ${results.length} results:`);

                results.slice(0, 5).forEach((result, i) => {
                    log(`  ${i + 1}. ID: ${result.id.slice(0, 8)}... Score: ${result.score.toFixed(4)}`);
                });

                setStatus(`Query returned ${results.length} results in ${elapsed.toFixed(2)}ms`, 'success');
            } catch (error) {
                log(` Query failed: ${error.message}`);
                setStatus('Query failed', 'error');
            }
        };

        window.showStats = function() {
            if (!substrate) {
                log('✗ Please initialize substrate first');
                return;
            }

            try {
                const stats = substrate.stats();
                const length = substrate.len();
                const isEmpty = substrate.isEmpty();

                log('Substrate Statistics:');
                log(`  Dimensions: ${stats.dimensions}`);
                log(`  Pattern Count: ${stats.pattern_count}`);
                log(`  Distance Metric: ${stats.distance_metric}`);
                log(`  Temporal Enabled: ${stats.temporal_enabled}`);
                log(`  Causal Enabled: ${stats.causal_enabled}`);
                log(`  Is Empty: ${isEmpty}`);
                log('');

                setStatus(`${stats.pattern_count} patterns in substrate`, 'info');
            } catch (error) {
                log(` Failed to get stats: ${error.message}`);
            }
        };

        window.benchmark = async function() {
            if (!substrate) {
                log('✗ Please initialize substrate first');
                return;
            }

            try {
                log('Running benchmark...');
                const dimensions = substrate.dimensions;
                const iterations = 100;

                // Insert benchmark
                log(`Benchmarking ${iterations} inserts...`);
                let startTime = performance.now();

                for (let i = 0; i < iterations; i++) {
                    const embedding = new Float32Array(dimensions);
                    for (let j = 0; j < dimensions; j++) {
                        embedding[j] = Math.random();
                    }
                    const pattern = new Pattern(embedding, { index: i }, []);
                    substrate.store(pattern);
                }

                let elapsed = performance.now() - startTime;
                let rate = (iterations / elapsed * 1000).toFixed(0);
                log(`  Insert: ${rate} ops/sec`);

                // Search benchmark
                log(`Benchmarking ${iterations} searches...`);
                startTime = performance.now();

                for (let i = 0; i < iterations; i++) {
                    const queryVector = new Float32Array(dimensions);
                    for (let j = 0; j < dimensions; j++) {
                        queryVector[j] = Math.random();
                    }
                    await substrate.query(queryVector, 10);
                }

                elapsed = performance.now() - startTime;
                rate = (iterations / elapsed * 1000).toFixed(0);
                log(`  Search: ${rate} ops/sec`);
                log('');

                setStatus('Benchmark complete', 'success');
            } catch (error) {
                log(` Benchmark failed: ${error.message}`);
                setStatus('Benchmark failed', 'error');
            }
        };

        // Initialize on page load
        initialize();
    </script>
</body>
</html>