From 27b3a208d2fa345afe86dc1773018e202c11da92 Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 20 Jun 2026 22:42:47 +0000 Subject: [PATCH] fix(web-probe): separate baseline execution errors --- .../hwlab-node-web-observe-runner-source.ts | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/scripts/src/hwlab-node-web-observe-runner-source.ts b/scripts/src/hwlab-node-web-observe-runner-source.ts index 40db6596..d86fcf92 100644 --- a/scripts/src/hwlab-node-web-observe-runner-source.ts +++ b/scripts/src/hwlab-node-web-observe-runner-source.ts @@ -1016,6 +1016,9 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { .map((item) => networkAlertEvent(item, promptTimes)); const domDiagnostics = []; const executionErrors = []; + const baselineExecutionErrors = []; + const firstPromptMs = promptTimes.length > 0 ? promptTimes[0] : Infinity; + const firstSeenExecutionErrorMs = new Map(); for (const sample of samples) { const tsMs = Date.parse(sample?.ts); const promptIndex = Number.isFinite(tsMs) ? latestPromptIndex(promptTimes, tsMs) : 0; @@ -1059,13 +1062,19 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { for (const candidate of sampleExecutionErrorCandidates(sample)) { const parsed = parseExecutionErrorText(candidate.text); if (!parsed) continue; - const dedupeKey = [candidate.source, candidate.traceId || "-", parsed.backend || "-", parsed.code || "-", parsed.status || "-", sha256(candidate.text)].join("|"); + const textHash = sha256(candidate.text); + const dedupeKey = [candidate.source, candidate.traceId || "-", parsed.backend || "-", parsed.code || "-", parsed.status || "-", textHash].join("|"); if (seenExecutionErrors.has(dedupeKey)) continue; seenExecutionErrors.add(dedupeKey); - executionErrors.push({ + const firstSeenMs = firstSeenExecutionErrorMs.has(dedupeKey) ? firstSeenExecutionErrorMs.get(dedupeKey) : tsMs; + if (!firstSeenExecutionErrorMs.has(dedupeKey) && Number.isFinite(tsMs)) firstSeenExecutionErrorMs.set(dedupeKey, tsMs); + const baseline = Number.isFinite(firstSeenMs) && firstSeenMs < firstPromptMs; + const event = { seq: sample.seq ?? null, ts: sample.ts ?? null, promptIndex, + baseline, + firstSeenAt: Number.isFinite(firstSeenMs) ? new Date(firstSeenMs).toISOString() : null, source: candidate.source, backend: parsed.backend, status: parsed.status, @@ -1076,9 +1085,11 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { messageId: candidate.messageId || null, routeSessionId: sample.routeSessionId ?? null, activeSessionId: sample.activeSessionId ?? null, - textHash: sha256(candidate.text), + textHash, preview: limitText(candidate.text, 260) - }); + }; + if (baseline) baselineExecutionErrors.push(event); + else executionErrors.push(event); domDiagnostics.push({ seq: sample.seq ?? null, ts: sample.ts ?? null, @@ -1088,7 +1099,7 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { traceId: candidate.traceId || parsed.traceId || null, routeSessionId: sample.routeSessionId ?? null, activeSessionId: sample.activeSessionId ?? null, - textHash: sha256(candidate.text), + textHash, preview: limitText(candidate.text, 220) }); } @@ -1110,11 +1121,13 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { requestFailedCount: requestFailed.length, domDiagnosticSampleCount: domDiagnostics.length, executionErrorCount: executionErrors.length, + baselineExecutionErrorCount: baselineExecutionErrors.length, consoleAlertCount: consoleAlerts.length, pageErrorCount: pageErrors.length, networkErrorGroupCount: groupNetworkAlerts(httpErrors).length, requestFailedGroupCount: groupNetworkAlerts(requestFailed).length, executionErrorGroupCount: groupExecutionErrors(executionErrors).length, + baselineExecutionErrorGroupCount: groupExecutionErrors(baselineExecutionErrors).length, consoleAlertGroupCount: groupConsoleAlerts(consoleAlerts).length }, networkHttpErrorsByPath: groupNetworkAlerts(httpErrors), @@ -1122,6 +1135,8 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) { domDiagnostics: domDiagnostics.slice(0, 80), runtimeExecutionErrors: executionErrors.slice(0, 120), runtimeExecutionErrorsByCode: groupExecutionErrors(executionErrors), + baselineRuntimeExecutionErrors: baselineExecutionErrors.slice(0, 80), + baselineRuntimeExecutionErrorsByCode: groupExecutionErrors(baselineExecutionErrors), consoleAlerts: consoleAlerts.slice(0, 80), consoleAlertsByPath: groupConsoleAlerts(consoleAlerts), pageErrors: pageErrors.slice(0, 40)