feat: add workbench triad sentinel check
This commit is contained in:
@@ -4580,12 +4580,20 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
seen.add(key);
|
||||
const rect = element.getBoundingClientRect();
|
||||
const fallbackTitle = looksLikeSessionTitleFallback(titleText, sessionId);
|
||||
const dataStatus = element.getAttribute("data-status") || element.getAttribute("data-state") || null;
|
||||
const dataRunning = element.getAttribute("data-running") || element.getAttribute("data-busy") || null;
|
||||
const ariaBusy = element.getAttribute("aria-busy") || null;
|
||||
items.push({
|
||||
index: items.length,
|
||||
tag: element.tagName.toLowerCase(),
|
||||
testId: element.getAttribute("data-testid"),
|
||||
role: element.getAttribute("role"),
|
||||
active: element.getAttribute("data-active") === "true" || element.getAttribute("aria-selected") === "true",
|
||||
status: dataStatus || ariaBusy || null,
|
||||
dataStatus,
|
||||
running: dataRunning === "true" || ariaBusy === "true" || element.classList.contains("is-running") || element.classList.contains("running"),
|
||||
dataRunning,
|
||||
ariaBusy,
|
||||
sessionId,
|
||||
sessionIdPrefix: sessionId ? String(sessionId).slice(0, 12) : null,
|
||||
titleText,
|
||||
@@ -4601,6 +4609,7 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
visibleCount,
|
||||
fallbackTitleCount,
|
||||
fallbackTitleRatio: visibleCount > 0 ? Number((fallbackTitleCount / visibleCount).toFixed(4)) : 0,
|
||||
activeItem: visibleItems.find((item) => item.active) || null,
|
||||
items: visibleItems.slice(0, 60),
|
||||
fallbackItems: fallbackItems.slice(0, 12),
|
||||
};
|
||||
@@ -4637,7 +4646,7 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
const title = element.getAttribute("title") || "";
|
||||
return tag === "button" || role === "button" || /诊断/u.test(aria) || /诊断/u.test(title);
|
||||
};
|
||||
const stableMessageText = (element) => {
|
||||
const messageBodyTextDetail = (element) => {
|
||||
const bodySelectors = [
|
||||
".message-markdown.message-text",
|
||||
".message-text",
|
||||
@@ -4651,10 +4660,21 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
for (const candidate of Array.from(element.querySelectorAll(selector))) {
|
||||
if (!visible(candidate)) continue;
|
||||
const text = trim(candidate.textContent || "", 1200);
|
||||
if (text && !parts.includes(text)) parts.push(text);
|
||||
if (text && !parts.some((part) => part.text === text)) parts.push({ text, selector });
|
||||
}
|
||||
}
|
||||
if (parts.length > 0) return parts.join(" ");
|
||||
if (parts.length > 0) {
|
||||
return {
|
||||
text: parts.map((part) => part.text).join(" "),
|
||||
source: parts[0]?.selector || "body-selector",
|
||||
candidateCount: parts.length
|
||||
};
|
||||
}
|
||||
return { text: "", source: null, candidateCount: 0 };
|
||||
};
|
||||
const stableMessageText = (element) => {
|
||||
const body = messageBodyTextDetail(element);
|
||||
if (body.text) return body.text;
|
||||
const clone = element.cloneNode(true);
|
||||
for (const selector of [
|
||||
".message-duration-meta",
|
||||
@@ -4715,6 +4735,7 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
const summarize = (selector, limit) => summarizeElements(Array.from(document.querySelectorAll(selector)), limit);
|
||||
const summarizeMessages = (selector, limit) => Array.from(document.querySelectorAll(selector)).filter(visible).slice(-limit).map((element, index) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const body = messageBodyTextDetail(element);
|
||||
return {
|
||||
index,
|
||||
tag: element.tagName.toLowerCase(),
|
||||
@@ -4728,6 +4749,9 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
turnId: element.getAttribute("data-turn-id") || null,
|
||||
durationText: trim(element.querySelector(".message-duration-meta")?.textContent || "", 120),
|
||||
activityText: trim(element.querySelector(".message-activity-meta")?.textContent || "", 120),
|
||||
bodyText: body.text,
|
||||
bodyTextSource: body.source,
|
||||
bodyTextCandidateCount: body.candidateCount,
|
||||
text: stableMessageText(element),
|
||||
rect: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },
|
||||
};
|
||||
@@ -4914,6 +4938,7 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
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 finalResponse = messageBodyTextDetail(element);
|
||||
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);
|
||||
@@ -4929,6 +4954,10 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
turnId: element.getAttribute("data-turn-id") || directTraceId,
|
||||
durationText,
|
||||
activityText,
|
||||
finalResponseText: finalResponse.text,
|
||||
finalResponseTextSource: finalResponse.source,
|
||||
finalResponseCandidateCount: finalResponse.candidateCount,
|
||||
finalResponsePresent: Boolean(finalResponse.text && finalResponse.text.trim()),
|
||||
text,
|
||||
rect: { x: Math.round(rect.x), y: Math.round(rect.y), width: Math.round(rect.width), height: Math.round(rect.height) },
|
||||
};
|
||||
@@ -5014,12 +5043,12 @@ async function sampleOnePage(targetPage, { reason, groupSeq, pageRole, targetPag
|
||||
|
||||
function digestDom(dom, pageRole = "control") {
|
||||
if (dom && dom.error) return dom;
|
||||
const messages = Array.isArray(dom.messages) ? dom.messages.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 160), textBytes: Buffer.byteLength(item.text || "") })) : [];
|
||||
const messages = Array.isArray(dom.messages) ? dom.messages.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 160), textBytes: Buffer.byteLength(item.text || ""), bodyTextHash: sha256Text(item.bodyText || ""), bodyTextPreview: truncate(item.bodyText || "", 160), bodyTextBytes: Buffer.byteLength(item.bodyText || ""), bodyTextPresent: Boolean(String(item.bodyText || "").trim()) })) : [];
|
||||
const traceRows = Array.isArray(dom.traceRows) ? dom.traceRows.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 160), textBytes: Buffer.byteLength(item.text || "") })) : [];
|
||||
const loadings = Array.isArray(dom.loadings) ? dom.loadings.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 160), textBytes: Buffer.byteLength(item.text || ""), ownerTextHash: sha256Text(item.ownerText || ""), ownerTextPreview: truncate(item.ownerText || "", 160) })) : [];
|
||||
const sessionRail = digestSessionRail(dom.sessionRail);
|
||||
const diagnostics = Array.isArray(dom.diagnostics) ? dom.diagnostics.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 260), textBytes: Buffer.byteLength(item.text || "") })) : [];
|
||||
const turns = Array.isArray(dom.turns) ? dom.turns.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 200), textBytes: Buffer.byteLength(item.text || "") })) : [];
|
||||
const turns = Array.isArray(dom.turns) ? dom.turns.map((item) => ({ ...item, textHash: sha256Text(item.text || ""), textPreview: truncate(item.text || "", 200), textBytes: Buffer.byteLength(item.text || ""), finalResponseTextHash: sha256Text(item.finalResponseText || ""), finalResponseTextPreview: truncate(item.finalResponseText || "", 200), finalResponseTextBytes: Buffer.byteLength(item.finalResponseText || ""), finalResponsePresent: Boolean(String(item.finalResponseText || "").trim()) })) : [];
|
||||
const projectManagementSample = digestProjectManagement(dom.projectManagement);
|
||||
const pageProvenance = normalizePageProvenance(dom.pageProvenance, { reason: "sample", pageLoadSeq: currentPageProvenance?.pageLoadSeq ?? pageLoadSeq });
|
||||
if (pageRole === "control") currentPageProvenance = pageProvenance;
|
||||
@@ -5112,6 +5141,11 @@ function digestSessionRail(value) {
|
||||
testId: item?.testId ?? null,
|
||||
role: item?.role ?? null,
|
||||
active: item?.active === true,
|
||||
status: item?.status ?? null,
|
||||
dataStatus: item?.dataStatus ?? null,
|
||||
running: item?.running === true,
|
||||
dataRunning: item?.dataRunning ?? null,
|
||||
ariaBusy: item?.ariaBusy ?? null,
|
||||
sessionId: item?.sessionId ?? null,
|
||||
sessionIdPrefix: item?.sessionIdPrefix ?? (item?.sessionId ? String(item.sessionId).slice(0, 12) : null),
|
||||
fallbackTitle: item?.fallbackTitle === true,
|
||||
@@ -5128,6 +5162,7 @@ function digestSessionRail(value) {
|
||||
visibleCount: Number.isFinite(visibleCount) ? visibleCount : items.length,
|
||||
fallbackTitleCount: Number.isFinite(fallbackTitleCount) ? fallbackTitleCount : fallbackItems.length,
|
||||
fallbackTitleRatio: Number.isFinite(Number(value.fallbackTitleRatio)) ? Number(value.fallbackTitleRatio) : (items.length > 0 ? Number((fallbackItems.length / items.length).toFixed(4)) : 0),
|
||||
activeItem: items.find((item) => item.active) || null,
|
||||
items,
|
||||
fallbackItems,
|
||||
valuesRedacted: true,
|
||||
|
||||
Reference in New Issue
Block a user