fix(web-probe): report api dom lag candidates

This commit is contained in:
Codex
2026-06-26 21:58:43 +00:00
parent b74a793804
commit 70b3b0725a
2 changed files with 358 additions and 4 deletions
@@ -2164,6 +2164,8 @@ function renderMarkdown(report) {
const traceOrder = report.sampleMetrics?.traceOrder || {};
const traceOrderSummary = traceOrder.summary || {};
const alertSummary = report.runtimeAlerts?.summary || {};
const apiDomLag = report.apiDomLag || {};
const apiDomLagSummary = apiDomLag.summary || {};
const projectManagement = report.projectManagement || {};
const projectSummary = projectManagement.summary || {};
const projectCommandLines = Array.isArray(projectManagement.commands) && projectManagement.commands.length > 0
@@ -2254,6 +2256,12 @@ function renderMarkdown(report) {
const streamPerformanceLines = streamPerformanceItems.length > 0
? streamPerformanceItems.slice(0, 80).map((item) => "- " + item.path + " kind=" + (item.routeKind || "same-origin-api-stream") + " samples=" + item.sampleCount + " streamOpenP50=" + (item.streamOpenP50Ms ?? "-") + "ms streamOpenP75=" + (item.streamOpenP75Ms ?? "-") + "ms streamOpenP95=" + (item.streamOpenP95Ms ?? "-") + "ms streamOpenMax=" + (item.streamOpenMaxMs ?? "-") + "ms streamOpen>budget=" + (item.streamOpenOverBudgetCount ?? item.streamOpenOverFiveSecondCount ?? 0) + " streamOpenBudgetMs=" + (item.streamOpenBudgetMs ?? streamOpenBudgetMs) + " streamOpenLegacy>5s=" + (item.streamOpenOverFiveSecondCount ?? 0) + " streamLifetime>5s=" + (item.streamLifetimeOverFiveSecondCount ?? 0) + " lifetimeMax=" + (item.maxMs ?? "-") + "ms window=" + (item.firstAt || "-") + ".." + (item.lastAt || "-")).join("\n")
: "- 无同源长连接 Resource Timing 样本。";
const apiDomLagGroupLines = Array.isArray(apiDomLag.groups) && apiDomLag.groups.length > 0
? apiDomLag.groups.slice(0, 80).map((item) => "- " + (item.method || "-") + " " + (item.path || "-") + " status=" + (item.status ?? "-") + " kind=" + (item.routeKind || "-") + " confidence=" + (item.confidence || "-") + " count=" + (item.count ?? 0) + " changed=" + (item.domChangedCount ?? 0) + " noChange=" + (item.noDomChangeWithinWindowCount ?? 0) + " p50=" + (item.p50DomChangeDeltaMs ?? "-") + "ms p95=" + (item.p95DomChangeDeltaMs ?? "-") + "ms max=" + (item.maxDomChangeDeltaMs ?? "-") + "ms overBudget=" + (item.overBudgetCount ?? 0) + " window=" + (item.firstAt || "-") + ".." + (item.lastAt || "-")).join("\n")
: "- 无 API-DOM 候选分组。";
const apiDomLagWorstLines = Array.isArray(apiDomLag.worstCandidates) && apiDomLag.worstCandidates.length > 0
? apiDomLag.worstCandidates.slice(0, 40).map((item) => "- " + (item.ts || "-") + " " + (item.method || "-") + " " + (item.path || "-") + " status=" + (item.status ?? "-") + " confidence=" + (item.confidence || "-") + " domChange=" + (item.domChangeDeltaMs ?? "-") + "ms firstSample=" + (item.firstSampleDeltaMs ?? "-") + "ms session=" + (item.sessionId || "-") + " traceId=" + (item.traceId || "-") + " beforeSeq=" + (item.beforeSample?.seq ?? "-") + " changeSeq=" + (item.changeSample?.seq ?? "-")).join("\n")
: "- 无 API-DOM digest 变化候选。";
const metricLines = Array.isArray(report.sampleMetrics?.timeline) && report.sampleMetrics.timeline.length > 0
? report.sampleMetrics.timeline.slice(0, 120).map((item) => "- #" + item.seq + " " + item.ts + " prompt=" + item.promptIndex + " loadingCount=" + (item.loadingCount ?? 0) + " loadingOwners=" + (item.loadingOwnerCount ?? 0) + " totalElapsedSeconds=" + (item.totalElapsedSeconds ?? "-") + " recentUpdateSeconds=" + (item.recentUpdateSeconds ?? "-") + " terminal=" + item.terminalSeen + " finalText=" + item.finalResultTextSeen + " diagnostic=" + item.diagnosticSeen).join("\n")
: "- 无采样指标。";
@@ -2403,6 +2411,20 @@ function renderMarkdown(report) {
+ "### Page performance: long-lived streams\n\n"
+ "- policy: SSE/long-lived stream lifetime is not ordinary API load latency; only stream open latency is compared with the YAML usability budget, while disconnects remain runtime alerts.\n\n"
+ streamPerformanceLines + "\n\n"
+ "### Natural API to DOM lag candidates\n\n"
+ "- naturalApiResponseCount: " + (apiDomLagSummary.naturalApiResponseCount ?? 0) + "\n"
+ "- stateRelevantResponseCount: " + (apiDomLagSummary.stateRelevantResponseCount ?? 0) + "\n"
+ "- candidateCount: " + (apiDomLagSummary.candidateCount ?? 0) + "\n"
+ "- domChangedCount: " + (apiDomLagSummary.domChangedCount ?? 0) + "\n"
+ "- noDomChangeWithinWindowCount: " + (apiDomLagSummary.noDomChangeWithinWindowCount ?? 0) + "\n"
+ "- budgetMs: " + (apiDomLagSummary.budgetMs ?? "-") + "\n"
+ "- p95DomChangeDeltaMs: " + (apiDomLagSummary.p95DomChangeDeltaMs ?? "-") + "\n"
+ "- maxDomChangeDeltaMs: " + (apiDomLagSummary.maxDomChangeDeltaMs ?? "-") + "\n"
+ "- overBudgetCount: " + (apiDomLagSummary.overBudgetCount ?? 0) + "\n"
+ "- lowConfidenceStreamOpenCount: " + (apiDomLagSummary.lowConfidenceStreamOpenCount ?? 0) + "\n"
+ "- policy: 该指标是调查证据,不作为 Code Agent 阻塞项;/v1/workbench/events 只能代表 SSE stream-open 到后续 DOM 变化的低置信度候选。\n\n"
+ "#### API-DOM groups\n\n" + apiDomLagGroupLines + "\n\n"
+ "#### Worst API-DOM candidates\n\n" + apiDomLagWorstLines + "\n\n"
+ "### Prompt network\n\n" + promptNetworkLines + "\n\n"
+ "### Runtime alerts\n\n"
+ "- httpErrorCount: " + (alertSummary.httpErrorCount ?? 0) + "\n"