From c9901dbc9453f55a3dbeadafb990994925ce1875 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 26 Mar 2026 05:06:24 -0500 Subject: [PATCH] Meta-pipeline UI: add Stop/Restart/Results controls per pipeline Each pipeline card now shows: - Status dot + name + status tag + best score - Stop button (red) when running - Restart button (green) when stopped/completed - Results button (magenta) to drill into iterations - Live progress text when running - Stages and iteration count on info line Co-Authored-By: Claude Opus 4.6 (1M context) --- llm_team_ui.py | 79 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/llm_team_ui.py b/llm_team_ui.py index 34f4b75..a153d49 100644 --- a/llm_team_ui.py +++ b/llm_team_ui.py @@ -4007,43 +4007,66 @@ async function loadMetaPipelines() { title.textContent = 'Pipeline Runs'; el.appendChild(title); pipes.forEach(function(p) { - var row = document.createElement('div'); - row.style.cssText = 'display:flex;align-items:center;gap:8px;padding:8px;background:rgba(0,0,0,0.2);border:2px solid var(--border);border-radius:2px;margin-bottom:4px;cursor:pointer;transition:border-color 0.15s;font-size:11px'; - if (p.status === 'running') row.style.borderColor = 'rgba(217,70,239,0.3)'; - if (p.status === 'completed') row.style.borderColor = 'rgba(74,222,128,0.2)'; - row.onmouseenter = function(){row.style.borderColor='var(--accent)'}; - row.onmouseleave = function(){row.style.borderColor = p.status==='running'?'rgba(217,70,239,0.3)':p.status==='completed'?'rgba(74,222,128,0.2)':'var(--border)'}; - // Status dot + var card = document.createElement('div'); + card.style.cssText = 'background:rgba(0,0,0,0.2);border:2px solid var(--border);border-radius:2px;margin-bottom:6px;padding:10px 12px'; + if (p.status === 'running') card.style.borderColor = 'rgba(217,70,239,0.3)'; + if (p.status === 'completed') card.style.borderColor = 'rgba(74,222,128,0.2)'; + + // Top row: status + name + score + controls + var topRow = document.createElement('div'); + topRow.style.cssText = 'display:flex;align-items:center;gap:8px;font-size:11px'; var dot = document.createElement('div'); var dotColor = p.status==='running'?'#d946ef':p.status==='completed'?'var(--green)':'var(--text2)'; dot.style.cssText = 'width:8px;height:8px;border-radius:50%;background:'+dotColor+';flex-shrink:0'; if (p.status === 'running') dot.style.animation = 'pulse 2s infinite'; - row.appendChild(dot); + topRow.appendChild(dot); var name = document.createElement('span'); - name.style.cssText = 'font-weight:700;min-width:140px'; - name.textContent = p.name; row.appendChild(name); - var stagesEl = document.createElement('span'); - stagesEl.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;color:var(--text2);flex:1'; - stagesEl.textContent = (p.stages||[]).join('→'); - row.appendChild(stagesEl); - if (p.live_status && p.status === 'running') { - var prog = document.createElement('span'); - prog.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;color:#d946ef'; - prog.textContent = p.live_status.substep || ''; - row.appendChild(prog); - } + name.style.cssText = 'font-weight:700'; + name.textContent = p.name; topRow.appendChild(name); + var statusTag = document.createElement('span'); + statusTag.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:8px;text-transform:uppercase;letter-spacing:1px;padding:2px 6px;border:1px solid;border-radius:1px;color:'+dotColor+';border-color:'+dotColor; + statusTag.textContent = p.status; topRow.appendChild(statusTag); if (p.best_score > 0) { var score = document.createElement('span'); - score.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;color:var(--green)'; + score.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:11px;font-weight:700;color:var(--green)'; score.textContent = p.best_score.toFixed(1)+'/10'; - row.appendChild(score); + topRow.appendChild(score); } - var iters = document.createElement('span'); - iters.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;color:var(--text2)'; - iters.textContent = (p.iterations||0)+' iters'; - row.appendChild(iters); - row.onclick = function(){viewMetaPipeline(p.id)}; - el.appendChild(row); + var spacer = document.createElement('span'); spacer.style.flex = '1'; topRow.appendChild(spacer); + // Controls + if (p.status === 'running') { + var stopBtn = document.createElement('button'); + stopBtn.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:8px;text-transform:uppercase;padding:3px 8px;border:2px solid rgba(224,82,82,0.3);border-radius:2px;background:transparent;color:var(--red);cursor:pointer'; + stopBtn.textContent = 'Stop'; + stopBtn.onclick = function(e){e.stopPropagation();fetch('/api/meta-pipeline/'+p.id+'/stop',{method:'POST'}).then(function(){loadMetaPipelines()})}; + topRow.appendChild(stopBtn); + } else if (p.status !== 'running') { + var startBtn = document.createElement('button'); + startBtn.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:8px;text-transform:uppercase;padding:3px 8px;border:2px solid rgba(74,222,128,0.3);border-radius:2px;background:transparent;color:var(--green);cursor:pointer'; + startBtn.textContent = 'Restart'; + startBtn.onclick = function(e){e.stopPropagation();fetch('/api/meta-pipeline/'+p.id+'/start',{method:'POST'}).then(function(){loadMetaPipelines()})}; + topRow.appendChild(startBtn); + } + var viewBtn = document.createElement('button'); + viewBtn.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:8px;text-transform:uppercase;padding:3px 8px;border:2px solid rgba(217,70,239,0.3);border-radius:2px;background:transparent;color:#d946ef;cursor:pointer'; + viewBtn.textContent = 'Results'; + viewBtn.onclick = function(e){e.stopPropagation();viewMetaPipeline(p.id)}; + topRow.appendChild(viewBtn); + card.appendChild(topRow); + + // Info row: stages + iterations + live status + var infoRow = document.createElement('div'); + infoRow.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;color:var(--text2);margin-top:4px;display:flex;gap:12px'; + infoRow.textContent = (p.stages||[]).join(' → ') + ' | ' + (p.iterations||0) + ' iterations'; + if (p.live_status && p.status === 'running') { + var prog = document.createElement('span'); + prog.style.cssText = 'color:#d946ef;margin-left:auto'; + prog.textContent = p.live_status.substep || ''; + infoRow.appendChild(prog); + } + card.appendChild(infoRow); + + el.appendChild(card); }); } catch(e) {} }