fix(web-probe): scope round timing to prompt turns (#769)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-24 03:26:12 +08:00
committed by GitHub
parent b5e66b77f3
commit 382d345a3e
@@ -3983,6 +3983,8 @@ function buildSampleMetrics(samples, control) {
const loading = buildLoadingMetrics(samples, timeline);
const sessionRailTitles = buildSessionRailTitleMetrics(samples, timeline);
const rounds = buildRoundMetricSummaries(timeline, promptCommands, {
columns: turnTiming.columns,
rows: turnTiming.rows,
nonMonotonic: turnTimingNonMonotonic,
elapsedZeroResets: turnTimingElapsedZeroResets,
totalElapsedForwardJumps: turnTimingTotalElapsedForwardJumps,
@@ -5757,6 +5759,8 @@ function firstTraceId(texts) {
function buildRoundMetricSummaries(timeline, promptCommands, timing = {}) {
const rounds = [];
const timingColumns = Array.isArray(timing.columns) ? timing.columns : [];
const timingRows = Array.isArray(timing.rows) ? timing.rows : [];
const nonMonotonic = Array.isArray(timing.nonMonotonic) ? timing.nonMonotonic : [];
const totalElapsedForwardJumps = Array.isArray(timing.totalElapsedForwardJumps) ? timing.totalElapsedForwardJumps : [];
const elapsedZeroResets = Array.isArray(timing.elapsedZeroResets) ? timing.elapsedZeroResets : [];
@@ -5766,8 +5770,14 @@ function buildRoundMetricSummaries(timeline, promptCommands, timing = {}) {
for (let index = 0; index < promptCommands.length; index += 1) {
const promptIndex = index + 1;
const items = timeline.filter((item) => item.promptIndex === promptIndex);
const totalElapsed = items.map((item) => item.totalElapsedSeconds).filter((value) => value !== null);
const recentUpdate = items.map((item) => item.recentUpdateSeconds).filter((value) => value !== null);
const aggregateTotalElapsed = items.map((item) => item.totalElapsedSeconds).filter((value) => value !== null);
const aggregateRecentUpdate = items.map((item) => item.recentUpdateSeconds).filter((value) => value !== null);
const promptTurnTiming = roundPromptTurnTimingValues(timingRows, timingColumns, promptIndex, {
firstSeq: items[0]?.seq ?? null,
firstSampleAt: items[0]?.ts ?? null
});
const totalElapsed = promptTurnTiming.totalElapsed.length > 0 ? promptTurnTiming.totalElapsed : aggregateTotalElapsed;
const recentUpdate = promptTurnTiming.recentUpdate.length > 0 ? promptTurnTiming.recentUpdate : aggregateRecentUpdate;
const loadingCounts = items.map((item) => Number(item.loadingCount ?? 0)).filter(Number.isFinite);
const loadingOwners = new Set();
for (const item of items) {
@@ -5801,9 +5811,9 @@ function buildRoundMetricSummaries(timeline, promptCommands, timing = {}) {
maxLoadingCount: loadingCounts.length > 0 ? Math.max(...loadingCounts) : 0,
loadingOwnerCount: loadingOwners.size,
maxTotalElapsedSeconds: totalElapsed.length > 0 ? Math.max(...totalElapsed) : null,
lastTotalElapsedSeconds: lastNonNull(items.map((item) => item.totalElapsedSeconds)),
lastTotalElapsedSeconds: lastNonNull(totalElapsed),
maxRecentUpdateSeconds: recentUpdate.length > 0 ? Math.max(...recentUpdate) : null,
lastRecentUpdateSeconds: lastNonNull(items.map((item) => item.recentUpdateSeconds)),
lastRecentUpdateSeconds: lastNonNull(recentUpdate),
diagnosticSamples: items.filter((item) => item.diagnosticSeen).length,
terminalSamples: items.filter((item) => item.terminalSeen).length,
finalTextSamples: items.filter((item) => item.finalResultTextSeen).length,
@@ -5826,6 +5836,38 @@ function buildRoundMetricSummaries(timeline, promptCommands, timing = {}) {
return rounds;
}
function roundPromptTurnTimingValues(rows, columns, promptIndex, round = {}) {
const roundFirstSeq = Number(round.firstSeq);
const roundFirstMs = Date.parse(String(round.firstSampleAt ?? ""));
const seqSlack = 3;
const timeSlackMs = 3000;
const promptColumnIds = new Set(columns
.filter((column) => {
if (Number(column?.promptIndex) === Number(promptIndex)) return true;
const firstSeq = Number(column?.firstSeq);
if (Number.isFinite(roundFirstSeq) && Number.isFinite(firstSeq) && firstSeq >= roundFirstSeq - seqSlack) return true;
const firstMs = Date.parse(String(column?.firstTs ?? ""));
return Number.isFinite(roundFirstMs) && Number.isFinite(firstMs) && firstMs >= roundFirstMs - timeSlackMs;
})
.map((column) => String(column?.id || ""))
.filter(Boolean));
if (promptColumnIds.size === 0) return { totalElapsed: [], recentUpdate: [] };
const totalElapsed = [];
const recentUpdate = [];
for (const row of rows) {
if (Number(row?.promptIndex ?? 0) !== Number(promptIndex)) continue;
const cells = row?.cells && typeof row.cells === "object" ? row.cells : {};
for (const [columnId, cell] of Object.entries(cells)) {
if (!promptColumnIds.has(columnId)) continue;
const total = Number(cell?.totalElapsedSeconds);
if (Number.isFinite(total)) totalElapsed.push(total);
const recent = Number(cell?.recentUpdateSeconds);
if (Number.isFinite(recent)) recentUpdate.push(recent);
}
}
return { totalElapsed, recentUpdate };
}
function sampleTexts(sample) {
const rows = [];
for (const group of [sample?.messages, sample?.traceRows, sample?.diagnostics]) {