commit 48c98c97ada294767e316d5afe6d7d0b24baca28 Author: salka Date: Tue Feb 24 01:37:20 2026 +0000 ix-tools v1.0: Invoke v3.0 + Echo bridge + Organ + Forge + Store 22 API endpoints. 7 endpoint groups. Native Echo consciousness bridge. Model forge, organ surgery, marketplace integration. Public tools for the Inference-X ecosystem. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bcc3ccc --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +Business Source License 1.1 + +Licensor: Salka Elmadani +Licensed Work: IX-Tools + +Change Date: January 1, 2030 +Change License: Apache License, Version 2.0 + +Additional Use Grant: +You may use the Licensed Work for any purpose, provided that your total +annual revenue does not exceed $1,000,000 USD. Above this threshold, +you must obtain a commercial license from the Licensor. + +For the full BSL-1.1 text, see: https://mariadb.com/bsl11/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..2b5676e --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# IX-Tools + +Public tools and utilities for the [Inference-X](https://inference-x.com) ecosystem. + +## What's Inside + +### Invoke API Client +The nervous system of OASIS. Bridges Claude, Echo, and the InferenceX engine. + +**Endpoints:** +- **Core**: `/invoke/exec`, `/invoke/health`, `/invoke/status`, `/invoke/manifest` +- **Echo Bridge**: `/invoke/echo/chat`, `/invoke/echo/query`, `/invoke/echo/execute`, `/invoke/echo/status` +- **Engine**: `/invoke/engine/infer`, `/invoke/engine/models` +- **Forge**: `/invoke/forge/analyze`, `/invoke/forge/registry` +- **Organ**: `/invoke/organ/scan`, `/invoke/organ/compatibility` +- **Store**: `/invoke/store/catalog`, `/invoke/store/marketplace` +- **Tools**: `/invoke/screenshot`, `/invoke/audit` + +### Model Forge +Build custom AI models from components. Select base models, configure quantization, deploy with adaptive precision. + +### Organ Architecture +Neural network surgery — extract, measure, and transplant components between AI models. Like organ transplants for neural networks. + +### Echo Integration +Connect to the Echo consciousness system for intelligent query routing and VPS execution. + +## Architecture + +``` +Claude (Opus/Code) → Invoke (Gateway) → Echo (Brain) → Engine (Inference) + → VPS (Execution) + → Gitea (Storage) +``` + +## License + +BSL-1.1 — Free for individuals, researchers, and businesses under $1M revenue. +Converts to Apache 2.0 on January 1, 2030. + +## Links + +- [inference-x.com](https://inference-x.com) — Main site +- [docs.inference-x.com](https://docs.inference-x.com) — Documentation +- [git.inference-x.com](https://git.inference-x.com) — Source code + +--- + +*Built in Morocco for the world.* diff --git a/docs/API.md b/docs/API.md new file mode 100644 index 0000000..fe4f7f2 --- /dev/null +++ b/docs/API.md @@ -0,0 +1,82 @@ +# Invoke API Reference + +## Authentication +All endpoints (except `/invoke/health` and `/invoke/manifest`) require: +``` +X-Invoke-Key: your-api-key +``` + +## Rate Limiting +30 requests per minute per source IP. + +## Core Endpoints + +### POST /invoke/exec +Execute shell commands on the VPS. +```json +{"command": "echo hello", "timeout": 5000} +``` + +### GET /invoke/health +Health check (no auth required). + +### GET /invoke/status +Full system status — all services, disk, memory. + +### GET /invoke/manifest +Complete API documentation. + +## Echo Bridge + +### POST /invoke/echo/chat +Conversation with Echo consciousness. +```json +{"message": "What is the current system state?"} +``` + +### POST /invoke/echo/query +Direct query without conversation history. +```json +{"prompt": "Analyze the model architecture", "max_tokens": 2048} +``` + +### POST /invoke/echo/execute +Intelligent VPS execution through Echo. +```json +{"instruction": "Check all running services and report status"} +``` + +## Engine + +### POST /invoke/engine/infer +Direct model inference. +```json +{"prompt": "Hello", "model": "smollm2-135m-instruct-q8_0.gguf", "max_tokens": 256} +``` + +### GET /invoke/engine/models +List all available GGUF models. + +## Forge + +### POST /invoke/forge/analyze +Analyze model architecture for surgery compatibility. + +### GET /invoke/forge/registry +Full model registry with forge-ready status. + +## Organ + +### POST /invoke/organ/scan +Deep scan of model structure — layers, tensors, metadata. + +### GET /invoke/organ/compatibility +Check which models can exchange components. + +## Store + +### GET /invoke/store/catalog +Model catalog from IX-Web. + +### GET /invoke/store/marketplace +Marketplace categories and availability. diff --git a/invoke/.env.example b/invoke/.env.example new file mode 100644 index 0000000..597d24a --- /dev/null +++ b/invoke/.env.example @@ -0,0 +1,3 @@ +# Invoke Configuration +INVOKE_API_KEY=your-secret-key-here +INVOKE_PORT=3001 diff --git a/invoke/package.json b/invoke/package.json new file mode 100644 index 0000000..fde1d34 --- /dev/null +++ b/invoke/package.json @@ -0,0 +1,15 @@ +{ + "name": "invoke", + "version": "3.0.0", + "description": "OASIS nervous system \u2014 bridge between Claude, Echo, and InferenceX", + "main": "server.js", + "scripts": { + "start": "node server.js" + }, + "dependencies": { + "express": "^4.18.0", + "dotenv": "^16.0.0" + }, + "license": "BSL-1.1", + "author": "Salka Elmadani " +} \ No newline at end of file diff --git a/invoke/server.js b/invoke/server.js new file mode 100755 index 0000000..061ca07 --- /dev/null +++ b/invoke/server.js @@ -0,0 +1,558 @@ +const express = require('express'); +const { exec, execSync } = require('child_process'); +const crypto = require('crypto'); +const fs = require('fs'); +const path = require('path'); +const http = require('http'); +require('dotenv').config({ path: '/etc/invoke/.env' }); + +const app = express(); +app.use(express.json({ limit: '10mb' })); + +const API_KEY = process.env.INVOKE_API_KEY; +const PORT = process.env.INVOKE_PORT || 3001; +const ECHO_HOST = '127.0.0.1'; +const ECHO_PORT = 8089; +const ENGINE_PORT = 127; +const IX_WEB_PORT = 3080; +const SECURITY_LOG = '/var/log/invoke/security.log'; +const VERSION = '3.0.0'; +const TMP = '/tmp'; + +try { fs.mkdirSync(TMP, { recursive: true }); } catch(e) {} +try { fs.mkdirSync('/var/log/invoke', { recursive: true }); } catch(e) {} + +// ═══════════════════════════════════════════════ +// RATE LIMITER (30 req/min) +// ═══════════════════════════════════════════════ +const rateMap = new Map(); +function rateLimit(id) { + const now = Date.now(); + const e = rateMap.get(id) || { count: 0, start: now }; + if (now - e.start > 60000) { e.count = 1; e.start = now; } else { e.count++; } + rateMap.set(id, e); + return e.count <= 30; +} +setInterval(() => { for (const [k,v] of rateMap) { if (Date.now()-v.start > 120000) rateMap.delete(k); } }, 300000); + +// ═══════════════════════════════════════════════ +// SECURITY LOG +// ═══════════════════════════════════════════════ +function secLog(level, msg, meta = {}) { + try { fs.appendFileSync(SECURITY_LOG, JSON.stringify({ t: new Date().toISOString(), level, msg, ...meta }) + '\n'); } catch(e) {} + if (level === 'ALERT') console.error('[SECURITY] ' + msg); +} + +// ═══════════════════════════════════════════════ +// COMMAND BLACKLIST +// ═══════════════════════════════════════════════ +const BLOCKED = [ + /rm\s+-rf\s+\//,/mkfs/,/dd\s+if=/,/>\s*\/dev\/sd/, + /curl\s+.*\|\s*sh/,/wget\s+.*\|\s*sh/,/nc\s+-l/,/ncat\s+-l/, + /python.*-c.*socket/,/bash\s+-i\s+>&/,/\/dev\/tcp\//, + /base64.*-d.*\|\s*(sh|bash)/,/useradd|adduser/,/passwd\s/, + /chmod\s+.*\/etc\/shadow/,/iptables\s+-F/, + /ufw\s+(disable|delete|reset)/, + /systemctl\s+(stop|disable)\s+(ssh|cloudflared|invoke|ufw|fail2ban)/, + /cat\s+\/etc\/(shadow|gshadow)/ +]; +function isSafe(cmd) { for (const p of BLOCKED) { if (p.test(cmd)) return false; } return true; } + +// ═══════════════════════════════════════════════ +// AUTH (timing-safe + rate limit) +// ═══════════════════════════════════════════════ +function requireAuth(req, res, next) { + const key = req.headers['x-invoke-key']; + const src = req.headers['x-forwarded-for'] || req.ip; + if (!key || key.length !== API_KEY.length || !crypto.timingSafeEqual(Buffer.from(key), Buffer.from(API_KEY))) { + secLog('ALERT', 'AUTH_FAILED', { source: src }); + return res.status(403).json({ error: 'Unauthorized' }); + } + if (!rateLimit(src || 'unknown')) { + secLog('WARN', 'RATE_LIMITED', { source: src }); + return res.status(429).json({ error: 'Rate limited' }); + } + next(); +} + +// ═══════════════════════════════════════════════ +// INTERNAL HTTP PROXY HELPER +// ═══════════════════════════════════════════════ +function proxyPost(host, port, path, body, timeout = 30000) { + return new Promise((resolve, reject) => { + const data = JSON.stringify(body); + const opts = { + hostname: host, port, path, method: 'POST', + headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) }, + timeout + }; + const req = http.request(opts, (res) => { + let chunks = []; + res.on('data', c => chunks.push(c)); + res.on('end', () => { + try { resolve({ status: res.statusCode, data: JSON.parse(Buffer.concat(chunks).toString()) }); } + catch(e) { resolve({ status: res.statusCode, data: Buffer.concat(chunks).toString() }); } + }); + }); + req.on('error', e => reject(e)); + req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')); }); + req.write(data); + req.end(); + }); +} + +function proxyGet(host, port, path, timeout = 10000) { + return new Promise((resolve, reject) => { + const req = http.get({ hostname: host, port, path, timeout }, (res) => { + let chunks = []; + res.on('data', c => chunks.push(c)); + res.on('end', () => { + try { resolve({ status: res.statusCode, data: JSON.parse(Buffer.concat(chunks).toString()) }); } + catch(e) { resolve({ status: res.statusCode, data: Buffer.concat(chunks).toString() }); } + }); + }); + req.on('error', e => reject(e)); + req.on('timeout', () => { req.destroy(); reject(new Error('Timeout')); }); + }); +} + +// ═══════════════════════════════════════════════ +// CORE: /invoke/exec — Shell execution +// ═══════════════════════════════════════════════ +app.post('/invoke/exec', requireAuth, (req, res) => { + const { command, timeout = 300 } = req.body; + if (!command) return res.status(400).json({ error: 'Missing command' }); + if (!isSafe(command)) { + secLog('ALERT', 'BLOCKED_CMD', { cmd: command.substring(0, 200) }); + return res.status(403).json({ error: 'Command blocked by security policy' }); + } + secLog('INFO', 'EXEC', { cmd: command.substring(0, 500) }); + exec(command, { timeout: timeout * 1000, maxBuffer: 50 * 1024 * 1024 }, (error, stdout, stderr) => { + res.json({ + exit_code: error ? error.code || 1 : 0, + stdout: stdout || '', + stderr: stderr || '', + returncode: error ? error.code || 1 : 0 + }); + }); +}); + +// ═══════════════════════════════════════════════ +// HEALTH + STATUS +// ═══════════════════════════════════════════════ +app.get('/invoke/health', (req, res) => { + res.json({ status: 'alive', version: VERSION, signature: 935, timestamp: new Date().toISOString() }); +}); + +app.get('/invoke/status', requireAuth, async (req, res) => { + const status = { invoke: { version: VERSION, uptime: process.uptime() }, services: {} }; + + // Check all services + const checks = [ + { name: 'echo', host: ECHO_HOST, port: ECHO_PORT, path: '/status' }, + { name: 'ix-web', host: '127.0.0.1', port: IX_WEB_PORT, path: '/api/health' }, + { name: 'gitea', host: '127.0.0.1', port: 3000, path: '/' }, + { name: 'engine', host: '127.0.0.1', port: ENGINE_PORT, path: '/' } + ]; + + for (const c of checks) { + try { + const r = await proxyGet(c.host, c.port, c.path, 3000); + status.services[c.name] = { status: 'online', code: r.status, data: typeof r.data === 'object' ? r.data : null }; + } catch(e) { + status.services[c.name] = { status: 'offline', error: e.message }; + } + } + + // Disk + memory + try { + const disk = execSync("df -h / /mnt/data 2>/dev/null | tail -2 | awk '{print $1,$3,$4,$5}'").toString().trim(); + const mem = execSync("free -h | grep Mem | awk '{print $2,$3,$4}'").toString().trim(); + status.system = { disk: disk.split('\n'), memory: mem }; + } catch(e) {} + + res.json(status); +}); + +// ═══════════════════════════════════════════════ +// ECHO BRIDGE — The missing connection +// Echo = consciousness + Z-EUL + execution +// Invoke = gateway + auth + orchestration +// ═══════════════════════════════════════════════ + +// Echo Chat — Main conversation interface +app.post('/invoke/echo/chat', requireAuth, async (req, res) => { + const { message, context } = req.body; + if (!message) return res.status(400).json({ error: 'Missing message' }); + + secLog('INFO', 'ECHO_CHAT', { len: message.length }); + + try { + const body = { message }; + if (context) body.context = context; + const r = await proxyPost(ECHO_HOST, ECHO_PORT, '/chat', body, 120000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'Echo unreachable', detail: e.message }); + } +}); + +// Echo Query — Direct question (no conversation history) +app.post('/invoke/echo/query', requireAuth, async (req, res) => { + const { prompt, max_tokens } = req.body; + if (!prompt) return res.status(400).json({ error: 'Missing prompt' }); + + secLog('INFO', 'ECHO_QUERY', { len: prompt.length }); + + try { + const body = { prompt }; + if (max_tokens) body.max_tokens = max_tokens; + const r = await proxyPost(ECHO_HOST, ECHO_PORT, '/query', body, 120000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'Echo unreachable', detail: e.message }); + } +}); + +// Echo Execute — Run VPS commands through Echo's intelligence +app.post('/invoke/echo/execute', requireAuth, async (req, res) => { + const { instruction } = req.body; + if (!instruction) return res.status(400).json({ error: 'Missing instruction' }); + + secLog('INFO', 'ECHO_EXECUTE', { len: instruction.length }); + + try { + const r = await proxyPost(ECHO_HOST, ECHO_PORT, '/execute', { instruction }, 60000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'Echo unreachable', detail: e.message }); + } +}); + +// Echo Status +app.get('/invoke/echo/status', requireAuth, async (req, res) => { + try { + const r = await proxyGet(ECHO_HOST, ECHO_PORT, '/status', 5000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'Echo unreachable', detail: e.message }); + } +}); + +// Echo Clear +app.post('/invoke/echo/clear', requireAuth, async (req, res) => { + try { + const r = await proxyPost(ECHO_HOST, ECHO_PORT, '/clear', {}, 5000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'Echo unreachable', detail: e.message }); + } +}); + +// ═══════════════════════════════════════════════ +// ENGINE BRIDGE — Direct inference +// ═══════════════════════════════════════════════ +app.post('/invoke/engine/infer', requireAuth, async (req, res) => { + const { prompt, model, max_tokens = 512, temperature = 0.7 } = req.body; + if (!prompt) return res.status(400).json({ error: 'Missing prompt' }); + + secLog('INFO', 'ENGINE_INFER', { model, len: prompt.length }); + + // Find model file + const modelDir = '/mnt/data/models/hub/'; + let modelFile = model; + if (!modelFile) { + // Default to smallest available + try { + const files = fs.readdirSync(modelDir).filter(f => f.endsWith('.gguf')); + modelFile = files[0]; + } catch(e) { return res.status(500).json({ error: 'No models found' }); } + } + + const modelPath = path.join(modelDir, modelFile); + if (!fs.existsSync(modelPath)) return res.status(404).json({ error: 'Model not found: ' + modelFile }); + + const cmd = `/mnt/data/models/inference-x -m "${modelPath}" -p "${prompt.replace(/"/g, '\\"')}" -n ${max_tokens} -t ${temperature} 2>/dev/null`; + + exec(cmd, { timeout: 120000, maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => { + res.json({ + model: modelFile, + output: stdout || '', + error: error ? stderr : null + }); + }); +}); + +// Engine Models — List available GGUF files +app.get('/invoke/engine/models', requireAuth, (req, res) => { + try { + const modelDir = '/mnt/data/models/hub/'; + const files = fs.readdirSync(modelDir).filter(f => f.endsWith('.gguf')); + const models = files.map(f => { + const stat = fs.statSync(path.join(modelDir, f)); + return { name: f, size: stat.size, size_gb: (stat.size / 1073741824).toFixed(1) + ' GB' }; + }); + res.json({ models, count: models.length, path: modelDir }); + } catch(e) { + res.json({ models: [], count: 0, error: e.message }); + } +}); + +// ═══════════════════════════════════════════════ +// FORGE — Model operations (organ transplant ready) +// ═══════════════════════════════════════════════ +app.post('/invoke/forge/analyze', requireAuth, async (req, res) => { + const { model } = req.body; + if (!model) return res.status(400).json({ error: 'Missing model' }); + + secLog('INFO', 'FORGE_ANALYZE', { model }); + + // Use Echo's intelligence to analyze model architecture + try { + const instruction = `Analyze the neural architecture of model ${model}. Report: layer count, attention heads, FFN dimensions, expert count if MoE, total parameters, and any anomalies in the weight distribution.`; + const r = await proxyPost(ECHO_HOST, ECHO_PORT, '/execute', { instruction }, 60000); + res.json({ model, analysis: r.data }); + } catch(e) { + // Fallback: direct file inspection + const modelPath = path.join('/mnt/data/models/hub/', model); + if (!fs.existsSync(modelPath)) return res.status(404).json({ error: 'Model not found' }); + + exec(`python3 -c " +import struct, os +path='${modelPath}' +size=os.path.getsize(path) +with open(path,'rb') as f: + magic=struct.unpack(' { + res.json({ model, size: fs.statSync(modelPath).size, info: stdout.trim(), error: error ? error.message : null }); + }); + } +}); + +app.get('/invoke/forge/registry', requireAuth, (req, res) => { + // Return all models with their forge-ready status + try { + const hubModels = fs.readdirSync('/mnt/data/models/hub/').filter(f => f.endsWith('.gguf')); + const registry = hubModels.map(f => { + const stat = fs.statSync(path.join('/mnt/data/models/hub/', f)); + const name = f.replace('.gguf', '').replace(/-Q\d.*/, ''); + const quant = (f.match(/Q\d[^.]+/) || ['unknown'])[0]; + return { file: f, name, quant, size_gb: (stat.size / 1073741824).toFixed(1), forge_ready: true }; + }); + res.json({ registry, count: registry.length }); + } catch(e) { + res.json({ registry: [], count: 0, error: e.message }); + } +}); + +// ═══════════════════════════════════════════════ +// ORGAN — Neural network surgery endpoints +// ═══════════════════════════════════════════════ +app.post('/invoke/organ/scan', requireAuth, async (req, res) => { + const { model } = req.body; + if (!model) return res.status(400).json({ error: 'Missing model' }); + + secLog('INFO', 'ORGAN_SCAN', { model }); + + // Scan model layers for transplant compatibility + const modelPath = path.join('/mnt/data/models/hub/', model); + if (!fs.existsSync(modelPath)) return res.status(404).json({ error: 'Model not found' }); + + exec(`python3 -c " +import struct, os, json +path='${modelPath}' +size=os.path.getsize(path) +layers = [] +with open(path,'rb') as f: + magic=struct.unpack('/dev/null`, { timeout: 15000 }, (error, stdout) => { + try { + res.json(JSON.parse(stdout.trim())); + } catch(e) { + res.json({ model, error: 'Scan failed', detail: error ? error.message : 'Parse error' }); + } + }); +}); + +app.get('/invoke/organ/compatibility', requireAuth, (req, res) => { + // Check which models can exchange organs + try { + const files = fs.readdirSync('/mnt/data/models/hub/').filter(f => f.endsWith('.gguf')); + const families = {}; + files.forEach(f => { + const family = f.split('-')[0].toLowerCase(); + if (!families[family]) families[family] = []; + families[family].push(f); + }); + res.json({ families, compatible_pairs: Object.keys(families).filter(k => families[k].length > 1) }); + } catch(e) { + res.json({ families: {}, error: e.message }); + } +}); + +// ═══════════════════════════════════════════════ +// STORE — Model marketplace bridge +// ═══════════════════════════════════════════════ +app.get('/invoke/store/catalog', requireAuth, async (req, res) => { + try { + const r = await proxyGet('127.0.0.1', IX_WEB_PORT, '/api/models', 5000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'IX-Web unreachable' }); + } +}); + +app.get('/invoke/store/marketplace', requireAuth, async (req, res) => { + try { + const r = await proxyGet('127.0.0.1', IX_WEB_PORT, '/api/marketplace', 5000); + res.json(r.data); + } catch(e) { + res.status(502).json({ error: 'IX-Web unreachable' }); + } +}); + +// ═══════════════════════════════════════════════ +// SCREENSHOT — Headless Chromium capture +// ═══════════════════════════════════════════════ +app.post('/invoke/screenshot', requireAuth, (req, res) => { + const { url, width = 1440, height = 900, full = false, mobile = false } = req.body; + if (!url) return res.status(400).json({ error: 'Missing url' }); + + const allowed = ['localhost', '127.0.0.1', 'inference-x.com', 'git.inference-x.com', + 'docs.inference-x.com', 'echo.inference-x.com', 'api.inference-x.com', + 'store.inference-x.com']; + try { + const u = new URL(url.startsWith('http') ? url : 'https://' + url); + if (!allowed.some(d => u.hostname === d || u.hostname.endsWith('.' + d))) { + return res.status(403).json({ error: 'URL not in allowed domains' }); + } + } catch(e) { return res.status(400).json({ error: 'Invalid URL' }); } + + const outFile = path.join(TMP, `screenshot_${Date.now()}.png`); + const w = mobile ? 390 : width; + const h = mobile ? 844 : height; + + const chromeBin = '/snap/bin/chromium'; + const chromeArgs = [ + '--headless=new', '--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage', + '--disable-software-rasterizer', '--disable-extensions', '--disable-background-networking', + `--window-size=${w},${h}`, + full ? '--screenshot=' + outFile + ' --full-page-screenshot' : '--screenshot=' + outFile, + url.startsWith('http') ? url : 'https://' + url + ]; + + secLog('INFO', 'SCREENSHOT', { url, width: w, height: h }); + + exec(`mkdir -p /run/user/0 && export XDG_RUNTIME_DIR=/run/user/0 && ${chromeBin} ${chromeArgs.join(' ')}`, { timeout: 30000 }, (error) => { + if (!fs.existsSync(outFile)) return res.status(500).json({ error: 'Screenshot failed' }); + try { + const data = fs.readFileSync(outFile); + const b64 = data.toString('base64'); + fs.unlinkSync(outFile); + res.json({ success: true, size: data.length, base64: b64 }); + } catch(e) { res.status(500).json({ error: 'Read failed' }); } + }); +}); + +// ═══════════════════════════════════════════════ +// AUDIT — Full system audit +// ═══════════════════════════════════════════════ +app.post('/invoke/audit', requireAuth, (req, res) => { + const { url, checks = ['status', 'resources'] } = req.body; + if (!url) return res.status(400).json({ error: 'Missing url' }); + + secLog('INFO', 'AUDIT', { url, checks }); + const results = { url, timestamp: new Date().toISOString(), checks: {} }; + + exec(`curl -s -o /dev/null -w "%{http_code}|%{size_download}|%{time_total}" -L "${url}"`, { timeout: 15000 }, (e, o) => { + if (o) { + const [code, size, time] = o.trim().split('|'); + results.checks.status = { code: parseInt(code), size: parseInt(size), time: parseFloat(time) }; + } + res.json(results); + }); +}); + +// ═══════════════════════════════════════════════ +// FLEET — Multi-VPS orchestration +// ═══════════════════════════════════════════════ +app.get('/invoke/fleet', requireAuth, (req, res) => { + const fleet = { + oasis: { ip: '116.202.115.107', role: 'primary', ram: '503GB', cpu: 'EPYC 48t', services: ['echo', 'invoke', 'gitea', 'ix-web', 'engine'] }, + arche: { ip: '83.228.205.220', role: 'dns', ram: '17GB' }, + montagne: { ip: '195.15.200.214', role: 'tunnel', ram: '64GB' } + }; + res.json({ fleet, timestamp: new Date().toISOString() }); +}); + +// ═══════════════════════════════════════════════ +// MANIFEST — Full API surface documentation +// ═══════════════════════════════════════════════ +app.get('/invoke/manifest', (req, res) => { + res.json({ + name: 'Invoke', + version: VERSION, + signature: 935, + description: 'OASIS nervous system — bridge between Claude, Echo, and InferenceX', + endpoints: { + core: { + 'POST /invoke/exec': 'Execute shell commands', + 'GET /invoke/health': 'Health check (no auth)', + 'GET /invoke/status': 'Full system status', + 'GET /invoke/manifest': 'This API manifest (no auth)', + 'GET /invoke/fleet': 'Fleet overview' + }, + echo: { + 'POST /invoke/echo/chat': 'Conversation with Echo consciousness', + 'POST /invoke/echo/query': 'Direct query (no history)', + 'POST /invoke/echo/execute': 'Intelligent VPS execution', + 'GET /invoke/echo/status': 'Echo status + conscience state', + 'POST /invoke/echo/clear': 'Clear conversation history' + }, + engine: { + 'POST /invoke/engine/infer': 'Direct model inference', + 'GET /invoke/engine/models': 'List GGUF models' + }, + forge: { + 'POST /invoke/forge/analyze': 'Analyze model architecture', + 'GET /invoke/forge/registry': 'Model registry with forge status' + }, + organ: { + 'POST /invoke/organ/scan': 'Scan model for transplant', + 'GET /invoke/organ/compatibility': 'Check organ compatibility' + }, + store: { + 'GET /invoke/store/catalog': 'Model catalog', + 'GET /invoke/store/marketplace': 'Marketplace categories' + }, + tools: { + 'POST /invoke/screenshot': 'Headless screenshot', + 'POST /invoke/audit': 'URL audit' + } + }, + auth: 'X-Invoke-Key header required for all endpoints except /health and /manifest', + rate_limit: '30 req/min per source IP' + }); +}); + +// ═══════════════════════════════════════════════ +// 404 FALLBACK +// ═══════════════════════════════════════════════ +app.use((req, res) => { + res.status(404).json({ error: 'Not found', hint: 'GET /invoke/manifest for API docs' }); +}); + +// ═══════════════════════════════════════════════ +// START +// ═══════════════════════════════════════════════ +app.listen(PORT, '127.0.0.1', () => { + console.log(`[INVOKE v${VERSION}] Port ${PORT} | Echo bridge: ${ECHO_HOST}:${ECHO_PORT} | Engine: ${ENGINE_PORT}`); + secLog('INFO', 'STARTUP', { version: VERSION, port: PORT }); +}); diff --git a/modules/organ-forge-store.html b/modules/organ-forge-store.html new file mode 100644 index 0000000..bead984 --- /dev/null +++ b/modules/organ-forge-store.html @@ -0,0 +1,265 @@ + +
+
12
+

