Terminaalin status-rivit tiivistetty: yksi rivi per tehtävä jota päivitetään

Ennen (3 riviä):
  → qwen-coder käsittelee...
  → Reititetty solmulle #2
  ✓ Qwen2.5-Coder-0.5B-Instruct (75 tok)

Jälkeen (1 rivi jota päivitetään):
  → qwen-coder käsittelee...  →  → Reititetty solmulle #2 ▌  →  ✓ Qwen2.5-Coder 75 tok · 12.0s · 6.3 tok/s

Sama div päivitetään pyynnön elinkaaren läpi: käsittelee → reititys → valmis/virhe.
task_routed-viestit päivittävät samaa riviä uusien rivien sijaan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jaakko Vanhala
2026-04-05 18:34:07 +03:00
parent f17fcf0f9d
commit 6a587cd080

View File

@@ -1751,8 +1751,15 @@
// Lähettää promptin mallille ja palauttaa vastauksen (tai null virhetilanteessa)
async function kpnRun(model, prompt, silent) {
termLog(` → <span style="color:#58a6ff">${model}</span> käsittelee...`, '#8b949e');
const taskId = crypto.randomUUID();
// Yksittäinen status-rivi jota päivitetään läpi pyynnön elinkaaren
const statusDiv = document.createElement('div');
statusDiv.className = 'terminal-line';
statusDiv.id = 'status-' + taskId;
statusDiv.innerHTML = ` <span style="color:#8b949e">→ <span style="color:#58a6ff">${model}</span> käsittelee...</span>`;
termPanel.appendChild(statusDiv);
termPanel.scrollTop = termPanel.scrollHeight;
try {
const agent = Object.values(agentPrompts).find(a => a.model === model);
const parts = [];
@@ -1780,13 +1787,15 @@
if (!res.ok) {
const errText = await res.text().catch(() => res.statusText);
termLog(` ${errText}`, '#f85149');
statusDiv.innerHTML = ` <span style="color:#f85149">${esc(errText)}</span>`;
return null;
}
const data = await res.json();
const response = (data.response || '').trim();
const tokGen = data.tokens_generated || 0;
termLog(` <span style="color:#3fb950">✓</span> <span style="color:#58a6ff">${data.model || model}</span> <span style="color:#8b949e">(${tokGen} tok)</span>`);
const durS = data.duration_ms ? (data.duration_ms / 1000).toFixed(1) + 's' : '';
const tokS = data.tokens_per_sec ? data.tokens_per_sec.toFixed(1) + ' tok/s' : '';
statusDiv.innerHTML = ` <span style="color:#3fb950">✓</span> <span style="color:#58a6ff">${esc(data.model || model)}</span> <span style="color:#8b949e">${tokGen} tok · ${durS} · ${tokS}</span>`;
if (!silent) {
// Kompakti yksirivinen esikatselu — klikkaa/hover laajentaa
const firstLine = response.split('\n').find(l => l.trim()) || response;
@@ -1800,7 +1809,7 @@
}
return response;
} catch (e) {
termLog(` ${e.message}`, '#f85149');
statusDiv.innerHTML = ` <span style="color:#f85149">${esc(e.message)}</span>`;
return null;
} finally {
if (activeStreams[taskId]) {
@@ -2462,24 +2471,16 @@
}
}
} else if (data.type === "task_routed") {
const term = document.getElementById('agent-terminal');
const isQueued = data.status === 'queued';
const color = isQueued ? '#d29922' : '#58a6ff';
const color = isQueued ? '#d29922' : '#8b949e';
const icon = isQueued ? '⏳' : '→';
const msg = esc(data.message || '');
// Agents-terminaali
if (term && data.task_id && activeStreams[data.task_id]) {
const div = document.createElement('div');
div.className = 'terminal-line';
div.style.color = color;
div.innerHTML = ` ${icon} ${msg}`;
if (isQueued) div.id = 'routing-' + data.task_id;
// Päivitetään olemassaoleva jonorivi jos löytyy
const existing = document.getElementById('routing-' + data.task_id);
if (existing) { existing.innerHTML = ` ${icon} ${msg}`; existing.style.color = color; }
else term.appendChild(div);
term.scrollTop = term.scrollHeight;
// Päivitetään olemassaoleva status-rivi (kpnRun luo sen)
const statusDiv = document.getElementById('status-' + data.task_id);
if (statusDiv) {
statusDiv.innerHTML = ` <span style="color:${color}">${icon} ${msg}${isQueued ? '' : ' <span style="animation:blink 1s infinite">▌</span>'}</span>`;
termPanel.scrollTop = termPanel.scrollHeight;
}
// Codelab-loading-teksti