fix: preserve natural final response markdown
This commit is contained in:
@@ -48,6 +48,7 @@ export function parseProbeArgs(argv) {
|
||||
projectId: process.env.HWLAB_WEB_PROBE_PROJECT_ID ?? "prj_hwpod_workbench",
|
||||
conversationId: process.env.HWLAB_WEB_PROBE_CONVERSATION_ID ?? "",
|
||||
waitMessagesMs: 2500,
|
||||
waitAgentTerminalMs: Number(process.env.HWLAB_WEB_PROBE_WAIT_AGENT_TERMINAL_MS ?? "0"),
|
||||
reportPath: tempReportPath("web-live-dom-probe.json"),
|
||||
screenshotPath: tempReportPath("web-live-dom-probe.png"),
|
||||
jobId: ""
|
||||
@@ -75,6 +76,7 @@ export function parseProbeArgs(argv) {
|
||||
else if (arg === "--job-id" || arg.startsWith("--job-id=")) args.jobId = readValue("--job-id");
|
||||
else if (arg === "--wait-after-submit-ms" || arg.startsWith("--wait-after-submit-ms=")) args.waitAfterSubmitMs = positiveInteger(readValue("--wait-after-submit-ms"), "--wait-after-submit-ms");
|
||||
else if (arg === "--wait-messages-ms" || arg.startsWith("--wait-messages-ms=")) args.waitMessagesMs = positiveInteger(readValue("--wait-messages-ms"), "--wait-messages-ms");
|
||||
else if (arg === "--wait-agent-terminal-ms" || arg.startsWith("--wait-agent-terminal-ms=")) args.waitAgentTerminalMs = positiveInteger(readValue("--wait-agent-terminal-ms"), "--wait-agent-terminal-ms");
|
||||
else if (arg === "--timeout-ms" || arg.startsWith("--timeout-ms=")) args.timeoutMs = positiveInteger(readValue("--timeout-ms"), "--timeout-ms");
|
||||
else if (arg === "--fresh-session") args.freshSession = true;
|
||||
else if (arg === "--no-cancel-running") args.cancelRunning = false;
|
||||
@@ -105,6 +107,7 @@ export async function runProbe(args) {
|
||||
if (args.conversationId) await selectConversationInBrowserSession(page, args, actions);
|
||||
if (args.freshSession) await createFreshSession(page, args, actions);
|
||||
if (args.message) await submitPrompt(page, args, actions);
|
||||
if (args.waitAgentTerminalMs) await waitForAgentTerminal(page, args, actions);
|
||||
await waitForMessageCards(page, args, actions);
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
const dom = await collectDomEvidence(page);
|
||||
@@ -171,7 +174,8 @@ async function startProbe(args) {
|
||||
"--report", reportPath,
|
||||
"--screenshot", screenshotPath,
|
||||
"--timeout-ms", String(args.timeoutMs),
|
||||
"--wait-after-submit-ms", String(args.waitAfterSubmitMs)
|
||||
"--wait-after-submit-ms", String(args.waitAfterSubmitMs),
|
||||
"--wait-agent-terminal-ms", String(args.waitAgentTerminalMs)
|
||||
];
|
||||
if (args.freshSession) childArgs.push("--fresh-session");
|
||||
if (!args.cancelRunning) childArgs.push("--no-cancel-running");
|
||||
@@ -451,6 +455,37 @@ async function waitForMessageCards(page, args, actions) {
|
||||
actions.push({ action: "wait-message-cards", before, after, found: Boolean(found), timeoutMs: args.waitMessagesMs });
|
||||
}
|
||||
|
||||
async function waitForAgentTerminal(page, args, actions) {
|
||||
const timeoutMs = Math.min(args.waitAgentTerminalMs, args.timeoutMs);
|
||||
const before = await collectLatestAgentMessageState(page);
|
||||
const terminal = await page.waitForFunction(() => {
|
||||
const cards = [...document.querySelectorAll(".message-card")];
|
||||
const latestAgent = [...cards].reverse().find((card) => card.getAttribute("data-message-role") === "agent" || card.classList.contains("message-agent"));
|
||||
if (!latestAgent) return false;
|
||||
const status = latestAgent.getAttribute("data-message-status") ?? "";
|
||||
const finalResponse = latestAgent.querySelector(".message-final-response");
|
||||
const text = finalResponse?.textContent?.trim() ?? "";
|
||||
return status && status !== "running" && text.length > 0;
|
||||
}, null, { timeout: timeoutMs }).catch(() => null);
|
||||
const after = await collectLatestAgentMessageState(page);
|
||||
actions.push({ action: "wait-agent-terminal", terminal: Boolean(terminal), timeoutMs, before, after });
|
||||
if (!terminal) throw new Error(`agent final response did not reach terminal DOM state: ${JSON.stringify({ before, after, timeoutMs })}`);
|
||||
}
|
||||
|
||||
async function collectLatestAgentMessageState(page) {
|
||||
return page.evaluate(() => {
|
||||
const cards = [...document.querySelectorAll(".message-card")];
|
||||
const latestAgent = [...cards].reverse().find((card) => card.getAttribute("data-message-role") === "agent" || card.classList.contains("message-agent"));
|
||||
const finalResponse = latestAgent?.querySelector(".message-final-response");
|
||||
return {
|
||||
messageCount: cards.length,
|
||||
status: latestAgent?.getAttribute("data-message-status") ?? null,
|
||||
textChars: finalResponse?.textContent?.trim().length ?? 0,
|
||||
textPreview: (finalResponse?.textContent ?? "").replace(/\s+/gu, " ").trim().slice(0, 240)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async function collectDomEvidence(page) {
|
||||
return page.evaluate(() => {
|
||||
const workspace = document.querySelector("#workspace");
|
||||
@@ -483,6 +518,7 @@ async function collectDomEvidence(page) {
|
||||
const finalStyle = finalResponse ? getComputedStyle(finalResponse) : null;
|
||||
const traceRect = traceEvents?.getBoundingClientRect();
|
||||
const finalRect = finalResponse?.getBoundingClientRect();
|
||||
const finalBody = finalResponse?.querySelector(".message-body");
|
||||
return {
|
||||
status: card.getAttribute("data-message-status") ?? null,
|
||||
role: card.getAttribute("data-message-role") ?? [...card.classList].find((item) => item === "message-user" || item === "message-agent" || item === "message-system")?.replace(/^message-/, "") ?? null,
|
||||
@@ -502,7 +538,18 @@ async function collectDomEvidence(page) {
|
||||
maxHeight: finalStyle?.maxHeight ?? null,
|
||||
overflowY: finalStyle?.overflowY ?? null,
|
||||
height: finalRect ? Math.round(finalRect.height) : null,
|
||||
scrollHeight: Math.round(finalResponse.scrollHeight)
|
||||
scrollHeight: Math.round(finalResponse.scrollHeight),
|
||||
textChars: finalResponse.textContent?.trim().length ?? 0,
|
||||
textPreview: (finalResponse.textContent ?? "").replace(/\s+/gu, " ").trim().slice(0, 500),
|
||||
markdown: finalBody ? {
|
||||
paragraphs: finalBody.querySelectorAll("p").length,
|
||||
headings: finalBody.querySelectorAll("h1,h2,h3,h4,h5,h6").length,
|
||||
lists: finalBody.querySelectorAll("ul,ol").length,
|
||||
listItems: finalBody.querySelectorAll("li").length,
|
||||
codeBlocks: finalBody.querySelectorAll("pre code").length,
|
||||
inlineCode: finalBody.querySelectorAll("p code,li code").length,
|
||||
tables: finalBody.querySelectorAll("table").length
|
||||
} : null
|
||||
} : { present: false }
|
||||
};
|
||||
}),
|
||||
@@ -546,6 +593,7 @@ function helpPayload() {
|
||||
command: "web-live-dom-probe",
|
||||
usage: [
|
||||
"node scripts/web-live-dom-probe.mjs run --url http://74.48.78.17:19666/ --fresh-session --report /tmp/hwlab-dev-gate/web-live-dom-probe.json",
|
||||
"node scripts/web-live-dom-probe.mjs start --url http://74.48.78.17:19666/ --fresh-session --message '...' --no-cancel-running --wait-agent-terminal-ms 180000",
|
||||
"node scripts/web-live-dom-probe.mjs run --url http://74.48.78.17:19666/#/workspace --conversation-id cnv_...",
|
||||
"node scripts/web-live-dom-probe.mjs start --url http://74.48.78.17:19666/ --fresh-session",
|
||||
"node scripts/web-live-dom-probe.mjs status <jobId>"
|
||||
|
||||
Reference in New Issue
Block a user