Ask about a run from the row it is on, and stop spending context on health checks when the run was clean

This commit is contained in:
Gmer4Lfe
2026-08-06 21:51:55 -04:00
parent 4347fc5f07
commit f2d0e18f2c
5 changed files with 105 additions and 19 deletions
+33 -1
View File
@@ -2437,6 +2437,25 @@ function vvAiDockSend() {
}).catch(e => vvAiDockDone('Request failed: ' + e, true));
}
// Asks about one run from the Recent Activity list, in a single click.
//
// It opens the log first rather than asking from wherever the operator happens to be standing.
// That is not decoration: vvOpenRight() runs vvShowLogMode(), which scopes the dock to
// troubleshoot against this script's log id — the profile that gets the log tail and may file a
// bug. Asking without it would send the question up under the assistant's contract with no log
// attached, which is the failure this whole day was spent removing.
//
// The question is posted as text the operator can see in the transcript, not hidden in the
// request, so what was asked on their behalf is never a mystery.
function vvAiAskRun(id, failed, ev) {
if (ev) ev.stopPropagation();
if (!vvAiDockOn() || vvAiBusy) return;
vvOpenRight(id);
const input = document.getElementById('vv-ai-dock-input');
input.value = failed ? 'Why did this run fail?' : 'How did this run go?';
vvAiDockSend();
}
function vvAiDockPoll(token, started) {
started = started || Date.now();
clearTimeout(vvAiPoll);
@@ -3034,16 +3053,29 @@ function vvLoadRecentActivity() {
return;
}
const now = Math.floor(Date.now() / 1000);
const withAi = vvAiDockOn();
let errors = 0;
let html = '<div class="vv-activity-list">';
for (const r of d.runs) {
const cls = r.status === 'ok' ? 'vv-stat-ok' : r.status === 'warn' ? 'vv-stat-warn' : 'vv-stat-error';
if (r.status !== 'ok' && r.status !== 'skipped') errors++;
const bad = r.status !== 'ok' && r.status !== 'skipped';
if (bad) errors++;
// The question is on the row because that is where the operator already is when they want
// it. Reaching the same answer otherwise means noticing the red dot, clicking through to
// the log, finding the dock, and typing out what the row already knows.
const ask = withAi
? '<button class="vv-activity-ask' + (bad ? ' vv-ask-bad' : '') + '"'
+ ' title="' + (bad ? 'Ask the assistant why this run failed'
: 'Ask the assistant how this run went') + '"'
+ ' onclick="vvAiAskRun(' + JSON.stringify(r.id) + ',' + bad + ',event)">'
+ (bad ? 'why?' : 'recap') + '</button>'
: '';
html += '<div class="vv-activity-row" onclick="vvOpenRight(' + JSON.stringify(r.id) + ')">'
+ '<span class="vv-activity-dot ' + cls + '">●</span>'
+ '<span class="vv-activity-label">' + vvEscHtml(r.label) + '</span>'
+ '<span class="vv-activity-ago">' + vvTimeAgo(now - r.start) + '</span>'
+ '<span class="vv-activity-dur">' + vvFmtDur(r.dur) + '</span>'
+ ask
+ '</div>';
}
html += '</div>';