fix: prefer terminal markdown final response
This commit is contained in:
@@ -111,9 +111,10 @@ export async function runProbe(args) {
|
||||
await waitForMessageCards(page, args, actions);
|
||||
await page.screenshot({ path: screenshotPath, fullPage: true });
|
||||
const dom = await collectDomEvidence(page);
|
||||
const promptValidation = validatePromptFinalResponse(dom, args);
|
||||
result = {
|
||||
ok: true,
|
||||
status: dom.requiredSelectors.workspace && dom.requiredSelectors.commandInput && dom.requiredSelectors.conversationList ? "pass" : "blocked",
|
||||
status: dom.requiredSelectors.workspace && dom.requiredSelectors.commandInput && dom.requiredSelectors.conversationList && promptValidation.ok ? "pass" : "blocked",
|
||||
command: "web-live-dom-probe run",
|
||||
generatedAt: new Date().toISOString(),
|
||||
startedAt,
|
||||
@@ -123,6 +124,7 @@ export async function runProbe(args) {
|
||||
browser: browser.hwlabLaunchPlan ?? null,
|
||||
actions,
|
||||
dom,
|
||||
promptValidation,
|
||||
artifacts: { reportPath, screenshotPath },
|
||||
safety: {
|
||||
repoOwnedLauncher: true,
|
||||
@@ -155,6 +157,32 @@ export async function runProbe(args) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function validatePromptFinalResponse(dom, args) {
|
||||
if (!args.message) return { ok: true, applicable: false, reason: "no-prompt-submitted" };
|
||||
const messages = Array.isArray(dom.messages) ? dom.messages : [];
|
||||
const latestAgent = [...messages].reverse().find((message) => message.role === "agent");
|
||||
const finalResponse = latestAgent?.finalResponse ?? null;
|
||||
const markdown = finalResponse?.markdown ?? null;
|
||||
const failures = [];
|
||||
if (!latestAgent) failures.push("agent-message-missing");
|
||||
if (latestAgent?.status !== "completed") failures.push("agent-not-completed");
|
||||
if (finalResponse?.present !== true) failures.push("final-response-missing");
|
||||
if (!finalResponse || Number(finalResponse.textChars ?? 0) <= 0) failures.push("final-response-empty");
|
||||
if (Number(markdown?.headings ?? 0) <= 0) failures.push("markdown-heading-missing");
|
||||
if (Number(markdown?.lists ?? 0) <= 0 || Number(markdown?.listItems ?? 0) <= 0) failures.push("markdown-list-missing");
|
||||
if (Number(markdown?.codeBlocks ?? 0) <= 0) failures.push("markdown-code-block-missing");
|
||||
return {
|
||||
ok: failures.length === 0,
|
||||
applicable: true,
|
||||
failures,
|
||||
finalResponse: finalResponse ? {
|
||||
textChars: finalResponse.textChars ?? null,
|
||||
textPreview: finalResponse.textPreview ?? null,
|
||||
markdown: finalResponse.markdown ?? null
|
||||
} : null
|
||||
};
|
||||
}
|
||||
|
||||
async function startProbe(args) {
|
||||
await mkdir(stateRoot, { recursive: true });
|
||||
const jobId = args.jobId || `web-live-dom-probe-${Date.now()}-${process.pid}`;
|
||||
|
||||
@@ -72,6 +72,28 @@ test("mergeTraceResults uses final assistant authority instead of later progress
|
||||
assert.doesNotMatch(merged.assistantText ?? "", / --- ## hwpod-spec 机制说明 ###/u);
|
||||
});
|
||||
|
||||
test("mergeTraceResults prefers terminal result markdown over non-final flattened trace snapshots", () => {
|
||||
const resultMarkdown = "ISSUE959_MARKDOWN_OK\n\n## hwpod-spec 机制说明\n\n- 第一条\n- 第二条\n\n```bash\nhwpod inspect --dry-run\n```";
|
||||
const flattenedTrace = "I'll read context first.ISSUE959_MARKDOWN_OK ## hwpod-spec 机制说明 - 第一条 - 第二条 ```bash hwpod inspect --dry-run ```";
|
||||
const terminal: AgentChatResultResponse = {
|
||||
status: "completed",
|
||||
traceId: "trc_issue959_real_payload",
|
||||
reply: { role: "assistant", content: resultMarkdown }
|
||||
};
|
||||
const events: TraceEvent[] = [
|
||||
{ seq: 31, label: "agentrun:assistant:message", type: "assistant", status: "running", message: flattenedTrace },
|
||||
{ seq: 36, label: "agentrun:assistant:message", type: "assistant", status: "running", message: flattenedTrace },
|
||||
{ seq: 42, label: "agentrun:result:completed", type: "result", status: "completed", terminal: true, message: "AgentRun result is ready for HWLAB short-connection polling." }
|
||||
];
|
||||
const trace: TraceSnapshot = { traceId: "trc_issue959_real_payload", status: "completed", events, eventCount: events.length, lastEventLabel: "agentrun:result:completed" };
|
||||
|
||||
const merged = mergeTraceResults(terminal, trace);
|
||||
|
||||
assert.equal(merged.assistantText, resultMarkdown);
|
||||
assert.match(merged.assistantText ?? "", /ISSUE959_MARKDOWN_OK\n\n## hwpod-spec/u);
|
||||
assert.doesNotMatch(merged.assistantText ?? "", /^I'll read context first/u);
|
||||
});
|
||||
|
||||
test("mergeTraceResults prefers persisted finalResponse text for expired or compact natural traces", () => {
|
||||
const finalMarkdown = "**结论**\n\n- 自然结束和刷新后都应该显示这一段。\n- Markdown 换行必须保留。";
|
||||
const terminal: AgentChatResultResponse = {
|
||||
|
||||
@@ -97,7 +97,10 @@ export function mergeTraceResults(terminal: AgentChatResultResponse, trace: Trac
|
||||
const terminalRunnerEvents = Array.isArray(terminalRunnerTrace?.events) ? terminalRunnerTrace.events : [];
|
||||
const events = longestTraceEvents(traceEvents, terminalEvents, terminalRunnerEvents);
|
||||
const mergedTrace = { ...trace, events, eventCount: trace.eventCount ?? events.length };
|
||||
const assistantText = finalResponseText(trace.finalResponse) ?? assistantTextFromTraceEvents(events) ?? firstNonEmptyResultText(terminal);
|
||||
const assistantText = finalResponseText(trace.finalResponse)
|
||||
?? terminalAssistantTextFromTraceEvents(events)
|
||||
?? firstNonEmptyResultText(terminal)
|
||||
?? assistantTextFromTraceEvents(events);
|
||||
return {
|
||||
...terminal,
|
||||
traceId: trace.traceId ?? terminal.traceId,
|
||||
|
||||
Reference in New Issue
Block a user