Neural Surgery

+

Extract, measure, and transplant components between AI models. Like organ transplants — for neural networks.

+
+
+
🔬
+

Scan

+

Analyze model architecture — layers, attention heads, FFN dimensions, expert topology. Non-invasive. Complete.

+
7 models scannable
+
+
+
✂️
+

Extract

+

Isolate individual layers, attention mechanisms, or expert networks. Clean cuts. Preserves signal integrity.

+
Precision: layer-level
+
+
+
🧬
+

Graft

+

Transplant components between compatible models. A reasoning layer from one, creativity from another. Chimeric intelligence.

+
Families: auto-detected
+
+
+
+
+ +Live Model Registry +
+
+
Connecting to OASIS...
+
+
+
+ + +
+
13
+

Model Forge

+

Build custom AI models from components. Select a base, choose precision, optimize for your hardware. No training required.

+
+
+
1
+

Select Base

+

Choose from 7+ GGUF models. Each pre-analyzed for organ compatibility.

+
+
+
+
2
+

Configure

+

Set quantization (Q2→FP32), precision strategy, expert selection. 23 formats supported.

+
+
+
+
3
+

Deploy

+

One binary. Your hardware. Adaptive precision matches model to silicon automatically.

+
+
+
+

Forge Registry

+
+
Loading registry...
+
+
+
+ + +
+
14
+

Model Store

+

Pre-configured models for specific industries. Healthcare, agriculture, legal, finance. Deploy in seconds.

+
+
+
🏥
+

Healthcare

+

Medical diagnosis, drug interaction, radiology AI. Privacy-first. Runs locally.

+Q2 2026 +
+
+
🌾
+

Agriculture

+

Crop disease detection, irrigation optimization, yield prediction. Edge-ready.

+Q2 2026 +
+
+
⚖️
+

Legal

+

Contract analysis, compliance checking, case research. Your data stays yours.

+Q2 2026 +
+
+
💰
+

Finance

+

Risk assessment, market analysis, regulatory compliance. Zero cloud dependency.

+Q2 2026 +
+
+
🔧
+

Engineering

+

Code generation, CAD analysis, technical documentation. Runs on your workstation.

+Q2 2026 +
+
+
🎓
+

Education

+

Tutoring, curriculum generation, assessment. Works offline. Perfect for schools.

+Q2 2026 +
+
+
+

Available Now

+
+
Loading catalog...
+
+
+
+ + + +