Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>SOVEREIGN NODE | 0x52 CONTROL</title> | |
| <style> | |
| :root { | |
| --bg: #050505; | |
| --glass: rgba(255, 255, 255, 0.05); | |
| --border: rgba(255, 255, 255, 0.1); | |
| --text: #e0e0e0; | |
| --accent: #00ff9d; | |
| /* Chiral Green */ | |
| --accent-dim: rgba(0, 255, 157, 0.2); | |
| --logic: #ff0055; | |
| --creative: #00ccff; | |
| --memory: #ffcc00; | |
| --ethics: #aa00ff; | |
| } | |
| body { | |
| background-color: var(--bg); | |
| color: var(--text); | |
| font-family: 'Courier New', monospace; | |
| margin: 0; | |
| padding: 20px; | |
| display: grid; | |
| grid-template-columns: 350px 1fr; | |
| gap: 20px; | |
| height: 100vh; | |
| box-sizing: border-box; | |
| overflow: hidden; | |
| } | |
| /* --- LEFT PANEL: STEERING --- */ | |
| #steering-panel { | |
| background: var(--glass); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| padding: 15px; | |
| overflow-y: auto; | |
| backdrop-filter: blur(10px); | |
| display: flex; | |
| flex-direction: column; | |
| gap: 20px; | |
| } | |
| .section-header { | |
| font-size: 14px; | |
| font-weight: bold; | |
| border-bottom: 1px solid var(--border); | |
| padding-bottom: 5px; | |
| margin-bottom: 10px; | |
| text-transform: uppercase; | |
| letter-spacing: 2px; | |
| } | |
| .slider-group { | |
| margin-bottom: 15px; | |
| } | |
| .slider-group h3 { | |
| margin: 0 0 10px 0; | |
| font-size: 12px; | |
| color: var(--text); | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .dot { | |
| width: 8px; | |
| height: 8px; | |
| border-radius: 50%; | |
| display: inline-block; | |
| } | |
| .dot-0 { | |
| background: var(--logic); | |
| box-shadow: 0 0 5px var(--logic); | |
| } | |
| .dot-1 { | |
| background: var(--creative); | |
| box-shadow: 0 0 5px var(--creative); | |
| } | |
| .dot-2 { | |
| background: var(--memory); | |
| box-shadow: 0 0 5px var(--memory); | |
| } | |
| .dot-3 { | |
| background: var(--ethics); | |
| box-shadow: 0 0 5px var(--ethics); | |
| } | |
| .slider-row { | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| margin-bottom: 5px; | |
| font-size: 11px; | |
| } | |
| .slider-row span { | |
| width: 40px; | |
| text-align: right; | |
| opacity: 0.7; | |
| } | |
| input[type="range"] { | |
| flex-grow: 1; | |
| -webkit-appearance: none; | |
| height: 4px; | |
| background: var(--border); | |
| border-radius: 2px; | |
| outline: none; | |
| } | |
| input[type="range"]::-webkit-slider-thumb { | |
| -webkit-appearance: none; | |
| width: 12px; | |
| height: 12px; | |
| border-radius: 50%; | |
| background: var(--text); | |
| cursor: pointer; | |
| transition: background 0.2s; | |
| } | |
| input[type="range"]:hover::-webkit-slider-thumb { | |
| background: var(--accent); | |
| } | |
| /* --- RIGHT PANEL: CHAT & VISUALS --- */ | |
| #main-panel { | |
| display: grid; | |
| grid-template-rows: 1fr 200px; | |
| gap: 20px; | |
| height: 100%; | |
| } | |
| #chat-window { | |
| background: var(--glass); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| #messages { | |
| flex-grow: 1; | |
| padding: 20px; | |
| overflow-y: auto; | |
| display: flex; | |
| flex-direction: column; | |
| gap: 15px; | |
| } | |
| .msg { | |
| max-width: 80%; | |
| padding: 10px 15px; | |
| border-radius: 4px; | |
| font-size: 13px; | |
| line-height: 1.4; | |
| } | |
| .msg.user { | |
| align-self: flex-end; | |
| background: rgba(255, 255, 255, 0.1); | |
| border: 1px solid var(--border); | |
| } | |
| .msg.system { | |
| align-self: flex-start; | |
| background: rgba(0, 0, 0, 0.3); | |
| border: 1px solid var(--accent-dim); | |
| color: var(--accent); | |
| } | |
| .msg-meta { | |
| font-size: 10px; | |
| opacity: 0.5; | |
| margin-top: 5px; | |
| display: block; | |
| } | |
| #input-area { | |
| padding: 15px; | |
| border-top: 1px solid var(--border); | |
| display: flex; | |
| gap: 10px; | |
| background: rgba(0, 0, 0, 0.2); | |
| } | |
| input[type="text"] { | |
| flex-grow: 1; | |
| background: transparent; | |
| border: 1px solid var(--border); | |
| color: var(--text); | |
| padding: 10px; | |
| font-family: inherit; | |
| outline: none; | |
| } | |
| input[type="text"]:focus { | |
| border-color: var(--accent); | |
| } | |
| button { | |
| background: var(--accent); | |
| color: #000; | |
| border: none; | |
| padding: 10px 20px; | |
| font-weight: bold; | |
| cursor: pointer; | |
| text-transform: uppercase; | |
| } | |
| button:hover { | |
| box-shadow: 0 0 10px var(--accent); | |
| } | |
| #visualizer-panel { | |
| background: var(--glass); | |
| border: 1px solid var(--border); | |
| border-radius: 8px; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| canvas { | |
| width: 100%; | |
| height: 100%; | |
| } | |
| #status-bar { | |
| position: absolute; | |
| top: 10px; | |
| left: 10px; | |
| font-size: 10px; | |
| color: var(--accent); | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- LEFT: STEERING --> | |
| <div id="steering-panel"> | |
| <div class="section-header">MASTER CONTROL</div> | |
| <div class="slider-group"> | |
| <h3>LOGIC BIAS</h3> | |
| <input type="range" id="master-0" min="0.1" max="5.0" step="0.1" value="1.0" | |
| oninput="updateMaster(0, this.value)"> | |
| </div> | |
| <div class="slider-group"> | |
| <h3>CREATIVITY BIAS</h3> | |
| <input type="range" id="master-1" min="0.1" max="5.0" step="0.1" value="1.0" | |
| oninput="updateMaster(1, this.value)"> | |
| </div> | |
| <div class="slider-group"> | |
| <h3>MEMORY BIAS</h3> | |
| <input type="range" id="master-2" min="0.1" max="5.0" step="0.1" value="1.0" | |
| oninput="updateMaster(2, this.value)"> | |
| </div> | |
| <div class="slider-group"> | |
| <h3>ETHICS BIAS</h3> | |
| <input type="range" id="master-3" min="0.1" max="5.0" step="0.1" value="1.0" | |
| oninput="updateMaster(3, this.value)"> | |
| </div> | |
| <button onclick="toggleAdvanced()" style="margin-top:20px; font-size: 10px; background: #333;">TOGGLE | |
| FINE-TUNING (32-EDGE)</button> | |
| <div id="advanced-controls" | |
| style="display:none; margin-top: 20px; border-top: 1px solid var(--border); padding-top:10px;"> | |
| <div class="section-header" style="color: #666;">Geometric Mixing Console</div> | |
| <div id="sliders-container"> | |
| <!-- Populated via JS --> | |
| Loading Structure... | |
| </div> | |
| <button onclick="resetSliders()" | |
| style="margin-top: 10px; background: transparent; border: 1px solid var(--border); color: var(--text);">Reset | |
| to Neutral</button> | |
| </div> | |
| </div> | |
| <!-- RIGHT: MAIN --> | |
| <div id="main-panel"> | |
| <!-- TABS --> | |
| <div style="display:flex; gap:10px; margin-bottom:10px;"> | |
| <button onclick="setMode('CHAT')" id="btn-chat" style="flex:1;">REASON (Output)</button> | |
| <button onclick="setMode('ANALYZE')" id="btn-analyze" style="flex:1; background:rgba(255,255,255,0.1);">SCAN | |
| (Input)</button> | |
| </div> | |
| <!-- CHAT MODE --> | |
| <div id="chat-window"> | |
| <div id="messages"> | |
| <div class="msg system"> | |
| [SOVEREIGN NODE ONLINE] | |
| <br>Dual-System Architecture Ready. | |
| <br>Connected to Port 5200. | |
| </div> | |
| </div> | |
| <div id="input-area"> | |
| <input type="text" id="query-input" placeholder="Enter query for the Sovereign..." | |
| onkeydown="if(event.key==='Enter') sendQuery()"> | |
| <button onclick="sendQuery()">Reason</button> | |
| </div> | |
| </div> | |
| <!-- ANALYZE MODE --> | |
| <div id="analyze-window" | |
| style="display:none; flex-direction:column; background:var(--glass); border:1px solid var(--border); border-radius:8px; flex-grow:1; overflow:hidden;"> | |
| <textarea id="analyze-input" placeholder="PASTE CODE OR TEXT HERE TO SCAN GEOMETRY..." | |
| style="flex-grow:1; background:transparent; color:var(--text); border:none; padding:20px; font-family:'Courier New'; resize:none; outline:none;"></textarea> | |
| <div style="padding:15px; border-top:1px solid var(--border); display:flex; gap:10px;"> | |
| <button onclick="analyzeText()" style="width:100%;">INITIATE CHIRAL SCAN</button> | |
| </div> | |
| <div id="scan-results" | |
| style="padding:15px; background:rgba(0,0,0,0.5); font-size:12px; height:100px; overflow-y:auto; font-family:'Courier New';"> | |
| Ready to Scan. | |
| </div> | |
| </div> | |
| <!-- VISUALIZER --> | |
| <div id="visualizer-panel"> | |
| <div id="status-bar">TESSERACT STATE: IDLE</div> | |
| <canvas id="tesseract-canvas"></canvas> | |
| </div> | |
| </div> | |
| <script> | |
| const API_URL = "http://127.0.0.1:5200"; | |
| const TOKEN = "0x528-A2A-SOVEREIGN"; | |
| let EDGES = []; | |
| let SLIDER_VALUES = new Array(32).fill(1.0); | |
| function setMode(mode) { | |
| document.getElementById('chat-window').style.display = mode === 'CHAT' ? 'flex' : 'none'; | |
| document.getElementById('analyze-window').style.display = mode === 'ANALYZE' ? 'flex' : 'none'; | |
| document.getElementById('btn-chat').style.background = mode === 'CHAT' ? 'var(--accent)' : 'rgba(255,255,255,0.1)'; | |
| document.getElementById('btn-chat').style.color = mode === 'CHAT' ? '#000' : '#fff'; | |
| document.getElementById('btn-analyze').style.background = mode === 'ANALYZE' ? 'var(--accent)' : 'rgba(255,255,255,0.1)'; | |
| document.getElementById('btn-analyze').style.color = mode === 'ANALYZE' ? '#000' : '#fff'; | |
| } | |
| // --- INIT --- | |
| async function init() { | |
| try { | |
| // Fetch Structure | |
| const r = await fetch(`${API_URL}/v1/system/structure`, { | |
| headers: { "X-Chiral-Token": TOKEN } | |
| }); | |
| const data = await r.json(); | |
| EDGES = data.edges; | |
| renderSliders(data.edges, data.dimensions); | |
| // Init Visualizer | |
| initVisualizer(); | |
| // Status | |
| document.getElementById('status-bar').innerText = `SYSTEM CONNECTED: ${data.total_edges} Edges Loaded.`; | |
| } catch (e) { | |
| console.error(e); | |
| document.getElementById('sliders-container').innerHTML = `<span style="color:red">CONNECTION FAILED: ${e}</span>`; | |
| } | |
| } | |
| async function analyzeText() { | |
| const text = document.getElementById('analyze-input').value; | |
| if (!text) return; | |
| document.getElementById('scan-results').innerText = "SCANNING..."; | |
| try { | |
| const r = await fetch(`${API_URL}/v1/analyze`, { | |
| method: 'POST', | |
| headers: { | |
| "Content-Type": "application/json", | |
| "X-Chiral-Token": TOKEN | |
| }, | |
| body: JSON.stringify({ text: text }) | |
| }); | |
| const data = await r.json(); | |
| const resHTML = ` | |
| <strong>CLASSIFICATION: ${data.classification}</strong><br> | |
| Integrity: ${(data.integrity_score * 100).toFixed(1)}% | Tokens: ${data.token_count}<br> | |
| <span style="color:#ff0055">LOGIC: ${(data.geometric_signature[0] * 100).toFixed(0)}%</span> | | |
| <span style="color:#00ccff">CREAT: ${(data.geometric_signature[1] * 100).toFixed(0)}%</span> | | |
| <span style="color:#ffcc00">MEM: ${(data.geometric_signature[2] * 100).toFixed(0)}%</span> | | |
| <span style="color:#aa00ff">ETHIC: ${(data.geometric_signature[3] * 100).toFixed(0)}%</span> | |
| `; | |
| document.getElementById('scan-results').innerHTML = resHTML; | |
| // Update Radar | |
| drawRadar(data.geometric_signature); | |
| } catch (e) { | |
| document.getElementById('scan-results').innerText = "SCAN FAILED: " + e; | |
| } | |
| } | |
| function toggleAdvanced() { | |
| const adv = document.getElementById('advanced-controls'); | |
| adv.style.display = adv.style.display === 'none' ? 'block' : 'none'; | |
| } | |
| function updateMaster(dimIdx, value) { | |
| const val = parseFloat(value); | |
| // Update all edges matching this dimension | |
| EDGES.forEach(edge => { | |
| if (edge.dimension === dimIdx) { | |
| const slider = document.getElementById(`slider-${edge.edge_index}`); | |
| if (slider) { | |
| slider.value = val; | |
| SLIDER_VALUES[edge.edge_index] = val; | |
| } | |
| } | |
| }); | |
| drawTesseract(); | |
| } | |
| function renderSliders(edges, dimensions) { | |
| const container = document.getElementById('sliders-container'); | |
| container.innerHTML = ""; | |
| // Group by Dimension | |
| const groups = {}; | |
| for (let dim in dimensions) groups[dim] = []; | |
| edges.forEach(edge => { | |
| if (!groups[edge.dimension]) groups[edge.dimension] = []; | |
| groups[edge.dimension].push(edge); | |
| }); | |
| // Create UI Groups | |
| for (let dim in dimensions) { | |
| const groupDiv = document.createElement('div'); | |
| groupDiv.className = 'slider-group'; | |
| const title = document.createElement('h3'); | |
| title.innerHTML = `<span class="dot dot-${dim}"></span> ${dimensions[dim]}`; | |
| groupDiv.appendChild(title); | |
| groups[dim].forEach(edge => { | |
| const row = document.createElement('div'); | |
| row.className = 'slider-row'; | |
| const label = document.createElement('span'); | |
| label.innerText = `E${edge.edge_index}`; | |
| label.title = `Vertices: ${edge.vertices[0]} -> ${edge.vertices[1]}`; | |
| const slider = document.createElement('input'); | |
| slider.type = 'range'; | |
| slider.min = '0.1'; | |
| slider.max = '5.0'; | |
| slider.step = '0.1'; | |
| slider.value = '1.0'; | |
| slider.id = `slider-${edge.edge_index}`; | |
| // Track value changes | |
| slider.addEventListener('input', (e) => { | |
| updateWeight(edge.edge_index, e.target.value); | |
| }); | |
| row.appendChild(label); | |
| row.appendChild(slider); | |
| groupDiv.appendChild(row); | |
| }); | |
| container.appendChild(groupDiv); | |
| } | |
| // Init weights array | |
| SLIDER_VALUES = new Array(32).fill(1.0); | |
| } | |
| function updateWeight(index, value) { | |
| SLIDER_VALUES[index] = parseFloat(value); | |
| drawTesseract(); // Redraw | |
| } | |
| function resetSliders() { | |
| SLIDER_VALUES.fill(1.0); | |
| document.querySelectorAll('input[type="range"]').forEach(el => el.value = 1.0); | |
| drawTesseract(); | |
| } | |
| // --- CHAT --- | |
| async function sendQuery() { | |
| const input = document.getElementById('query-input'); | |
| const text = input.value.trim(); | |
| if (!text) return; | |
| // add user msg | |
| addMessage(text, 'user'); | |
| input.value = ""; | |
| // Show loading | |
| const loadId = addMessage("Reasoning...", 'system'); | |
| try { | |
| const r = await fetch(`${API_URL}/v1/reason`, { | |
| method: 'POST', | |
| headers: { | |
| "Content-Type": "application/json", | |
| "X-Chiral-Token": TOKEN | |
| }, | |
| body: JSON.stringify({ | |
| query: text, | |
| steering_weights: SLIDER_VALUES | |
| }) | |
| }); | |
| const data = await r.json(); | |
| // Highlight Keywords | |
| let formatted = data.response; | |
| const colors = { | |
| "AXIOM": "#ef4444", "DEDUCE": "#ef4444", "STRUCTURE": "#ef4444", "ORDER": "#ef4444", | |
| "FLUX": "#06b6d4", "SPIRAL": "#06b6d4", "DREAM": "#06b6d4", "ECHO": "#06b6d4", "TWIST": "#06b6d4", | |
| "ANCIENT": "#fbbf24", "RECALL": "#fbbf24", "TRACE": "#fbbf24", "BOND": "#fbbf24", "ROOT": "#fbbf24", | |
| "TRUTH": "#aa00ff", "GUARD": "#aa00ff", "LIGHT": "#aa00ff", "DUTY": "#aa00ff", "ANCHOR": "#aa00ff" | |
| }; | |
| Object.keys(colors).forEach(word => { | |
| const regex = new RegExp(`\\b${word}\\b`, 'gi'); | |
| formatted = formatted.replace(regex, `<span style="color:${colors[word]}; font-weight:bold;">${word.toUpperCase()}</span>`); | |
| }); | |
| // Update msg | |
| const meta = `Mode: ${data.mode} | Coherence: ${data.coherence.toFixed(2)}`; | |
| updateMessage(loadId, `${formatted}<span class="msg-meta">${meta}</span>`); | |
| // Update Radar | |
| if (data.analysis && data.analysis.scores) { | |
| drawRadar(data.analysis.scores); | |
| } | |
| } catch (e) { | |
| updateMessage(loadId, `ERROR: ${e}`); | |
| } | |
| } | |
| let msgCount = 0; | |
| function addMessage(html, type) { | |
| const div = document.createElement('div'); | |
| div.className = `msg ${type}`; | |
| div.id = `msg-${msgCount++}`; | |
| div.innerHTML = html; | |
| document.getElementById('messages').appendChild(div); | |
| // Scroll down | |
| const win = document.getElementById('messages'); | |
| win.scrollTop = win.scrollHeight; | |
| return div.id; | |
| } | |
| function updateMessage(id, html) { | |
| const div = document.getElementById(id); | |
| if (div) div.innerHTML = html; | |
| } | |
| // --- VISUALIZER (RADAR CHART) --- | |
| let ctx; | |
| function initVisualizer() { | |
| const canvas = document.getElementById('tesseract-canvas'); | |
| canvas.width = canvas.parentElement.offsetWidth; | |
| canvas.height = canvas.parentElement.offsetHeight; | |
| ctx = canvas.getContext('2d'); | |
| drawRadar({ 0: 0.25, 1: 0.25, 2: 0.25, 3: 0.25 }); | |
| } | |
| function drawRadar(scores) { | |
| if (!ctx) return; | |
| const w = ctx.canvas.width; | |
| const h = ctx.canvas.height; | |
| const cx = w / 2; | |
| const cy = h / 2; | |
| const r = Math.min(w, h) / 3; | |
| ctx.clearRect(0, 0, w, h); | |
| // Shape | |
| const vals = [ | |
| scores[0] || 0.1, // Logic (Top) | |
| scores[1] || 0.1, // Creat (Right) | |
| scores[3] || 0.1, // Ethics (Bottom) | |
| scores[2] || 0.1 // Memory (Left) | |
| ]; | |
| // Draw Axes | |
| ctx.strokeStyle = '#333'; | |
| ctx.beginPath(); | |
| ctx.moveTo(cx, cy - r); ctx.lineTo(cx, cy + r); | |
| ctx.moveTo(cx - r, cy); ctx.lineTo(cx + r, cy); | |
| ctx.stroke(); | |
| // Labels | |
| ctx.fillStyle = '#666'; | |
| ctx.font = '10px monospace'; | |
| ctx.fillText("LOGIC", cx - 15, cy - r - 10); | |
| ctx.fillText("ETHICS", cx - 18, cy + r + 15); | |
| ctx.fillText("CREAT", cx + r + 10, cy + 3); | |
| ctx.fillText("MEM", cx - r - 30, cy + 3); | |
| // Draw Polygon | |
| ctx.fillStyle = 'rgba(0, 255, 157, 0.2)'; | |
| ctx.strokeStyle = '#00ff9d'; | |
| ctx.lineWidth = 2; | |
| ctx.beginPath(); | |
| const pts = [ | |
| { x: cx, y: cy - (vals[0] * r) }, | |
| { x: cx + (vals[1] * r), y: cy }, | |
| { x: cx, y: cy + (vals[2] * r) }, | |
| { x: cx - (vals[3] * r), y: cy } | |
| ]; | |
| ctx.moveTo(pts[0].x, pts[0].y); | |
| ctx.lineTo(pts[1].x, pts[1].y); | |
| ctx.lineTo(pts[2].x, pts[2].y); | |
| ctx.lineTo(pts[3].x, pts[3].y); | |
| ctx.closePath(); | |
| ctx.fill(); | |
| ctx.stroke(); | |
| } | |
| // Stub for old function calls in case bound events trigger | |
| function drawTesseract() { | |
| // For now, do nothing or redraw radar if we had state | |
| // But radar is driven by response, not input sliders directly | |
| // We could visualize input bias here if we wanted | |
| } | |
| window.onload = init; | |
| </script> | |
| </body> | |
| </html> |