fix: separate workbench user-visible performance probe

This commit is contained in:
lyon
2026-06-18 11:37:47 +08:00
parent 3abf7e2cb0
commit e5336276a4
3 changed files with 76 additions and 4 deletions
+33 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env node
// SPEC: PJ2026-010401 Web工作台 - Workbench 可见性与性能探针
// SPEC: PJ2026-01060505 Workbench Performance draft-2026-06-17-p0; PJ2026-010401 Web工作台 - Workbench 可见性与性能探针
import { createHash } from "node:crypto";
import { spawn } from "node:child_process";
import fs from "node:fs";
@@ -936,7 +936,27 @@ async function collectTraceTimelineSample(page, args, index) {
const trace = latestAgent?.querySelector(".trace-timeline") ?? null;
const details = trace?.querySelector("details") ?? null;
const rows = latestAgent ? [...latestAgent.querySelectorAll(".trace-render-row")] : [];
const rowPreview = (row) => row?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 240) ?? null;
const rowSummary = (row) => row ? {
rowId: row.getAttribute("data-row-id") ?? null,
kind: row.getAttribute("data-row-kind") ?? null,
terminal: row.getAttribute("data-terminal") === "true",
status: row.getAttribute("data-event-status") ?? null,
preview: rowPreview(row)
} : null;
const isUserVisibleOutputRow = (row) => {
const rowId = row.getAttribute("data-row-id") ?? "";
const kind = row.getAttribute("data-row-kind") ?? "";
const text = row.textContent?.replace(/\s+/gu, " ").trim() ?? "";
if (kind === "tool" || rowId.startsWith("tool:")) return true;
if (rowId.startsWith("trace-final-response:")) return true;
if (/助手(?:最终)?消息|assistant (?:final )?message|final response/iu.test(text)) return true;
if (row.getAttribute("data-terminal") === "true" && row.querySelector(".trace-row-body")?.textContent?.trim()) return true;
return false;
};
const latestRow = rows.at(-1) ?? null;
const userVisibleRows = rows.filter(isUserVisibleOutputRow);
const latestUserVisibleRow = userVisibleRows.at(-1) ?? null;
const empty = latestAgent?.querySelector(".trace-empty") ?? null;
const finalResponse = latestAgent?.querySelector(".message-final-response") ?? null;
return {
@@ -949,7 +969,11 @@ async function collectTraceTimelineSample(page, args, index) {
traceOpen: details instanceof HTMLDetailsElement ? details.open : null,
rowCount: rows.length,
emptyLabel: empty?.textContent?.replace(/\s+/gu, " ").trim() ?? null,
latestRowPreview: latestRow?.textContent?.replace(/\s+/gu, " ").trim().slice(0, 240) ?? null,
latestRowPreview: rowPreview(latestRow),
latestRow: rowSummary(latestRow),
userVisibleRowCount: userVisibleRows.length,
latestUserVisibleRowPreview: rowPreview(latestUserVisibleRow),
latestUserVisibleRow: rowSummary(latestUserVisibleRow),
finalTextChars: finalResponse?.textContent?.trim().length ?? 0
};
}, index);
@@ -1057,6 +1081,7 @@ function compactSessionState(state) {
function summarizeTraceRun(samples, dom, sessionSummary) {
const firstDomRow = samples.find((sample) => Number(sample.rowCount ?? 0) > 0) ?? null;
const firstUserVisibleRow = samples.find((sample) => Number(sample.userVisibleRowCount ?? 0) > 0) ?? null;
const firstRestEvent = samples.find((sample) => Number(sample.traceFetch?.eventCount ?? 0) > 0) ?? null;
const last = samples.at(-1) ?? null;
const failedFetches = samples.filter((sample) => sample.traceFetch && sample.traceFetch.ok !== true);
@@ -1069,8 +1094,12 @@ function summarizeTraceRun(samples, dom, sessionSummary) {
finalAgentStatus: last?.agentStatus ?? null,
finalTraceStatus: last?.traceStatus ?? null,
finalDomRowCount: last?.rowCount ?? null,
finalUserVisibleDomRowCount: last?.userVisibleRowCount ?? null,
firstDomRowVisibleAt: firstDomRow?.sampledAt ?? null,
firstDomRowPreview: firstDomRow?.latestRowPreview ?? null,
firstUserVisibleRowAt: firstUserVisibleRow?.sampledAt ?? null,
firstUserVisibleRowPreview: firstUserVisibleRow?.latestUserVisibleRowPreview ?? null,
firstUserVisibleRow: firstUserVisibleRow?.latestUserVisibleRow ?? null,
firstRestEventVisibleAt: firstRestEvent?.sampledAt ?? null,
firstRestEventCount: firstRestEvent?.traceFetch?.eventCount ?? null,
restTraceOk: samples.some((sample) => sample.traceFetch?.ok === true),
@@ -1087,8 +1116,10 @@ function summarizeProbePerformance(actions, startedAt, samples, traceSummary) {
startedAt,
submittedAt,
firstDomTraceRowAt: traceSummary?.firstDomRowVisibleAt ?? null,
firstUserVisibleTraceRowAt: traceSummary?.firstUserVisibleRowAt ?? null,
firstRestTraceEventAt: traceSummary?.firstRestEventVisibleAt ?? null,
submitToFirstDomTraceRowMs: submittedAt && traceSummary?.firstDomRowVisibleAt ? Math.max(0, new Date(traceSummary.firstDomRowVisibleAt).getTime() - new Date(submittedAt).getTime()) : null,
submitToFirstUserVisibleTraceRowMs: submittedAt && traceSummary?.firstUserVisibleRowAt ? Math.max(0, new Date(traceSummary.firstUserVisibleRowAt).getTime() - new Date(submittedAt).getTime()) : null,
submitToFirstRestTraceEventMs: submittedAt && traceSummary?.firstRestEventVisibleAt ? Math.max(0, new Date(traceSummary.firstRestEventVisibleAt).getTime() - new Date(submittedAt).getTime()) : null,
totalSampleWindowMs: samples.length >= 2 ? Math.max(0, new Date(samples.at(-1).sampledAt).getTime() - new Date(samples[0].sampledAt).getTime()) : 0
};