// Per-agent display metadata (icons + role blurb). Built-ins + known custom agents. const ROUTER_AGENT_META = { opencode: { icon: '🔧', blurb: 'Code & DevOps' }, hermes: { icon: '⚡', blurb: 'Memory & Scheduling' }, gemini: { icon: '🧠', blurb: 'Research & Analysis' }, jarvis: { icon: '🤖', blurb: 'Local-first AI / Deep Research' }, kilocode: { icon: '💻', blurb: 'AI Coding Assistant' }, codex: { icon: '🧩', blurb: 'Code Generation' }, }; function routerAgentMeta(name) { return ROUTER_AGENT_META[name] || { icon: '🤖', blurb: 'Custom agent' }; } async function renderSmartRouter() { const content = document.getElementById('pageContent'); content.innerHTML = `
Route a Task
Routing Rules
AgentBest ForKeywords
`; await loadRouterAgents(); } // Pull the live agent list from the server so the dropdown + rules table // always reflect every registered agent (built-in AND custom). async function loadRouterAgents() { let agents = []; try { const data = await api.getAgents(); agents = (data.agents || []).map(a => a.name); } catch (e) { // Fallback to known built-ins if the API is unreachable. agents = ['opencode', 'hermes', 'gemini']; } const select = document.getElementById('routerAgentSelect'); const table = document.getElementById('routerRulesTable'); if (!select || !table) return; // Populate dropdown (preserve the Auto option already in the DOM). agents.forEach(name => { const meta = routerAgentMeta(name); const opt = document.createElement('option'); opt.value = name; opt.textContent = `${meta.icon} ${name} (${meta.blurb})`; select.appendChild(opt); }); // Populate routing-rules table. const rows = agents.map(name => { const meta = routerAgentMeta(name); const kw = (window._routerKeywords && window._routerKeywords[name]) || []; return ` ${meta.icon} ${name} ${meta.blurb} ${kw.join(', ') || '—'} `; }).join(''); table.innerHTML = `AgentBest ForKeywords${rows}`; } async function suggestRouter() { const task = document.getElementById('routerTaskInput').value.trim(); if (!task) { showToast('Describe your task first', 'warning'); return; } const btn = document.querySelector('button[onclick="suggestRouter()"]'); if (btn) { btn.disabled = true; btn.textContent = '⏳ Thinking...'; } try { const data = await api.suggestRouter(task); // Cache keyword map from scores for the rules table refresh. window._routerKeywords = data.scores ? Object.keys(data.scores).reduce((m, a) => m, {}) : {}; const result = document.getElementById('routerResult'); const agentIcons = { opencode: '🔧', hermes: '⚡', gemini: '🧠', jarvis: '🤖', kilocode: '💻', codex: '🧩' }; const confidenceColors = { high: 'var(--green)', medium: 'var(--yellow)', low: 'var(--text-muted)' }; result.innerHTML = `
${agentIcons[data.suggested_agent] || '🤖'} ${data.suggested_agent}
Confidence: ${data.confidence} ${data.confidence === 'high' ? '✅' : data.confidence === 'medium' ? '⚠️' : '❓'}
Best Match
${Object.entries(data.scores || {}).map(([agent, score]) => ` ${agentIcons[agent] || '🤖'} ${agent}: ${score} `).join('')}
`; document.getElementById('routerAgentSelect').value = data.suggested_agent || 'auto'; } catch (err) { showToast('Suggestion failed: ' + err.message, 'error'); } finally { if (btn) { btn.disabled = false; btn.textContent = '🤖 Suggest Agent'; } } } async function routeTask() { const task = document.getElementById('routerTaskInput').value.trim(); if (!task) { showToast('Describe your task first', 'warning'); return; } let agent = document.getElementById('routerAgentSelect').value; if (agent === 'auto') { showToast('Click "Suggest Agent" first or pick an agent manually', 'warning'); return; } const btn = document.querySelector('button[onclick="routeTask()"]'); if (btn) { btn.disabled = true; btn.textContent = '⏳ Routing...'; } try { const data = await api.routeTask(task, agent); showToast(`✅ Task routed to ${agent}`, 'success'); const result = document.getElementById('routerResult'); result.innerHTML += `
Task Routed
${data.message}
`; } catch (err) { showToast('Routing failed: ' + err.message, 'error'); } finally { if (btn) { btn.disabled = false; btn.textContent = '🚀 Route Task'; } } }