fix(web-probe): expose page identity in turn timing report (#788)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -8996,6 +8996,12 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
const partialApiBudgetLabel = budgetLabel(alertThresholds?.partialApiSlowMs);
|
||||
const streamOpenBudgetLabel = budgetLabel(alertThresholds?.longLivedStreamOpenSlowMs);
|
||||
const loadingBudgetLabel = budgetLabel(alertThresholds?.visibleLoadingSlowMs);
|
||||
const pageLabel = (item: Record<string, unknown>): string => {
|
||||
const role = webObserveText(item.pageRole);
|
||||
const pageId = webObserveShort(webObserveText(item.pageId), 18);
|
||||
if (role === "-" && pageId === "-") return "-";
|
||||
return `${role}/${pageId}`;
|
||||
};
|
||||
const promptNetwork = record(analysis?.promptNetwork);
|
||||
const loading = record(sampleMetrics?.loading);
|
||||
const loadingSummary = record(loading?.summary);
|
||||
@@ -9078,6 +9084,7 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
]);
|
||||
const recentUpdateJumpRows = recentUpdateJumps.map((item) => [
|
||||
webObserveShort(webObserveText(item.columnLabel), 14),
|
||||
pageLabel(item),
|
||||
webObserveText(item.promptIndex),
|
||||
webObserveText(item.fromSeq),
|
||||
webObserveText(item.toSeq),
|
||||
@@ -9089,6 +9096,7 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
]);
|
||||
const elapsedZeroResetRows = elapsedZeroResets.map((item) => [
|
||||
webObserveShort(webObserveText(item.columnLabel), 14),
|
||||
pageLabel(item),
|
||||
webObserveText(item.promptIndex),
|
||||
webObserveText(item.fromSeq),
|
||||
webObserveText(item.toSeq),
|
||||
@@ -9098,6 +9106,7 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
]);
|
||||
const elapsedForwardJumpRows = elapsedForwardJumps.map((item) => [
|
||||
webObserveShort(webObserveText(item.columnLabel), 14),
|
||||
pageLabel(item),
|
||||
webObserveText(item.promptIndex),
|
||||
webObserveText(item.fromSeq),
|
||||
webObserveText(item.toSeq),
|
||||
@@ -9202,8 +9211,9 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
"Trace row order anomalies:",
|
||||
traceOrderAnomalies.length === 0
|
||||
? "-"
|
||||
: webObserveTable(["SEQ", "TRACE", "ROWS", "REASONS", "TOTAL", "CLOCK", "PREVIEW"], traceOrderAnomalies.map((item) => [
|
||||
: webObserveTable(["SEQ", "PAGE", "TRACE", "ROWS", "REASONS", "TOTAL", "CLOCK", "PREVIEW"], traceOrderAnomalies.map((item) => [
|
||||
webObserveText(item.sampleIndex ?? item.seq),
|
||||
pageLabel(item),
|
||||
webObserveShort(webObserveText(item.traceId), 24),
|
||||
`${webObserveText(item.previousRowIndex)}->${webObserveText(item.currentRowIndex)}`,
|
||||
webObserveShort(webObserveArray(item.reasons).map(webObserveText).join(",") || "-", 48),
|
||||
@@ -9300,23 +9310,24 @@ function renderWebObserveAnalyzeTable(value: Record<string, unknown>): string {
|
||||
]) : [["-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Turn columns:",
|
||||
webObserveTable(["TURN", "PROMPT", "TRACE", "FIRST_SEQ", "LAST_SEQ", "SOURCE"], turnColumns.length > 0 ? turnColumns.map((item) => [
|
||||
webObserveTable(["TURN", "PAGE", "PROMPT", "TRACE", "FIRST_SEQ", "LAST_SEQ", "SOURCE"], turnColumns.length > 0 ? turnColumns.map((item) => [
|
||||
webObserveText(item.label),
|
||||
pageLabel(item),
|
||||
webObserveText(item.promptIndex ?? item.lastPromptIndex),
|
||||
webObserveShort(webObserveText(item.traceId), 28),
|
||||
webObserveText(item.firstSeq),
|
||||
webObserveText(item.lastSeq),
|
||||
webObserveShort(webObserveText(item.source), 24),
|
||||
]) : [["-", "-", "-", "-", "-", "-"]]),
|
||||
]) : [["-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Recent update jumps:",
|
||||
webObserveTable(["TURN", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "SAMPLE_S", "ALLOWED", "TRACE"], recentUpdateJumpRows.length > 0 ? recentUpdateJumpRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
webObserveTable(["TURN", "PAGE", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "SAMPLE_S", "ALLOWED", "TRACE"], recentUpdateJumpRows.length > 0 ? recentUpdateJumpRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Total elapsed zero resets:",
|
||||
webObserveTable(["TURN", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "TRACE"], elapsedZeroResetRows.length > 0 ? elapsedZeroResetRows : [["-", "-", "-", "-", "-", "-", "-"]]),
|
||||
webObserveTable(["TURN", "PAGE", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "TRACE"], elapsedZeroResetRows.length > 0 ? elapsedZeroResetRows : [["-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Total elapsed forward jumps:",
|
||||
webObserveTable(["TURN", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "SAMPLE_S", "ALLOWED", "TRACE"], elapsedForwardJumpRows.length > 0 ? elapsedForwardJumpRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
webObserveTable(["TURN", "PAGE", "PROMPT", "FROM_SEQ", "TO_SEQ", "VALUE", "DELTA", "SAMPLE_S", "ALLOWED", "TRACE"], elapsedForwardJumpRows.length > 0 ? elapsedForwardJumpRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Runtime alerts:",
|
||||
webObserveTable(["HTTP_ERR", "REQUEST_FAILED", "DOM_DIAG", "CONSOLE_ALERT", "PROMPT_SEGMENTS", "PROMPT_NETWORK"], [[
|
||||
|
||||
@@ -2176,7 +2176,7 @@ console.log(JSON.stringify({
|
||||
sampleMetrics: {
|
||||
...recentWindow.sampleMetrics.summary,
|
||||
rounds: recentWindow.sampleMetrics.rounds.slice(-8).map((item) => ({ promptIndex: item.promptIndex, promptTextHash: item.promptTextHash, sampleCount: item.sampleCount, firstSeq: item.firstSeq, lastSeq: item.lastSeq, lastTotalElapsedSeconds: item.lastTotalElapsedSeconds, lastRecentUpdateSeconds: item.lastRecentUpdateSeconds, loadingSamples: item.loadingSamples, maxLoadingCount: item.maxLoadingCount, loadingOwnerCount: item.loadingOwnerCount, diagnosticSamples: item.diagnosticSamples, terminalSamples: item.terminalSamples, finalTextSamples: item.finalTextSamples, turnTimingTotalElapsedZeroResetCount: item.turnTimingTotalElapsedZeroResetCount, turnTimingTotalElapsedForwardJumpCount: item.turnTimingTotalElapsedForwardJumpCount, turnTimingTotalElapsedForwardJumpMaxSeconds: item.turnTimingTotalElapsedForwardJumpMaxSeconds, turnTimingRecentUpdateJumpCount: item.turnTimingRecentUpdateJumpCount, turnTimingRecentUpdateMaxIncreaseSeconds: item.turnTimingRecentUpdateMaxIncreaseSeconds })),
|
||||
turnColumns: recentWindow.sampleMetrics.turnColumns.slice(-12).map((item) => ({ label: item.label, source: item.source, promptIndex: item.promptIndex, lastPromptIndex: item.lastPromptIndex, firstSeq: item.firstSeq, lastSeq: item.lastSeq, traceId: item.traceId, messageId: item.messageId })),
|
||||
turnColumns: recentWindow.sampleMetrics.turnColumns.slice(-12).map((item) => ({ label: item.label, source: item.source, pageRole: item.pageRole ?? null, pageId: item.pageId ?? null, promptIndex: item.promptIndex, lastPromptIndex: item.lastPromptIndex, firstSeq: item.firstSeq, lastSeq: item.lastSeq, traceId: item.traceId, messageId: item.messageId })),
|
||||
loading: compactLoadingMetricsForOutput(recentWindow.sampleMetrics.loading),
|
||||
sessionRailTitles: compactSessionRailTitleMetricsForOutput(recentWindow.sampleMetrics.sessionRailTitles),
|
||||
},
|
||||
@@ -6534,8 +6534,9 @@ function renderTurnTimingTable(sampleMetrics) {
|
||||
if (columns.length === 0 || rows.length === 0) return "- 无 turn 时间表。";
|
||||
const header = ["时间戳"];
|
||||
for (const column of columns) {
|
||||
header.push(column.label + " 总耗时(s)");
|
||||
header.push(column.label + " 最近更新(s)");
|
||||
const columnLabel = formatTurnColumnDisplayLabel(column);
|
||||
header.push(columnLabel + " 总耗时(s)");
|
||||
header.push(columnLabel + " 最近更新(s)");
|
||||
}
|
||||
const lines = [];
|
||||
lines.push("| " + header.map(escapeMarkdownCell).join(" | ") + " |");
|
||||
@@ -6549,28 +6550,28 @@ function renderTurnTimingTable(sampleMetrics) {
|
||||
}
|
||||
lines.push("| " + cells.map(escapeMarkdownCell).join(" | ") + " |");
|
||||
}
|
||||
const columnLines = columns.map((column) => "- " + column.label + ": source=" + (column.source || "-") + " prompt=" + (column.promptIndex ?? "-") + " lastPrompt=" + (column.lastPromptIndex ?? "-") + " firstSeq=" + (column.firstSeq ?? "-") + " lastSeq=" + (column.lastSeq ?? "-") + " traceId=" + (column.traceId || "-") + " messageId=" + (column.messageId || "-")).join("\n");
|
||||
const columnLines = columns.map((column) => "- " + formatTurnColumnDisplayLabel(column) + ": pageRole=" + (column.pageRole || "-") + " pageId=" + (column.pageId || "-") + " source=" + (column.source || "-") + " prompt=" + (column.promptIndex ?? "-") + " lastPrompt=" + (column.lastPromptIndex ?? "-") + " firstSeq=" + (column.firstSeq ?? "-") + " lastSeq=" + (column.lastSeq ?? "-") + " traceId=" + (column.traceId || "-") + " messageId=" + (column.messageId || "-")).join("\n");
|
||||
const nonMonotonic = Array.isArray(sampleMetrics?.turnTimingNonMonotonic) ? sampleMetrics.turnTimingNonMonotonic : [];
|
||||
const nonMonotonicLines = nonMonotonic.length > 0
|
||||
? nonMonotonic.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " " + item.metric + (item.anomaly ? " " + item.anomaly : "") + " " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? nonMonotonic.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " " + item.metric + (item.anomaly ? " " + item.anomaly : "") + " " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到总耗时下降或最近更新异常跳增。";
|
||||
const terminalGrowth = Array.isArray(sampleMetrics?.turnTimingTerminalElapsedGrowth) ? sampleMetrics.turnTimingTerminalElapsedGrowth : [];
|
||||
const terminalGrowthLines = terminalGrowth.length > 0
|
||||
? terminalGrowth.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " terminal totalElapsed growth " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " status " + (item.fromStatus || "-") + " -> " + (item.toStatus || "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? terminalGrowth.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " terminal totalElapsed growth " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " status " + (item.fromStatus || "-") + " -> " + (item.toStatus || "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到 terminal 后总耗时增长。";
|
||||
const elapsedZeroResets = Array.isArray(sampleMetrics?.turnTimingElapsedZeroResets) ? sampleMetrics.turnTimingElapsedZeroResets : [];
|
||||
const elapsedZeroResetLines = elapsedZeroResets.length > 0
|
||||
? elapsedZeroResets.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " totalElapsed zero-reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? elapsedZeroResets.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " totalElapsed zero-reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到总耗时从非零跳回 0 秒。";
|
||||
const totalElapsedForwardJumps = Array.isArray(sampleMetrics?.turnTimingTotalElapsedForwardJumps) ? sampleMetrics.turnTimingTotalElapsedForwardJumps : [];
|
||||
const totalElapsedForwardJumpLines = totalElapsedForwardJumps.length > 0
|
||||
? totalElapsedForwardJumps.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " totalElapsed forward-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? totalElapsedForwardJumps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " totalElapsed forward-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到总耗时超出采样间隔的异常前跳。";
|
||||
const sawtoothJumps = Array.isArray(sampleMetrics?.turnTimingRecentUpdateSawtoothJumps)
|
||||
? sampleMetrics.turnTimingRecentUpdateSawtoothJumps
|
||||
: nonMonotonic.filter((item) => item.metric === "recentUpdateSeconds" && item.anomaly === "jump");
|
||||
const sawtoothJumpLines = sawtoothJumps.length > 0
|
||||
? sawtoothJumps.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " recentUpdate sawtooth-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? sawtoothJumps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " recentUpdate sawtooth-jump " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到最近更新三角波异常跳增。";
|
||||
const recentUpdateSteps = Array.isArray(sampleMetrics?.turnTimingRecentUpdateLargestSteps)
|
||||
? sampleMetrics.turnTimingRecentUpdateLargestSteps
|
||||
@@ -6578,11 +6579,11 @@ function renderTurnTimingTable(sampleMetrics) {
|
||||
? sampleMetrics.turnTimingRecentUpdateSteps.filter((item) => Number.isFinite(Number(item.delta))).slice().sort((a, b) => Number(b.delta) - Number(a.delta)).slice(0, 200)
|
||||
: [];
|
||||
const stepLines = recentUpdateSteps.length > 0
|
||||
? recentUpdateSteps.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " recentUpdate step " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " excess=" + (item.excessiveIncreaseSeconds ?? 0) + " event=" + (item.event || "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? recentUpdateSteps.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " recentUpdate step " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " allowed=" + (item.allowedIncreaseSeconds ?? "-") + " excess=" + (item.excessiveIncreaseSeconds ?? 0) + " event=" + (item.event || "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到最近更新相邻采样 step。";
|
||||
const recentUpdateResets = Array.isArray(sampleMetrics?.turnTimingRecentUpdateResets) ? sampleMetrics.turnTimingRecentUpdateResets : [];
|
||||
const resetLines = recentUpdateResets.length > 0
|
||||
? recentUpdateResets.slice(0, 80).map((item) => "- " + (item.columnLabel || item.columnId || "-") + " reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
? recentUpdateResets.slice(0, 80).map((item) => "- " + formatTurnEventDisplayLabel(item) + " reset " + (item.fromValue ?? "-") + " -> " + (item.toValue ?? "-") + " delta=" + (item.delta ?? "-") + " sampleDelta=" + (item.sampleDeltaSeconds ?? "-") + " seq " + (item.fromSeq ?? "-") + " -> " + (item.toSeq ?? "-") + " ts " + (item.fromTs || "-") + " -> " + (item.toTs || "-") + " traceId=" + (item.traceId || "-")).join("\n")
|
||||
: "- 未观察到最近更新归零/回落。";
|
||||
const disclosureLine = disclosure?.truncated
|
||||
? "表格披露:已按 head/tail 有界输出,totalRows=" + disclosure.totalRows + " includedRows=" + disclosure.includedRows + " omittedRows=" + disclosure.omittedRows + ";异常计数在截断前基于全量采样计算。"
|
||||
@@ -6590,6 +6591,27 @@ function renderTurnTimingTable(sampleMetrics) {
|
||||
return disclosureLine + "\n\n" + lines.join("\n") + "\n\n列说明:\n" + columnLines + "\n\n异常事件(仅报表暴露,不做下游 repair;最近更新按三角波模型检测异常跳增):\n" + nonMonotonicLines + "\n\nTerminal 后总耗时增长事件(终态 turn 的总耗时应 sealed,不应继续增长):\n" + terminalGrowthLines + "\n\n总耗时归零跳变事件(例如已显示真实耗时后又变成 0 秒):\n" + elapsedZeroResetLines + "\n\n总耗时异常前跳事件(预期按采样间隔近似递增;例如 14 秒 -> 1137 秒应被列入这里):\n" + totalElapsedForwardJumpLines + "\n\n最近更新 sawtooth jump 事件(预期每秒增长约 1,遇到新活动归零;例如 1 秒 -> 1 分 4 秒应被列入这里):\n" + sawtoothJumpLines + "\n\n最近更新相邻采样 step(按 delta 降序;用于人工识别一秒跳几十秒/一分钟的瞬态):\n" + stepLines + "\n\n最近更新 reset 事件(预期三角波归零,不计为异常):\n" + resetLines;
|
||||
}
|
||||
|
||||
function formatTurnColumnDisplayLabel(column) {
|
||||
const base = String(column?.label || column?.id || "-");
|
||||
const role = String(column?.pageRole || "unknown");
|
||||
const pageId = compactPageId(column?.pageId);
|
||||
return pageId ? base + "@" + role + "/" + pageId : base + "@" + role;
|
||||
}
|
||||
|
||||
function formatTurnEventDisplayLabel(item) {
|
||||
const base = String(item?.columnLabel || item?.columnId || "-");
|
||||
const role = String(item?.pageRole || "unknown");
|
||||
const pageId = compactPageId(item?.pageId);
|
||||
return pageId ? base + "@" + role + "/" + pageId : base + "@" + role;
|
||||
}
|
||||
|
||||
function compactPageId(value) {
|
||||
if (value === null || value === undefined || value === "") return "";
|
||||
const text = String(value);
|
||||
if (text.length <= 18) return text;
|
||||
return text.slice(0, 12) + ".." + text.slice(-4);
|
||||
}
|
||||
|
||||
function formatMetricCell(value) {
|
||||
if (value === null || value === undefined || !Number.isFinite(Number(value))) return "-";
|
||||
return String(Number(value));
|
||||
|
||||
Reference in New Issue
Block a user