fix(web-probe): scope card timing and refresh abort alerts (#754)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-23 21:15:37 +08:00
committed by GitHub
parent 671630500f
commit ea73dcfbdb
@@ -3398,6 +3398,11 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) {
.map((item) => Date.parse(item.ts))
.filter(Number.isFinite)
.sort((a, b) => a - b);
const observerRefreshTimes = control
.filter((item) => item.type === "observer-periodic-refresh")
.map((item) => Date.parse(item.ts))
.filter(Number.isFinite)
.sort((a, b) => a - b);
const naturalNetwork = network.filter((item) => item?.observerInitiated !== true);
const httpErrors = naturalNetwork
.filter((item) => item?.type === "response" && Number(item.status) >= 400)
@@ -3405,7 +3410,9 @@ function buildRuntimeAlerts(samples, control, network, consoleEvents, errors) {
const requestFailed = naturalNetwork
.filter((item) => item?.type === "requestfailed")
.map((item) => networkAlertEvent(item, promptTimes));
const significantRequestFailed = requestFailed.filter((item) => !isBenignLongLivedStreamClosureAlert(item));
const significantRequestFailed = requestFailed.filter(
(item) => !isBenignLongLivedStreamClosureAlert(item) && !isObserverRefreshClosureAlert(item, observerRefreshTimes),
);
const domDiagnostics = [];
const executionErrors = [];
const baselineExecutionErrors = [];
@@ -3789,6 +3796,15 @@ function isBenignLongLivedStreamClosureAlert(event) {
return /ERR_NETWORK_CHANGED|ERR_ABORTED|net::ERR_NETWORK_CHANGED|net::ERR_ABORTED|aborted|network changed/iu.test(text);
}
function isObserverRefreshClosureAlert(event, observerRefreshTimes) {
if (!["/v1/workbench/events", "/v1/web-performance"].includes(String(event?.urlPath || ""))) return false;
if (event.status !== null && event.status !== undefined && Number(event.status) > 0) return false;
const text = String(event.failureKind || event.errorPreview || event.preview || "");
if (!/ERR_NETWORK_CHANGED|ERR_ABORTED|net::ERR_NETWORK_CHANGED|net::ERR_ABORTED|aborted|network changed/iu.test(text)) return false;
const ts = Date.parse(String(event.ts || ""));
return Number.isFinite(ts) && observerRefreshTimes.some((refreshTs) => Math.abs(ts - refreshTs) <= 8000);
}
function networkAlertEvent(item, promptTimes) {
const failureText = item.failureKind ?? item.failure ?? item.errorText ?? null;
return {
@@ -5176,8 +5192,8 @@ function buildCodeAgentCardTimingMetrics(samples, timeline, turnTiming) {
const timelineItem = timeline[index] || {};
for (const card of codeAgentCardsForSample(sample)) {
const text = codeAgentCardText(card);
const totalElapsedValues = parseTotalElapsedSeconds(text).filter(Number.isFinite);
const recentUpdateValues = parseRecentUpdateSeconds(text).filter(Number.isFinite);
const totalElapsedValues = parseTotalElapsedSeconds(card?.durationText).filter(Number.isFinite);
const recentUpdateValues = parseRecentUpdateSeconds(card?.activityText).filter(Number.isFinite);
const terminal = isCodeAgentCardTerminal(card);
const row = {
...ref(sample),
@@ -5427,7 +5443,7 @@ function detectPostCompletionTimingChanges(turnTiming, event) {
if (!cell) continue;
if (event.traceId && cell.traceId && cell.traceId !== event.traceId) continue;
if (event.messageId && cell.messageId && cell.messageId !== event.messageId) continue;
const total = Number(cell.totalElapsedSeconds);
const total = cell.totalElapsedSeconds === null || cell.totalElapsedSeconds === undefined ? NaN : Number(cell.totalElapsedSeconds);
if (Number.isFinite(total)) {
if (previousTotal && Math.abs(total - previousTotal.value) > alertThresholds.turnTimingSampleSlackSeconds) {
timingChanges.push({
@@ -5450,7 +5466,7 @@ function detectPostCompletionTimingChanges(turnTiming, event) {
}
previousTotal = { value: total, seq: row.seq ?? null, ts: row.ts ?? null };
}
const recent = Number(cell.recentUpdateSeconds);
const recent = cell.recentUpdateSeconds === null || cell.recentUpdateSeconds === undefined ? NaN : Number(cell.recentUpdateSeconds);
if (Number.isFinite(recent)) {
recentUpdateVisible.push({
...eventRef(event),