// Multi-Agent Orchestration — fan-out N agents on one goal, then converge.
async function renderOrchestration() {
const content = document.getElementById('pageContent');
content.innerHTML = `
Past runs
`;
await orchLoadRuns();
}
async function orchLoadRuns() {
const box = document.getElementById('orchRuns');
try {
const d = await api.getOrchestrationRuns(30);
if (!d.runs.length) { box.innerHTML = ''; return; }
box.innerHTML = d.runs.map(r => `
${escapeHtml(r.goal || '(no goal)')}
${escapeHtml((r.agents||[]).join(' + '))}
→ ${escapeHtml(r.converge_agent||'')}
${escapeHtml(r.run_id||'')} · ${escapeHtml(r.timestamp||'')}
`).join('');
} catch (e) {
box.innerHTML = ``;
}
}
async function orchRun() {
const goal = document.getElementById('orchGoal').value.trim();
const btn = document.getElementById('orchRunBtn');
if (!goal) { alert('Enter a project goal first.'); return; }
const angles = {};
const oc = document.getElementById('orchOpencode').value.trim();
const gm = document.getElementById('orchGemini').value.trim();
const hm = document.getElementById('orchHermes').value.trim();
if (oc) angles.opencode = oc;
if (gm) angles.gemini = gm;
if (hm) angles.hermes = hm;
btn.disabled = true; btn.textContent = 'Running agents…';
const res = document.getElementById('orchResult');
res.innerHTML = 'Fanning out agents & converging… ';
try {
const data = await api.orchestrate({ goal, angles: Object.keys(angles).length ? angles : undefined });
const cards = (data.outputs && Object.entries(data.outputs) || [])
.map(([a, o]) => `
${escapeHtml(a)}angle output
${escapeHtml((o||'').slice(0,2000))}
`).join('');
res.innerHTML = `
✅ Synthesis (via ${escapeHtml(data.converge_agent||'')})
${escapeHtml(data.synthesis || '(no synthesis)')}
run_id: ${escapeHtml(data.run_id||'')} · saved to ${escapeHtml(data.run_file||'')}
Show per-agent angle outputs
${cards}
`;
await orchLoadRuns();
} catch (e) {
res.innerHTML = `⚠
Orchestration failed
${escapeHtml(e.message)}
`;
} finally {
btn.disabled = false; btn.textContent = '🚀 Launch agents';
}
}