Overhaul history: scores visible, optimization history, full run tracking

Archive list improvements:
- Score column added to run list (color-coded: green 7+, amber 5+, red)
- OPT badge on runs generated by optimization (shows parent run)
- quality_score, score_method, tags, source, parent_run now in list query

Detail panel score display:
- Large color-coded score badge in header (e.g., "8.0/10" in green)
- Shows scoring method (auto/thumbs up/thumbs down)
- Persistent — visible every time you open the detail, not just once

Full optimization history section:
- Shows all optimization runs with timestamps, scores, call counts
- Each run lists ranked variations with strategy, mode, score
- Winner highlighted with star and green border
- "View" button opens any variation's full detail
- "Use" button on winner sends prompt to composer via sessionStorage
- Always loads from /api/optimize-history — no stale data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
root 2026-03-29 07:32:50 -05:00
parent 856f584666
commit 462d81868f

View File

@ -6406,12 +6406,13 @@ def get_runs():
try:
with get_db() as conn:
with conn.cursor(cursor_factory=psycopg2.extras.RealDictCursor) as cur:
_cols = "id, mode, prompt, models_used, created_at, archived, quality_score, score_method, tags, notes, config->>'source' as source, config->>'parent_run' as parent_run"
if show == "archived":
cur.execute("SELECT id, mode, prompt, models_used, created_at, archived FROM team_runs WHERE archived = true ORDER BY created_at DESC LIMIT 200")
cur.execute(f"SELECT {_cols} FROM team_runs WHERE archived = true ORDER BY created_at DESC LIMIT 200")
elif show == "all":
cur.execute("SELECT id, mode, prompt, models_used, created_at, archived FROM team_runs ORDER BY created_at DESC LIMIT 200")
cur.execute(f"SELECT {_cols} FROM team_runs ORDER BY created_at DESC LIMIT 200")
else:
cur.execute("SELECT id, mode, prompt, models_used, created_at, archived FROM team_runs WHERE archived = false ORDER BY created_at DESC LIMIT 50")
cur.execute(f"SELECT {_cols} FROM team_runs WHERE archived = false ORDER BY created_at DESC LIMIT 50")
runs = cur.fetchall()
for r in runs:
r["created_at"] = r["created_at"].isoformat()
@ -6746,7 +6747,8 @@ h1 span{color:var(--accent)}
.spacer{flex:1}
.count-badge{font-family:'JetBrains Mono',monospace;font-size:10px;color:var(--text2)}
.run-table{width:100%}
.run-row{display:grid;grid-template-columns:30px 50px 90px 1fr 80px 100px 80px;gap:8px;padding:8px 10px;border-bottom:1px solid rgba(42,45,53,0.3);align-items:center;font-size:11px;cursor:pointer;transition:background 0.1s}
.run-row{display:grid;grid-template-columns:30px 50px 90px 1fr 80px 70px 100px 80px;gap:8px;padding:8px 10px;border-bottom:1px solid rgba(42,45,53,0.3);align-items:center;font-size:11px;cursor:pointer;transition:background 0.1s}
.run-score{font-family:'JetBrains Mono',monospace;font-size:11px;display:flex;align-items:center;gap:3px}
.run-row:hover{background:rgba(226,181,90,0.03)}
.run-row.archived{opacity:0.4}
.run-hdr{font-family:'JetBrains Mono',monospace;font-size:8px;text-transform:uppercase;letter-spacing:1px;color:var(--text2);cursor:default;border-bottom:2px solid var(--border)}
@ -7029,6 +7031,21 @@ function renderTable(runs) {
var tagsEl = document.createElement('span'); tagsEl.className = 'run-tags';
(r.tags||[]).forEach(function(t){ var pill = document.createElement('span'); pill.className = 'tag-pill'; pill.textContent = t; tagsEl.appendChild(pill); });
row.appendChild(tagsEl);
// Score + badges
var scoreEl = document.createElement('span'); scoreEl.className = 'run-score';
if (r.quality_score) {
scoreEl.textContent = r.quality_score.toFixed(1);
scoreEl.style.color = r.quality_score >= 7 ? 'var(--green)' : r.quality_score >= 5 ? 'var(--accent)' : 'var(--red)';
scoreEl.style.fontWeight = '700';
}
if (r.source === 'optimize') {
var optPill = document.createElement('span');
optPill.style.cssText = 'font-size:8px;background:rgba(79,70,229,0.1);color:var(--accent);padding:1px 5px;border-radius:2px;border:1px solid rgba(79,70,229,0.2);margin-left:4px';
optPill.textContent = 'OPT';
optPill.title = 'Generated by optimization from run #' + (r.parent_run||'?');
scoreEl.appendChild(optPill);
}
row.appendChild(scoreEl);
// Date
var dateEl = document.createElement('span'); dateEl.className = 'run-date';
var dt = new Date(r.created_at); dateEl.textContent = dt.toLocaleDateString()+' '+dt.toLocaleTimeString([],{hour:'2-digit',minute:'2-digit'});
@ -7056,6 +7073,22 @@ async function openDetail(id) {
modeTag.textContent = run.mode + ' #' + id; hdr.appendChild(modeTag);
var dateTag = document.createElement('span'); dateTag.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;color:var(--text2)';
dateTag.textContent = new Date(run.created_at).toLocaleString(); hdr.appendChild(dateTag);
// Score badge in header
if (run.quality_score) {
var scoreBadge = document.createElement('span');
var sc = run.quality_score;
scoreBadge.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:14px;font-weight:700;margin-left:auto;padding:4px 12px;border:2px solid;border-radius:2px;' +
'color:' + (sc >= 7 ? 'var(--green)' : sc >= 5 ? 'var(--accent)' : 'var(--red)') + ';' +
'border-color:' + (sc >= 7 ? 'var(--green)' : sc >= 5 ? 'var(--accent)' : 'var(--red)');
scoreBadge.textContent = sc.toFixed(1) + '/10';
if (run.score_method) {
var method = document.createElement('span');
method.style.cssText = 'font-size:8px;text-transform:uppercase;letter-spacing:0.5px;opacity:0.6;margin-left:6px';
method.textContent = run.score_method === 'auto' ? 'auto' : run.score_method === 'user_up' ? '\u{1F44D}' : '\u{1F44E}';
scoreBadge.appendChild(method);
}
hdr.appendChild(scoreBadge);
}
panel.appendChild(hdr);
// Prompt
@ -7107,38 +7140,108 @@ async function openDetail(id) {
actions.appendChild(optBtn);
panel.appendChild(actions);
// Optimization history
if (isOptimized) {
// Optimization history always load, show if data exists
var optSection = document.createElement('div');
optSection.style.cssText = 'background:var(--glow);border:1px solid var(--accent);border-radius:2px;padding:12px;margin-bottom:12px';
var optTitle = document.createElement('div');
optTitle.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:9px;text-transform:uppercase;letter-spacing:1.5px;color:var(--accent);margin-bottom:6px;font-weight:700';
optTitle.textContent = 'Optimization Results';
optSection.appendChild(optTitle);
var optInfo = document.createElement('div');
optInfo.style.cssText = 'font-size:12px;color:var(--text);line-height:1.6';
var bestId = meta.best_variation_run;
var jobId = meta.optimize_job || '';
optInfo.textContent = 'Best variation: Run #' + (bestId||'?') + ' | Job: ' + jobId;
optSection.appendChild(optInfo);
if (bestId) {
var viewBtn = document.createElement('button'); viewBtn.className = 'tool-btn';
viewBtn.style.cssText = 'margin-top:8px;font-size:9px';
viewBtn.textContent = 'View Best Variation (#' + bestId + ')';
viewBtn.onclick = function(){ openDetail(bestId); };
optSection.appendChild(viewBtn);
}
// Load pipeline results for more detail
optSection.style.cssText = 'margin-bottom:12px';
fetch('/api/optimize-history/' + id).then(function(r){return r.json()}).then(function(d){
if (d.results && d.results.length) {
var count = document.createElement('div');
count.style.cssText = 'font-size:11px;color:var(--text2);margin-top:6px;font-family:JetBrains Mono,monospace';
count.textContent = d.results.length + ' optimization(s) run | Best: ' + (d.results[0].best_score||'?') + '/10 | Original: ' + (d.results[0].original_score||'?') + '/10';
optSection.appendChild(count);
var results = d.results || [];
var children = d.children || [];
if (!results.length && !children.length) return;
optSection.style.cssText = 'background:var(--glow);border:1px solid var(--accent);border-radius:2px;padding:14px;margin-bottom:12px';
// Header with count
var optHdr = document.createElement('div');
optHdr.style.cssText = 'display:flex;align-items:center;gap:8px;margin-bottom:10px;cursor:pointer';
var optTitle = document.createElement('div');
optTitle.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:10px;text-transform:uppercase;letter-spacing:1.5px;color:var(--accent);font-weight:700';
optTitle.textContent = '\u26A1 Optimization History (' + results.length + ' run' + (results.length !== 1 ? 's' : '') + ', ' + children.length + ' variation' + (children.length !== 1 ? 's' : '') + ')';
optHdr.appendChild(optTitle);
optSection.appendChild(optHdr);
// Each optimization run
results.forEach(function(res, ri) {
var runCard = document.createElement('div');
runCard.style.cssText = 'background:rgba(0,0,0,0.15);border:1px solid var(--border);border-radius:2px;padding:10px;margin-bottom:6px';
var runHdr = document.createElement('div');
runHdr.style.cssText = 'display:flex;align-items:center;gap:8px;font-family:JetBrains Mono,monospace;font-size:10px';
var runLabel = document.createElement('span');
runLabel.style.cssText = 'color:var(--accent);font-weight:700';
runLabel.textContent = 'Run ' + (ri+1);
runHdr.appendChild(runLabel);
var bestBadge = document.createElement('span');
bestBadge.style.cssText = 'color:var(--green);font-weight:700';
bestBadge.textContent = 'Best: ' + (res.best_score||'?') + '/10';
runHdr.appendChild(bestBadge);
var origBadge = document.createElement('span');
origBadge.style.cssText = 'color:var(--text2)';
origBadge.textContent = 'Original: ' + (res.original_score||'?') + '/10';
runHdr.appendChild(origBadge);
if (res.improvement > 0) {
var impBadge = document.createElement('span');
impBadge.style.cssText = 'color:var(--green)';
impBadge.textContent = '+' + res.improvement.toFixed(1);
runHdr.appendChild(impBadge);
}
var callsBadge = document.createElement('span');
callsBadge.style.cssText = 'color:var(--text2);margin-left:auto';
callsBadge.textContent = (res.calls_used||'?') + ' calls';
runHdr.appendChild(callsBadge);
if (res.completed_at) {
var dateBadge = document.createElement('span');
dateBadge.style.cssText = 'color:var(--text2);font-size:9px';
dateBadge.textContent = new Date(res.completed_at).toLocaleDateString();
runHdr.appendChild(dateBadge);
}
runCard.appendChild(runHdr);
// Ranked variations for this run
var ranked = res.ranked || [];
ranked.forEach(function(v, vi) {
var vRow = document.createElement('div');
vRow.style.cssText = 'display:flex;align-items:center;gap:8px;padding:4px 0;font-size:11px;border-top:1px solid rgba(42,45,53,0.2);margin-top:4px';
if (vi === 0) vRow.style.borderLeft = '2px solid var(--green)';
var rank = document.createElement('span');
rank.style.cssText = 'font-family:JetBrains Mono,monospace;font-size:10px;font-weight:700;color:' + (vi === 0 ? 'var(--green)' : 'var(--text2)') + ';min-width:20px';
rank.textContent = vi === 0 ? '\u2605' : '#' + (vi+1);
vRow.appendChild(rank);
var strat = document.createElement('span');
strat.style.cssText = 'font-size:9px;color:var(--accent);font-family:JetBrains Mono,monospace;text-transform:uppercase;min-width:60px';
strat.textContent = v.strategy || '?';
vRow.appendChild(strat);
var vMode = document.createElement('span');
vMode.style.cssText = 'font-size:9px;color:var(--text2);font-family:JetBrains Mono,monospace;min-width:70px';
vMode.textContent = v.mode || '';
vRow.appendChild(vMode);
var vScore = document.createElement('span');
vScore.style.cssText = 'font-family:JetBrains Mono,monospace;font-weight:700;color:' + ((v.score||0) >= 7 ? 'var(--green)' : 'var(--accent)');
vScore.textContent = v.score ? v.score.toFixed(1) : '?';
vRow.appendChild(vScore);
var vSnippet = document.createElement('span');
vSnippet.style.cssText = 'flex:1;color:var(--text2);font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
vSnippet.textContent = (v.snippet || v.prompt || '').substring(0, 80);
vRow.appendChild(vSnippet);
if (v.run_id) {
var viewBtn = document.createElement('button');
viewBtn.style.cssText = 'font-size:8px;padding:2px 6px;cursor:pointer;background:none;border:1px solid var(--border);color:var(--text2);font-family:JetBrains Mono,monospace;border-radius:2px';
viewBtn.textContent = 'View';
viewBtn.onclick = function(e){ e.stopPropagation(); openDetail(v.run_id); };
vRow.appendChild(viewBtn);
}
if (vi === 0 && v.prompt) {
var useBtn = document.createElement('button');
useBtn.style.cssText = 'font-size:8px;padding:2px 6px;cursor:pointer;background:none;border:1px solid var(--accent);color:var(--accent);font-family:JetBrains Mono,monospace;border-radius:2px';
useBtn.textContent = 'Use';
useBtn.onclick = function(e){ e.stopPropagation(); sessionStorage.setItem('pending-prompt', v.prompt); window.location.href = '/'; };
vRow.appendChild(useBtn);
}
runCard.appendChild(vRow);
});
optSection.appendChild(runCard);
});
}).catch(function(){});
panel.appendChild(optSection);
}
// Responses
var responses = run.responses || [];