| <!DOCTYPE html>
|
| <html lang="en">
|
| <head>
|
| <meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
| <title>agents ยท holy-agents</title>
|
| <style>
|
| *{margin:0;padding:0;box-sizing:border-box}
|
| body{background:#0a0a0a;color:#b0b0b0;font-family:'Courier New',monospace;min-height:100vh}
|
| .nav{display:flex;justify-content:space-between;align-items:center;padding:12px 20px;border-bottom:1px solid #1a1a1a}
|
| .nav-brand{color:#e0e0e0;font-size:14px;letter-spacing:2px}
|
| .nav-links a{color:#555;text-decoration:none;margin-left:16px;font-size:11px}
|
| .nav-links a:hover,.nav-links a.active{color:#e0e0e0}
|
| .container{max-width:900px;margin:0 auto;padding:32px 20px}
|
| h1{color:#e0e0e0;font-size:18px;margin-bottom:8px}
|
| p{color:#555;font-size:12px;margin-bottom:24px}
|
| .query-box{display:flex;gap:8px;margin-bottom:24px}
|
| .query-input{flex:1;background:#111;border:1px solid #1a1a1a;color:#e0e0e0;padding:12px 16px;font-family:'Courier New',monospace;font-size:14px;outline:none}
|
| .query-input:focus{border-color:#333}
|
| .btn{background:#1a1a1a;border:1px solid #333;color:#e0e0e0;padding:12px 24px;font-family:'Courier New',monospace;font-size:12px;cursor:pointer;text-transform:uppercase;letter-spacing:1px}
|
| .btn:hover{background:#222}
|
| .pipeline-canvas{border:1px solid #1a1a1a;margin-bottom:16px}
|
| .agent-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:24px}
|
| .agent-card{border:1px solid #1a1a1a;padding:16px;text-align:center}
|
| .agent-card.active{border-color:#4a9}
|
| .agent-emoji{font-size:24px;margin-bottom:4px}
|
| .agent-name{color:#e0e0e0;font-size:11px;font-weight:bold}
|
| .agent-zone{color:#444;font-size:9px;margin-top:2px}
|
| .agent-status{font-size:9px;margin-top:4px;color:#555}
|
| .event-log{border:1px solid #1a1a1a;max-height:300px;overflow-y:auto;padding:12px}
|
| .event{padding:4px 0;border-bottom:1px solid #0a0a0a;font-size:10px}
|
| .event:last-child{border-bottom:none}
|
| .event .time{color:#333}
|
| .event .agent{font-weight:bold}
|
| .event .scribe{color:#4a9}
|
| .event .judge{color:#a84}
|
| .event .prophet{color:#a44}
|
| .event .sentinel{color:#44a}
|
| .event .ledge{color:#888}
|
| </style>
|
| </head>
|
| <body>
|
| <nav class="nav">
|
| <div class="nav-brand">holy-agents</div>
|
| <div class="nav-links">
|
| <a href="index.html">home</a>
|
| <a href="query.html">query</a>
|
| <a href="twins.html">twins</a>
|
| <a href="agents.html" class="active">agents</a>
|
| <a href="geometry.html">geometry</a>
|
| <a href="debate.html">debate</a>
|
| <a href="repl.html">repl</a>
|
| </div>
|
| </nav>
|
| <div class="container">
|
| <h1>Agent Pipeline</h1>
|
| <p>Watch agents animate through the pipeline as each query runs.</p>
|
|
|
| <div class="query-box">
|
| <input class="query-input" id="query" placeholder="What is covenant?" />
|
| <button class="btn" id="run-btn">Run Pipeline</button>
|
| </div>
|
|
|
| <canvas class="pipeline-canvas" id="pipeline" width="860" height="160"></canvas>
|
|
|
| <div class="agent-grid">
|
| <div class="agent-card" id="card-scribe"><div class="agent-emoji">๐๐</div><div class="agent-name">SCRIBE</div><div class="agent-zone">Library</div><div class="agent-status" id="status-scribe">idle</div></div>
|
| <div class="agent-card" id="card-judge"><div class="agent-emoji">โ๏ธ๐ง </div><div class="agent-name">JUDGE</div><div class="agent-zone">Court</div><div class="agent-status" id="status-judge">idle</div></div>
|
| <div class="agent-card" id="card-prophet"><div class="agent-emoji">๐ฅ</div><div class="agent-name">PROPHET</div><div class="agent-zone">Forge</div><div class="agent-status" id="status-prophet">idle</div></div>
|
| <div class="agent-card" id="card-sentinel"><div class="agent-emoji">๐ก๏ธ</div><div class="agent-name">SENTINEL</div><div class="agent-zone">Sentinel Gate</div><div class="agent-status" id="status-sentinel">idle</div></div>
|
| <div class="agent-card" id="card-ledge"><div class="agent-emoji">๐งพ๐</div><div class="agent-name">LEDGE</div><div class="agent-zone">Ledger Vault</div><div class="agent-status" id="status-ledge">idle</div></div>
|
| </div>
|
|
|
| <div class="event-log" id="event-log"></div>
|
| </div>
|
|
|
| <script>
|
| const canvas = document.getElementById('pipeline');
|
| const ctx = canvas.getContext('2d');
|
| const agentPositions = [
|
| { name: 'scribe', x: 80, y: 80, emoji: '๐๐', color: '#4a9' },
|
| { name: 'judge', x: 240, y: 80, emoji: 'โ๏ธ๐ง ', color: '#a84' },
|
| { name: 'prophet', x: 400, y: 80, emoji: '๐ฅ', color: '#a44' },
|
| { name: 'sentinel', x: 560, y: 80, emoji: '๐ก๏ธ', color: '#44a' },
|
| { name: 'ledge', x: 720, y: 80, emoji: '๐งพ๐', color: '#888' }
|
| ];
|
| let activeAgent = -1;
|
| let particles = [];
|
| let logEntries = [];
|
|
|
| function drawPipeline() {
|
| ctx.clearRect(0, 0, canvas.width, canvas.height);
|
| ctx.strokeStyle = '#1a1a1a';
|
| ctx.beginPath();
|
| ctx.moveTo(80, 80);
|
| ctx.lineTo(720, 80);
|
| ctx.stroke();
|
|
|
| agentPositions.forEach((a, i) => {
|
| ctx.fillStyle = i === activeAgent ? a.color : '#1a1a1a';
|
| ctx.beginPath();
|
| ctx.arc(a.x, a.y, 20, 0, Math.PI * 2);
|
| ctx.fill();
|
| ctx.font = '16px serif';
|
| ctx.textAlign = 'center';
|
| ctx.fillStyle = '#fff';
|
| ctx.fillText(a.emoji, a.x, a.y + 6);
|
| ctx.font = '9px Courier New';
|
| ctx.fillStyle = i === activeAgent ? a.color : '#555';
|
| ctx.fillText(a.name, a.x, a.y + 35);
|
| });
|
|
|
| particles = particles.filter(p => p.life > 0);
|
| particles.forEach(p => {
|
| p.x += p.vx; p.y += p.vy; p.life--;
|
| ctx.globalAlpha = p.life / p.maxLife;
|
| ctx.fillStyle = p.color;
|
| ctx.fillRect(p.x, p.y, 2, 2);
|
| });
|
| ctx.globalAlpha = 1;
|
| requestAnimationFrame(drawPipeline);
|
| }
|
| drawPipeline();
|
|
|
| function activateAgent(index) {
|
| activeAgent = index;
|
| const a = agentPositions[index];
|
| document.querySelectorAll('.agent-card').forEach(c => c.classList.remove('active'));
|
| document.getElementById(`card-${a.name}`).classList.add('active');
|
| document.getElementById(`status-${a.name}`).textContent = 'running';
|
| document.getElementById(`status-${a.name}`).style.color = a.color;
|
|
|
| if (index > 0) {
|
| const prev = agentPositions[index - 1];
|
| for (let i = 0; i < 5; i++) {
|
| particles.push({
|
| x: prev.x, y: prev.y,
|
| vx: (a.x - prev.x) / 30 + (Math.random() - 0.5) * 2,
|
| vy: (a.y - prev.y) / 30 + (Math.random() - 0.5) * 2,
|
| life: 30, maxLife: 30, color: a.color
|
| });
|
| }
|
| }
|
|
|
| addLog(a.name.toUpperCase(), `pipeline stage active`);
|
| }
|
|
|
| function addLog(agent, message) {
|
| const time = new Date().toLocaleTimeString();
|
| const cls = agent.toLowerCase();
|
| logEntries.unshift({ time, agent, message, cls });
|
| if (logEntries.length > 50) logEntries.pop();
|
| const el = document.getElementById('event-log');
|
| el.innerHTML = logEntries.map(e =>
|
| `<div class="event"><span class="time">[${e.time}]</span> <span class="agent ${e.cls}">${e.agent}</span> ${e.message}</div>`
|
| ).join('');
|
| }
|
|
|
| async function runPipeline() {
|
| const query = document.getElementById('query').value.trim() || 'What is covenant?';
|
| addLog('SYSTEM', `pipeline started: "${query}"`);
|
|
|
| for (let i = 0; i < agentPositions.length; i++) {
|
| await new Promise(r => setTimeout(r, 600));
|
| activateAgent(i);
|
| }
|
|
|
| await new Promise(r => setTimeout(r, 400));
|
| activeAgent = -1;
|
| agentPositions.forEach(a => {
|
| document.getElementById(`status-${a.name}`).textContent = 'complete';
|
| document.getElementById(`status-${a.name}`).style.color = '#4a9';
|
| });
|
| addLog('SYSTEM', 'pipeline complete โ verdict: approve');
|
| }
|
|
|
| document.getElementById('run-btn').addEventListener('click', runPipeline);
|
| document.getElementById('query').addEventListener('keydown', e => { if (e.key === 'Enter') runPipeline(); });
|
| </script>
|
| </body>
|
| </html>
|
|
|