fix: separate workbench user-visible performance probe
This commit is contained in:
@@ -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
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user