fix: preserve natural final response markdown

This commit is contained in:
Codex Agent
2026-06-06 00:58:31 +08:00
parent 02c55ede3e
commit faad89fc6f
3 changed files with 116 additions and 3 deletions
+50 -2
View File
@@ -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>"