fix: bind web-probe turn timing to stable ids (#571)

Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
Lyon
2026-06-21 13:44:22 +08:00
committed by GitHub
parent e3dd4b6409
commit f99e9fbd88
@@ -428,13 +428,21 @@ async function createSessionFromUi() {
return Boolean(activeTab && sessionId && sessionId !== initial.sessionId && input && !input.disabled && !warning);
}, { sessionId: before?.activeSessionId || "" }, { timeout: 30000 }).catch(() => null);
const after = await workbenchSessionSnapshot();
const beforeSessionId = before?.activeSessionId || before?.routeSessionId || "";
const afterSessionId = after?.activeSessionId || after?.routeSessionId || "";
const ok = Boolean(afterSessionId && afterSessionId !== beforeSessionId && after?.composerReady);
if (!ok) {
const error = new Error("newSession did not create or select a different workbench session");
error.details = { beforeUrl, afterUrl: currentPageUrl(), before, after, pageId, valuesRedacted: true };
throw error;
}
return {
beforeUrl,
afterUrl: currentPageUrl(),
ok: Boolean(after?.activeSessionId && after.activeSessionId !== before?.activeSessionId),
ok,
before,
after,
sessionId: after?.activeSessionId || null,
sessionId: afterSessionId || null,
pageId
};
}
@@ -702,6 +710,10 @@ async function samplePage(reason) {
testId: element.getAttribute("data-testid"),
role: element.getAttribute("role"),
status: element.getAttribute("data-status") || element.getAttribute("aria-busy") || null,
sessionId: element.getAttribute("data-session-id") || null,
messageId: element.getAttribute("data-message-id") || element.getAttribute("id") || null,
traceId: element.getAttribute("data-trace-id") || null,
turnId: element.getAttribute("data-turn-id") || null,
text: textHashInput(element),
rect: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },
};
@@ -747,16 +759,19 @@ async function samplePage(reason) {
const turns = Array.from(document.querySelectorAll('article.message-card[data-role="agent"], .message-card[data-role="agent"], article[data-role="agent"]')).filter(visible).map((element, index) => {
const rect = element.getBoundingClientRect();
const text = textHashInput(element);
const traceElement = element.querySelector("[data-trace-id]");
const traceElement = element.matches("[data-trace-id]") ? element : element.querySelector("[data-trace-id]");
const traceMatch = text.match(/\btrc_[A-Za-z0-9_-]+\b/u);
const durationText = trim(element.querySelector(".message-duration-meta")?.textContent || "", 120);
const activityText = trim(element.querySelector(".message-activity-meta")?.textContent || "", 120);
const directTraceId = element.getAttribute("data-trace-id") || traceElement?.getAttribute("data-trace-id") || traceMatch?.[0] || null;
return {
index,
role: element.getAttribute("data-role") || "agent",
status: element.getAttribute("data-status") || null,
sessionId: element.getAttribute("data-session-id") || null,
messageId: element.getAttribute("data-message-id") || element.getAttribute("id") || null,
traceId: traceElement?.getAttribute("data-trace-id") || traceMatch?.[0] || null,
traceId: directTraceId,
turnId: element.getAttribute("data-turn-id") || directTraceId,
durationText,
activityText,
text,
@@ -2059,14 +2074,19 @@ function turnMetricItems(sample, timelineItem) {
const recentUpdateValues = texts.flatMap(parseRecentUpdateSeconds).filter(Number.isFinite);
const traceId = turn.traceId || firstTraceId(texts);
const messageId = turn.messageId || null;
const turnId = turn.turnId || traceId || null;
const stableId = traceId || messageId || turnId || null;
const domIndex = Number.isFinite(Number(turn.index)) ? Number(turn.index) : items.length;
const key = "turn:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex);
const key = stableId
? "turn:" + sessionKey + ":id-" + stableId
: "turn:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex);
items.push({
key,
source: "turn",
promptIndex,
traceId,
messageId,
turnId,
domIndex,
status: turn.status ?? null,
totalElapsedSeconds: totalElapsedValues.length > 0 ? Math.max(...totalElapsedValues) : null,
@@ -2083,12 +2103,18 @@ function turnMetricItems(sample, timelineItem) {
const recentUpdateValues = parseRecentUpdateSeconds(text).filter(Number.isFinite);
if (totalElapsedValues.length === 0 && recentUpdateValues.length === 0) continue;
const domIndex = Number.isFinite(Number(message.index)) ? Number(message.index) : items.length;
const traceId = message.traceId || firstTraceId([text]);
const messageId = message.messageId || null;
const stableId = traceId || messageId || message.turnId || null;
items.push({
key: "message:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex),
key: stableId
? "message:" + sessionKey + ":id-" + stableId
: "message:" + sessionKey + ":round-" + roundKey + ":dom-index-" + String(domIndex),
source: "message",
promptIndex,
traceId: firstTraceId([text]),
messageId: null,
traceId,
messageId,
turnId: message.turnId || traceId || null,
domIndex,
status: message.status ?? null,
totalElapsedSeconds: totalElapsedValues.length > 0 ? Math.max(...totalElapsedValues) : null,