diff --git a/network-poc/static/index.html b/network-poc/static/index.html
index 2e93435..df19615 100644
--- a/network-poc/static/index.html
+++ b/network-poc/static/index.html
@@ -1751,8 +1751,15 @@
// Lähettää promptin mallille ja palauttaa vastauksen (tai null virhetilanteessa)
async function kpnRun(model, prompt, silent) {
- termLog(` → ${model} 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 = ` → ${model} käsittelee...`;
+ 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 = ` ✗ ${esc(errText)}`;
return null;
}
const data = await res.json();
const response = (data.response || '').trim();
const tokGen = data.tokens_generated || 0;
- termLog(` ✓ ${data.model || model} (${tokGen} tok)`);
+ 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 = ` ✓ ${esc(data.model || model)} ${tokGen} tok · ${durS} · ${tokS}`;
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 = ` ✗ ${esc(e.message)}`;
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 = ` ${icon} ${msg}${isQueued ? '' : ' ▌'}`;
+ termPanel.scrollTop = termPanel.scrollHeight;
}
// Codelab-loading-teksti