fix(hwlab): align web-probe terminal finding (#551)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-21 10:13:19 +08:00
committed by GitHub
parent 8e8865e9df
commit b5d4f9594e
@@ -930,7 +930,7 @@ function buildFindings(samples, control, network, errors, sampleMetrics, promptN
if (prevY > 250 && nextY < 40 && !nearCommand(samples[i], commandTimes, 8000)) scrollJumps.push({ from: ref(samples[i - 1]), to: ref(samples[i]) });
}
if (scrollJumps.length > 0) findings.push({ id: "scroll-jump-top", severity: "amber", summary: "scroll position jumped near top without nearby command", count: scrollJumps.length, samples: scrollJumps.slice(0, 10) });
const traceTerminal = samples.some((item) => Array.isArray(item.traceRows) && item.traceRows.some((row) => /completed|failed|canceled|terminal|done/iu.test((row.status || "") + " " + (row.textPreview || ""))));
const traceTerminal = samples.some((item) => Array.isArray(item.traceRows) && item.traceRows.some((row) => isTerminalTraceText((row.status || "") + " " + (row.textPreview || ""))));
const traceSeen = samples.some((item) => Array.isArray(item.traceRows) && item.traceRows.length > 0);
if (traceSeen && !traceTerminal) findings.push({ id: "trace-without-terminal", severity: "amber", summary: "trace rows were visible but no terminal status was sampled", firstTraceSample: ref(samples.find((item) => Array.isArray(item.traceRows) && item.traceRows.length > 0)) });
const promptFailures = Array.isArray(promptNetwork?.rounds) ? promptNetwork.rounds.filter((item) => item.chatPostOk === false) : [];
@@ -1403,6 +1403,14 @@ function isDiagnosticText(text) {
return /Failed to (?:fetch|load resource)|request failed|net::ERR_[A-Z0-9_:-]+|server responded with a status of [45][0-9]{2}|HTTP\s+[45][0-9]{2}|trace_id=|workbench turn\s*超过|无新活动|idle\s+\d+s|waitingFor=|lastEventLabel=|无法连接上游|(?:报警|告警|警告|错误|异常|超时)[:]|timeout[:=]|error[:=]|failed[:=]|warning[:=]|provider-unavailable|agentrun:error|AgentRun error|projection-resume|durable projection store|realtime-gap|\b50[234]\b/iu.test(value);
}
function isTerminalTraceText(text) {
return /轮次完成|轮次失败|轮次取消|已记录|已完成第\d+轮|final response|sealed final response|turn completed|turn failed|turn canceled|terminal result|\bcompleted\b|\bfailed\b|\bcanceled\b|\bcancelled\b|\bterminal\b|\bdone\b/iu.test(String(text || ""));
}
function isFinalResultText(text) {
return /已完成第\d+轮|final response|sealed final response|最终结果|已完成[:]/iu.test(String(text || ""));
}
function buildSampleMetrics(samples, control) {
const promptCommands = control
.filter((item) => item.type === "sendPrompt" && item.phase === "completed")
@@ -1417,8 +1425,8 @@ function buildSampleMetrics(samples, control) {
const totalElapsedValues = texts.flatMap(parseTotalElapsedSeconds).filter(Number.isFinite);
const recentUpdateValues = texts.flatMap(parseRecentUpdateSeconds).filter(Number.isFinite);
const diagnosticTexts = texts.filter((text) => /Failed to fetch|realtime-gap|durable projection store|turn 超过|无法连接|projection-resume|503|timeout|error/iu.test(text)).slice(0, 5);
const terminalTexts = texts.filter((text) => /轮次完成|轮次失败|轮次取消|已记录|已完成第\d+轮|final response|turn completed|turn failed|turn canceled|terminal result/iu.test(text)).slice(0, 5);
const finalResultTexts = texts.filter((text) => /已完成第\d+轮|final response|sealed final response|最终结果|已完成[:]/iu.test(text)).slice(0, 5);
const terminalTexts = texts.filter(isTerminalTraceText).slice(0, 5);
const finalResultTexts = texts.filter(isFinalResultText).slice(0, 5);
return {
seq: sample.seq ?? null,
ts: sample.ts ?? null,