Spaces:
Running
Running
| /** | |
| * CAPT Memory Palace - Real API Integration | |
| * | |
| * Connect to a running CAPT symbiote for real-time cognitive data. | |
| * See DEPLOY.md for server setup instructions. | |
| */ | |
| const CAPT_API = { | |
| endpoint: null, | |
| token: null, | |
| isConnected: false, | |
| lastState: null, | |
| pollInterval: null, | |
| /** | |
| * Configure API connection | |
| */ | |
| configure(options = {}) { | |
| this.endpoint = options.endpoint || null; | |
| this.token = options.token || null; | |
| if (this.endpoint) { | |
| console.log('[CAPT API] Configured:', this.endpoint); | |
| } | |
| }, | |
| /** | |
| * Test connection to CAPT server | |
| */ | |
| async test() { | |
| if (!this.endpoint) { | |
| console.warn('[CAPT API] No endpoint configured'); | |
| return false; | |
| } | |
| try { | |
| const response = await fetch(`${this.endpoint}/health`, { | |
| headers: this.getHeaders() | |
| }); | |
| this.isConnected = response.ok; | |
| console.log('[CAPT API] Connection:', this.isConnected ? 'OK' : 'Failed'); | |
| return this.isConnected; | |
| } catch (e) { | |
| console.error('[CAPT API] Connection error:', e.message); | |
| this.isConnected = false; | |
| return false; | |
| } | |
| }, | |
| /** | |
| * Get current CAPT state | |
| */ | |
| async getState() { | |
| if (!this.endpoint) return null; | |
| try { | |
| const response = await fetch(`${this.endpoint}/api/state`, { | |
| headers: this.getHeaders() | |
| }); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| const data = await response.json(); | |
| this.lastState = data; | |
| return data; | |
| } catch (e) { | |
| console.warn('[CAPT API] Get state failed:', e.message); | |
| return null; | |
| } | |
| }, | |
| /** | |
| * Submit a query to CAPT | |
| */ | |
| async query(text) { | |
| if (!this.endpoint) { | |
| console.warn('[CAPT API] No endpoint configured'); | |
| return null; | |
| } | |
| try { | |
| const response = await fetch(`${this.endpoint}/api/cogitate`, { | |
| method: 'POST', | |
| headers: this.getHeaders(), | |
| body: JSON.stringify({ query: text }) | |
| }); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| return await response.json(); | |
| } catch (e) { | |
| console.error('[CAPT API] Query failed:', e.message); | |
| return null; | |
| } | |
| }, | |
| /** | |
| * Get CAPT eval reports | |
| */ | |
| async getEvals() { | |
| if (!this.endpoint) return null; | |
| try { | |
| const response = await fetch(`${this.endpoint}/api/evals`, { | |
| headers: this.getHeaders() | |
| }); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| return await response.json(); | |
| } catch (e) { | |
| console.warn('[CAPT API] Get evals failed:', e.message); | |
| return null; | |
| } | |
| }, | |
| /** | |
| * Get knowledge status | |
| */ | |
| async getKnowledge() { | |
| if (!this.endpoint) return null; | |
| try { | |
| const response = await fetch(`${this.endpoint}/api/knowledge`, { | |
| headers: this.getHeaders() | |
| }); | |
| if (!response.ok) throw new Error(`HTTP ${response.status}`); | |
| return await response.json(); | |
| } catch (e) { | |
| console.warn('[CAPT API] Get knowledge failed:', e.message); | |
| return null; | |
| } | |
| }, | |
| /** | |
| * Start polling for state updates | |
| */ | |
| startPolling(callback, interval = 2000) { | |
| if (this.pollInterval) { | |
| this.stopPolling(); | |
| } | |
| const poll = async () => { | |
| const state = await this.getState(); | |
| if (state && callback) { | |
| callback(state); | |
| } | |
| }; | |
| poll(); | |
| this.pollInterval = setInterval(poll, interval); | |
| }, | |
| /** | |
| * Stop polling | |
| */ | |
| stopPolling() { | |
| if (this.pollInterval) { | |
| clearInterval(this.pollInterval); | |
| this.pollInterval = null; | |
| } | |
| }, | |
| /** | |
| * Get authorization headers | |
| */ | |
| getHeaders() { | |
| const headers = { | |
| 'Content-Type': 'application/json' | |
| }; | |
| if (this.token) { | |
| headers['Authorization'] = `Bearer ${this.token}`; | |
| } | |
| return headers; | |
| }, | |
| /** | |
| * Parse CAPT state into palace format | |
| */ | |
| parseState(captState) { | |
| if (!captState) return null; | |
| // Extract rooms from modules | |
| const modules = captState.modules || []; | |
| const rooms = modules.map(m => ({ | |
| id: m.id || m.name, | |
| label: m.label || m.id || m.name, | |
| type: this.getModuleType(m.id || m.name), | |
| color: this.getModuleColor(m.id || m.name), | |
| capacity: Math.round((m.activation || 0.5) * 100), | |
| position: { | |
| x: m.position?.x || Math.random() * 10 - 5, | |
| y: (m.activation || 0.5) * 3, | |
| z: m.position?.z || Math.random() * 10 - 5 | |
| } | |
| })); | |
| return { | |
| sweep: captState.sweep, | |
| modules: rooms, | |
| input: captState.input, | |
| output: captState.output, | |
| timestamp: Date.now() | |
| }; | |
| }, | |
| /** | |
| * Get module type from ID | |
| */ | |
| getModuleType(id) { | |
| const types = { | |
| PULSE: 'input', | |
| NEDA: 'processing', | |
| HMC: 'memory', | |
| CIG: 'processing', | |
| HDR: 'processing', | |
| QIPC: 'quorum', | |
| ECHO: 'memory', | |
| META: 'processing', | |
| IMMU: 'validation', | |
| NDS: 'output' | |
| }; | |
| return types[id] || 'processing'; | |
| }, | |
| /** | |
| * Get module color from ID | |
| */ | |
| getModuleColor(id) { | |
| const colors = { | |
| PULSE: '#8b5cf6', | |
| NEDA: '#a855f7', | |
| HMC: '#c084fc', | |
| CIG: '#d946ef', | |
| HDR: '#e879f9', | |
| QIPC: '#f472b6', | |
| ECHO: '#fb7185', | |
| META: '#f43f5e', | |
| IMMU: '#10b981', | |
| NDS: '#06b6d4' | |
| }; | |
| return colors[id] || '#8b5cf6'; | |
| } | |
| }; | |
| // Export | |
| window.CAPT_API = CAPT_API; | |