| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>eMoE v12 — Routing & z-Geometry</title> |
| |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> |
| <script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js"></script> |
| <style> |
| body { margin: 0; overflow: hidden; background: #0f172a; color: #f8fafc; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; display: flex; height: 100vh; } |
| |
| |
| #sidebar { width: 440px; background: #1e293b; padding: 20px; overflow-y: auto; border-right: 1px solid #334155; display: flex; flex-direction: column; gap: 20px; box-sizing: border-box; z-index: 10; } |
| |
| |
| #sidebar::-webkit-scrollbar { width: 6px; } |
| #sidebar::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.2); border-radius: 3px; } |
| |
| #canvas-container { flex-grow: 1; position: relative; background: #0f172a; cursor: crosshair; } |
| |
| |
| .control-box { background: #0f172a; padding: 15px; border-radius: 8px; border: 1px solid #334155; } |
| .slider-container { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; } |
| input[type=range] { flex-grow: 1; accent-color: #38bdf8; cursor: pointer; } |
| |
| |
| table { width: 100%; border-collapse: collapse; font-size: 0.85rem; background: #0f172a; border-radius: 8px; overflow: hidden; border: 1px solid #334155;} |
| th { text-align: left; color: #94a3b8; padding: 10px; background: #1e293b; border-bottom: 1px solid #334155;} |
| td { padding: 10px; border-bottom: 1px solid #334155; } |
| tr { transition: background 0.2s; } |
| .active-row-exec { background: rgba(244, 63, 94, 0.15); border-left: 3px solid #f43f5e; } |
| .active-row-know { background: rgba(59, 130, 246, 0.15); border-left: 3px solid #3b82f6; } |
| .active-row-open { background: rgba(234, 179, 8, 0.15); border-left: 3px solid #eab308; } |
| |
| |
| #task-panel { display: none; background: #0f172a; border-radius: 8px; padding: 15px; border: 1px solid #334155; animation: fadeIn 0.3s ease; } |
| #task-panel h3 { margin: 0 0 10px 0; font-size: 1rem; color: #38bdf8; } |
| .badge { display: inline-block; padding: 4px 8px; border-radius: 4px; font-size: 0.75rem; font-weight: bold; margin-bottom: 10px; color: #fff;} |
| .prompt-text { font-style: italic; color: #cbd5e1; font-size: 0.9rem; margin-bottom: 15px; background: rgba(255,255,255,0.05); padding: 10px; border-radius: 4px; border-left: 3px solid #64748b;} |
| |
| |
| .flow-node { display: flex; align-items: flex-start; gap: 12px; background: #1e293b; padding: 12px 14px; border-radius: 6px; border: 1px solid #334155; border-left-width: 4px; border-left-color: #64748b; margin: 0; } |
| .flow-icon { font-size: 1.25rem; opacity: 0.9; margin-top: 2px; } |
| .flow-content { display: flex; flex-direction: column; width: 100%; } |
| .flow-content strong { font-size: 0.85rem; color: #f8fafc; margin-bottom: 4px;} |
| .flow-content span { font-size: 0.75rem; color: #cbd5e1; line-height: 1.3;} |
| .flow-arrow { text-align: center; font-size: 1.2rem; color: #475569; margin: 4px 0; line-height: 1; font-weight: bold; } |
| |
| |
| .sub-steps { margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,0.1); display: flex; flex-direction: column; gap: 6px; } |
| .sub-step { position: relative; padding-left: 14px; font-size: 0.75rem; color: #94a3b8; line-height: 1.3; } |
| .sub-step::before { content: '↳'; position: absolute; left: 0; top: 0; color: #64748b; font-weight: bold; } |
| .sub-highlight { color: #e2e8f0; font-weight: 500; } |
| |
| .instructions { position: absolute; top: 20px; left: 20px; font-size: 0.85rem; color: #94a3b8; pointer-events: none; background: rgba(15,23,42,0.8); padding: 8px 12px; border-radius: 4px; border: 1px solid #334155;} |
| |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: translateY(0); } } |
| </style> |
| </head> |
| <body> |
|
|
| <div id="sidebar"> |
| <h2 style="margin-bottom:2px;">eMoE v12 — Routing Engine</h2><div style="font-size:0.72rem;color:#64748b;font-family:monospace;margin-bottom:4px;">frozen 190M base (VAL 1.66) · 9.20M hyper (VAL ~2.84) · d_z 768 · 64 sites</div> |
| |
| <div class="control-box" style="border-color:#1e3a5f;"> |
| <div style="font-size:0.85rem;font-weight:600;margin-bottom:8px;color:#f8fafc;">Three pillars</div> |
| <div style="font-size:0.72rem;color:#cbd5e1;line-height:1.5;"> |
| <span style="color:#38bdf8;">1. Frozen base</span> 190M FFT-hybrid (4 attn + 8 spectral). Never adapted.<br> |
| <span style="color:#38bdf8;">2. Hypernetwork</span> 9.20M. z → FiLM (envelope/gain) + LoRA (kernel-gen MLP) at 64 sites. No dense ΔW.<br> |
| <span style="color:#38bdf8;">3. Runtime harness</span> deterministic: gate → OOD controller → RAG → mint/verify/escalate. α backstop 0.8 (fixed). |
| </div> |
| </div> |
|
|
| <div class="control-box"> |
| <div style="font-size: 0.85rem; font-weight: 600; margin-bottom: 8px; color:#f8fafc;">z-Geometry (1769 tasks → 1504 clusters)</div> |
| <div class="slider-container"> |
| <span style="font-size:0.75rem; color:#94a3b8;">Uniform</span> |
| <input type="range" id="clump-slider" min="0" max="1" step="0.01" value="0.46"> |
| <span style="font-size:0.75rem; color:#94a3b8;">Clumped</span> |
| </div> |
| <p id="status-text" style="font-size: 0.78rem; color: #38bdf8; margin: 5px 0 0 0; font-family: monospace;">spread set — click a dot to see its controller decision</p><div style="font-size:0.68rem;color:#64748b;font-family:monospace;margin-top:6px;line-height:1.5;">in-dist p90 = <span style="color:#3b82f6;">0.287</span> → RAG on<br>in-dist p95 = <span style="color:#f43f5e;">0.308</span> → escalate (k≤5)</div> |
| </div> |
|
|
| <table> |
| <thead><tr><th>Family</th><th>Verifier rung</th><th>k</th></tr></thead> |
| <tbody id="routing-table"> |
| <tr id="row-exec"><td><span style="color:#f43f5e;">●</span> Exec</td><td>exec.compile (parse)</td><td>1 → k</td></tr> |
| <tr id="row-know"><td><span style="color:#3b82f6;">●</span> Knowledge</td><td>rag.match (overlap)</td><td>1 → k</td></tr> |
| <tr id="row-open"><td><span style="color:#eab308;">●</span> Open</td><td>open → α backstop</td><td>1</td></tr> |
| </tbody> |
| </table> |
| |
| <div id="task-panel"> |
| <h3>Selected Prompt Routing</h3> |
| <div id="task-badge" class="badge"></div> |
| <div id="task-prompt" class="prompt-text"></div> |
| |
| <div style="font-size: 0.85rem; font-weight: bold; margin-bottom: 12px; color:#94a3b8; border-bottom: 1px solid #334155; padding-bottom: 6px;">Pipeline Execution Details</div> |
| <div id="ladder-steps"> |
| |
| </div> |
| </div> |
| </div> |
|
|
| <div id="canvas-container"> |
| <div class="instructions">Left Click + Drag to rotate | Scroll to zoom | <b>Click ON OR NEAR any dot to select</b></div> |
| </div> |
|
|
| <script> |
| // --- 1. Scene Setup --- |
| const container = document.getElementById('canvas-container'); |
| const scene = new THREE.Scene(); |
| scene.fog = new THREE.FogExp2(0x0f172a, 0.15); |
| |
| const SIDEBAR_WIDTH = 440; |
| const camera = new THREE.PerspectiveCamera(45, (window.innerWidth - SIDEBAR_WIDTH) / window.innerHeight, 0.1, 100); |
| camera.position.set(2, 1.5, 3.5); |
| |
| const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); |
| renderer.setSize(window.innerWidth - SIDEBAR_WIDTH, window.innerHeight); |
| renderer.setPixelRatio(window.devicePixelRatio); |
| container.appendChild(renderer.domElement); |
| |
| const controls = new THREE.OrbitControls(camera, renderer.domElement); |
| controls.enableDamping = true; |
| controls.dampingFactor = 0.05; |
| controls.enablePan = false; |
| controls.minDistance = 1.5; |
| controls.maxDistance = 6; |
| |
| // Base Wireframe Sphere |
| const sphereGeo = new THREE.SphereGeometry(1, 32, 32); |
| const sphereMat = new THREE.MeshBasicMaterial({ color: 0x334155, wireframe: true, transparent: true, opacity: 0.2 }); |
| const wireframeSphere = new THREE.Mesh(sphereGeo, sphereMat); |
| scene.add(wireframeSphere); |
| |
| // --- 2. Data Generation --- |
| const NUM_POINTS = 1769; // v12: 1769 tasks (1504 train clusters / 265 val) |
| |
| const families = [ |
| { id: 'exec', name: 'Exec-Verifiable', color: new THREE.Color(0xf43f5e), hex: '#f43f5e', pole: new THREE.Vector3(1, 1, 1).normalize() }, |
| { id: 'know', name: 'Knowledge-Factual', color: new THREE.Color(0x3b82f6), hex: '#3b82f6', pole: new THREE.Vector3(-1, 0.5, -1).normalize() }, |
| { id: 'open', name: 'Open-Ended', color: new THREE.Color(0xeab308), hex: '#eab308', pole: new THREE.Vector3(0.5, -1, -0.5).normalize() } |
| ]; |
| |
| // Dummy prompts to simulate real user requests |
| const promptExamples = { |
| 'exec': [ |
| "Write a Python script to parse a CSV file and output JSON.", |
| "Generate a SQL query to join the customers and orders tables.", |
| "Write a regex pattern to extract valid IPv4 addresses.", |
| "Write a C++ function to calculate the Fibonacci sequence.", |
| "Calculate the surface area of a cylinder with radius 5 and height 10." |
| ], |
| 'know': [ |
| "Explain the biological mechanism of CRISPR-Cas9.", |
| "Summarize the economic causes of the 1973 oil crisis.", |
| "What are the exceptions to the privity of contract rule?", |
| "Describe the process of photosynthesis in C4 plants.", |
| "What were the primary outcomes of the Council of Trent?" |
| ], |
| 'open': [ |
| "Write a formal email declining a vendor's software proposal.", |
| "Translate this poem from English to French.", |
| "Write a short sci-fi story about a sentient coffee machine.", |
| "Draft a polite out-of-office autoreply.", |
| "Rewrite this paragraph to sound more professional." |
| ] |
| }; |
| |
| const pointsData = []; |
| |
| for (let i = 0; i < NUM_POINTS; i++) { |
| // Assign family distribution (roughly 55% Exec, 25% Know, 20% Open) |
| let fIdx = 0; |
| const rand = Math.random(); |
| if (rand > 0.55 && rand < 0.80) fIdx = 1; |
| else if (rand >= 0.80) fIdx = 2; |
| |
| const fam = families[fIdx]; |
| |
| // Uniform random point on sphere (Base position) |
| const u = Math.random(), v = Math.random(); |
| const theta = u * 2.0 * Math.PI; |
| const phi = Math.acos(2.0 * v - 1.0); |
| const basePos = new THREE.Vector3(Math.sin(phi)*Math.cos(theta), Math.sin(phi)*Math.sin(theta), Math.cos(phi)); |
| |
| // Target pole with jitter for clustering |
| const jitter = new THREE.Vector3((Math.random()-0.5)*0.5, (Math.random()-0.5)*0.5, (Math.random()-0.5)*0.5); |
| const targetPos = fam.pole.clone().add(jitter).normalize(); |
| |
| const promptList = promptExamples[fam.id]; |
| const randomPrompt = promptList[Math.floor(Math.random() * promptList.length)]; |
| |
| pointsData.push({ |
| index: i, |
| family: fam, |
| prompt: randomPrompt, |
| base: basePos, |
| target: targetPos, |
| current: new THREE.Vector3(), |
| }); |
| } |
| |
| // Create Point Cloud |
| const geometry = new THREE.BufferGeometry(); |
| const positions = new Float32Array(NUM_POINTS * 3); |
| const colorArray = new Float32Array(NUM_POINTS * 3); |
| |
| for (let i = 0; i < NUM_POINTS; i++) { |
| colorArray[i*3] = pointsData[i].family.color.r; |
| colorArray[i*3+1] = pointsData[i].family.color.g; |
| colorArray[i*3+2] = pointsData[i].family.color.b; |
| } |
| |
| geometry.setAttribute('position', new THREE.BufferAttribute(positions, 3)); |
| geometry.setAttribute('color', new THREE.BufferAttribute(colorArray, 3)); |
| |
| const material = new THREE.PointsMaterial({ size: 0.06, vertexColors: true, transparent: true, opacity: 0.8, blending: THREE.AdditiveBlending }); |
| const pointCloud = new THREE.Points(geometry, material); |
| scene.add(pointCloud); |
| |
| // Highlight marker for clicked point |
| const markerGeo = new THREE.SphereGeometry(0.04, 16, 16); |
| const markerMat = new THREE.MeshBasicMaterial({ color: 0xffffff }); |
| const marker = new THREE.Mesh(markerGeo, markerMat); |
| marker.visible = false; |
| scene.add(marker); |
| |
| |
| // --- 3. Interaction & Logic --- |
| |
| // Slider Logic (Clumping) |
| const slider = document.getElementById('clump-slider'); |
| const statusTxt = document.getElementById('status-text'); |
| |
| function updatePoints() { |
| const t = parseFloat(slider.value); // 0 to 1 |
| |
| if (t < 0.15) statusTxt.innerText = `Mean Cosine: ${t.toFixed(2)} (Uniform/Random)`; |
| else if (t < 0.75) statusTxt.innerText = `Mean Cosine: ${t.toFixed(2)} (Healthy Spread)`; |
| else statusTxt.innerText = `Mean Cosine: ${t.toFixed(2)} (Mode Collapse/Clumped)`; |
| |
| const positionsAttribute = geometry.attributes.position; |
| for (let i = 0; i < NUM_POINTS; i++) { |
| const data = pointsData[i]; |
| data.current.copy(data.base).lerp(data.target, t).normalize(); // Slerp approximation |
| positionsAttribute.setXYZ(i, data.current.x, data.current.y, data.current.z); |
| } |
| positionsAttribute.needsUpdate = true; |
| |
| // Hide marker if space changes |
| marker.visible = false; |
| document.getElementById('task-panel').style.display = 'none'; |
| clearTableHighlights(); |
| } |
| |
| slider.addEventListener('input', updatePoints); |
| updatePoints(); // Init |
| |
| // Native ThreeJS Raycasting (Restored and fixed) |
| const raycaster = new THREE.Raycaster(); |
| raycaster.params.Points.threshold = 0.04; // Very generous hitbox for easy clicking |
| const mouse = new THREE.Vector2(); |
| |
| function clearTableHighlights() { |
| document.getElementById('row-exec').className = ''; |
| document.getElementById('row-know').className = ''; |
| document.getElementById('row-open').className = ''; |
| } |
| |
| container.addEventListener('pointerdown', (event) => { |
| const rect = renderer.domElement.getBoundingClientRect(); |
| mouse.x = ( (event.clientX - rect.left) / rect.width ) * 2 - 1; |
| mouse.y = - ( (event.clientY - rect.top) / rect.height ) * 2 + 1; |
| |
| raycaster.setFromCamera(mouse, camera); |
| const intersects = raycaster.intersectObject(pointCloud); |
| |
| if (intersects.length > 0) { |
| // Grab the actual index from the BufferGeometry array |
| const index = intersects[0].index; |
| const task = pointsData[index]; |
| |
| marker.position.copy(task.current); |
| marker.visible = true; |
| showTaskDetails(task); |
| } |
| }); |
| |
| function showTaskDetails(task) { |
| const panel = document.getElementById('task-panel'); |
| const badge = document.getElementById('task-badge'); |
| const promptStr = document.getElementById('task-prompt'); |
| const stepsContainer = document.getElementById('ladder-steps'); |
| |
| panel.style.display = 'block'; |
| clearTableHighlights(); |
| document.getElementById(`row-${task.family.id}`).className = `active-row-${task.family.id}`; |
| |
| const hexColor = task.family.hex; |
| badge.innerText = task.family.name; |
| badge.style.backgroundColor = hexColor; |
| promptStr.innerText = `"${task.prompt}"`; |
| |
| let best = -1; |
| for (const fam of families) best = Math.max(best, task.current.dot(fam.pole)); |
| const dist = 1 - best; |
| const ragOn = dist >= 0.287, escalate = dist >= 0.308; |
| const distCol = escalate ? '#f43f5e' : (ragOn ? '#eab308' : '#22c55e'); |
| let ctrl = ` |
| <div class="flow-node" style="border-left-color:${distCol}; margin-bottom:10px;"> |
| <div class="flow-icon">\ud83d\udccd</div> |
| <div class="flow-content"> |
| <strong>OOD controller — distance = <span style="color:${distCol}">${dist.toFixed(3)}</span></strong> |
| <span>nearest-cluster cosine distance (novelty, not trust).</span> |
| <div class="sub-steps"> |
| <div class="sub-step"><b>vs τ_rag_on 0.287:</b> ${ragOn ? '<span style="color:#eab308">RAG ON</span> (lean on retrieval)' : '<span style="color:#22c55e">RAG OFF</span> (in-distribution)'}</div> |
| <div class="sub-step"><b>vs τ_k_escalate 0.308:</b> ${escalate ? '<span style="color:#f43f5e">k ≤ 5</span> (escalate experts)' : 'k = 1 (single confident mint)'}</div> |
| <div class="sub-step"><b>α:</b> 0.8 fixed — distance does NOT scale the adapter.</div> |
| </div> |
| </div> |
| </div> |
| <div class="flow-arrow">\u2193</div> |
| `; |
| |
| // Common Step 1: Universal Minting (NO Rephrasing) |
| let html = ctrl + ` |
| <div class="flow-node"> |
| <div class="flow-icon">🧠</div> |
| <div class="flow-content"> |
| <strong>Mint expert</strong> |
| <span>BGE-encoded descriptor → <span class="sub-highlight">z</span> → hypernetwork mints FiLM+LoRA deltas at 64 sites (no dense ΔW).</span> |
| </div> |
| </div> |
| <div class="flow-arrow">↓</div> |
| `; |
| |
| if (task.family.id === 'exec') { |
| html += ` |
| <div class="flow-node" style="border-left-color: ${hexColor}"> |
| <div class="flow-icon">🔄</div> |
| <div class="flow-content"> |
| <strong>Multi-Expert Verifier Loop</strong> |
| <span>Synthesize <span class="sub-highlight">k variant adapters</span> for frozen base.</span> |
| <div class="sub-steps"> |
| <div class="sub-step"><b>Degeneracy Pre-filter:</b> Fast-fail empty/looping generations to save compute.</div> |
| <div class="sub-step"><b>Static Checker:</b> Code goes to compiler/sandbox. Math/Regex goes to rigid regex format parsers (e.g. extracting final numeric values).</div> |
| <div class="sub-step"><b>Stop Condition:</b> Halt execution immediately on first output that parses/compiles successfully (Exit Code 0).</div> |
| </div> |
| </div> |
| </div> |
| <div class="flow-arrow" style="color: ${hexColor}">↓</div> |
| <div class="flow-node" style="border-color: ${hexColor}; border-left-color: ${hexColor}; background: rgba(244, 63, 94, 0.1);"> |
| <div class="flow-icon" style="opacity:1;">✅</div> |
| <div class="flow-content"> |
| <strong style="color: #fff">Selection complete</strong> |
| <span>Deterministically correct output returned.</span> |
| </div> |
| </div> |
| `; |
| } |
| else if (task.family.id === 'know') { |
| html += ` |
| <div class="flow-node" style="border-left-color: ${hexColor}"> |
| <div class="flow-icon">📚</div> |
| <div class="flow-content"> |
| <strong>Multi-Expert RAG Loop</strong> |
| <span>Synthesize <span class="sub-highlight">k variant adapters</span> for frozen base.</span> |
| <div class="sub-steps"> |
| <div class="sub-step"><b>Degeneracy Pre-filter:</b> Fast-fail empty/looping generations to save compute.</div> |
| <div class="sub-step"><b>RAG-Match Scoring:</b> Local BGE similarity-scores every output against retrieved offline text (Wikipedia/Manuals).</div> |
| <div class="sub-step"><b>Stop Condition:</b> Score all <i>k</i>. (Tiebreaker: Embedding-medoid consensus).</div> |
| </div> |
| </div> |
| </div> |
| <div class="flow-arrow" style="color: ${hexColor}">↓</div> |
| <div class="flow-node" style="border-color: ${hexColor}; border-left-color: ${hexColor}; background: rgba(59, 130, 246, 0.1);"> |
| <div class="flow-icon" style="opacity:1;">🎯</div> |
| <div class="flow-content"> |
| <strong style="color: #fff">Selection complete</strong> |
| <span>Output with highest factual RAG-match returned.</span> |
| </div> |
| </div> |
| `; |
| } |
| else if (task.family.id === 'open') { |
| html += ` |
| <div class="flow-node" style="border-left-color: ${hexColor}"> |
| <div class="flow-icon">1️⃣</div> |
| <div class="flow-content"> |
| <strong>Single-Mint Generation</strong> |
| <span>Multi-expert loop bypassed. No objective verifier exists for unstructured prose.</span> |
| <div class="sub-steps"> |
| <div class="sub-step"><b>No Judges:</b> No LLM-as-judge, no entropy proxies, no self-critique.</div> |
| <div class="sub-step"><b>Global α Backstop:</b> Fixed α = 0.8 (NOT distance- or perplexity-gated; those were retired).</div> |
| </div> |
| </div> |
| </div> |
| <div class="flow-arrow" style="color: ${hexColor}">↓</div> |
| <div class="flow-node" style="border-color: ${hexColor}; border-left-color: ${hexColor}; background: rgba(234, 179, 8, 0.1);"> |
| <div class="flow-icon" style="opacity:1;">✍️</div> |
| <div class="flow-content"> |
| <strong style="color: #fff">Output returned</strong> |
| <span>α Backstop prevents catastrophic shattering.</span> |
| </div> |
| </div> |
| `; |
| } |
| |
| stepsContainer.innerHTML = html; |
| } |
| |
| // Handle window resize |
| window.addEventListener('resize', onWindowResize, false); |
| function onWindowResize() { |
| camera.aspect = (window.innerWidth - SIDEBAR_WIDTH) / window.innerHeight; |
| camera.updateProjectionMatrix(); |
| renderer.setSize(window.innerWidth - SIDEBAR_WIDTH, window.innerHeight); |
| } |
| |
| // --- 4. Animation Loop --- |
| function animate() { |
| requestAnimationFrame(animate); |
| // Slow auto-rotation |
| scene.rotation.y += 0.0008; |
| controls.update(); |
| renderer.render(scene, camera); |
| } |
| |
| animate(); |
| </script> |
| </body> |
| </html> |