fix: stop terminal traces showing thinking placeholder (#1441)

This commit is contained in:
Lyon
2026-06-18 00:14:10 +08:00
committed by GitHub
parent ca813aeecc
commit 1635767730
3 changed files with 60 additions and 0 deletions
@@ -156,11 +156,17 @@ function createScenarioState(scenarioId: string): ScenarioState {
conversations.push(crossProjectConversation());
traces.trc_cross_project = crossProjectTrace();
}
if (id === "terminal-empty-trace") {
conversations.push(terminalEmptyTraceConversation());
traces.trc_terminal_empty = terminalEmptyTrace();
}
if (id === "session-switch-empty-reload") conversations.push(emptyConversation());
const selectedConversationId = id === "deep-link" || id === "stale-nested-trace"
? "cnv_failed"
: id === "terminal-turn-stale-session-active"
? "cnv_completed"
: id === "terminal-empty-trace"
? "cnv_terminal_empty"
: id === "deep-link-stale-workspace-authority" || id === "stale-submit-restore"
? "cnv_running"
: base.selectedConversationId;
@@ -285,6 +291,31 @@ function crossProjectTrace(): JsonRecord {
return { traceId: "trc_cross_project", projectId: "prj_v02_code_agent", conversationId: "cnv_cross_project", sessionId: "ses_cross_project", threadId: "thr_cross_project", status: "completed", events: [], eventCount: 0, fullTraceLoaded: true, hasMore: false };
}
function terminalEmptyTraceConversation(): ConversationRecord {
const now = new Date().toISOString();
return {
conversationId: "cnv_terminal_empty",
projectId: capture.scenario.projectId,
sessionId: "ses_terminal_empty",
threadId: "thr_terminal_empty",
status: "completed",
lastTraceId: "trc_terminal_empty",
startedAt: now,
updatedAt: now,
messageCount: 2,
firstUserMessagePreview: "完成态空 Trace 文案验证",
session: { sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", status: "completed" },
messages: [
{ id: "msg_terminal_empty_user", role: "user", title: "用户", text: "完成态空 Trace 文案验证", status: "sent", createdAt: now, conversationId: "cnv_terminal_empty", sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", turnId: "turn_terminal_empty" },
{ id: "msg_terminal_empty_agent", role: "agent", title: "Code Agent", text: "终态空 Trace 已完成。", status: "completed", createdAt: now, conversationId: "cnv_terminal_empty", sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", traceId: "trc_terminal_empty", turnId: "turn_terminal_empty", runnerTrace: terminalEmptyTrace() }
]
};
}
function terminalEmptyTrace(): JsonRecord {
return { traceId: "trc_terminal_empty", status: "completed", conversationId: "cnv_terminal_empty", sessionId: "ses_terminal_empty", threadId: "thr_terminal_empty", events: [], eventCount: 0, fullTraceLoaded: true, hasMore: false, finalResponse: { text: "终态空 Trace 已完成。" } };
}
function emptyConversation(): ConversationRecord {
const now = new Date().toISOString();
return { conversationId: "cnv_empty", projectId: state?.projectId ?? capture.scenario.projectId, sessionId: "ses_empty", threadId: "thr_empty", status: "active", startedAt: now, updatedAt: now, messageCount: 0, firstUserMessagePreview: "空白会话", session: { sessionId: "ses_empty", threadId: "thr_empty", status: "active" }, messages: [] };
@@ -15,6 +15,7 @@ const events = computed(() => Array.isArray(props.trace?.events) ? props.trace.e
const eventCount = computed(() => props.trace?.eventCount ?? events.value.length);
const readableRows = computed(() => traceDisplayRows(traceRecord(props.trace), events.value as Record<string, unknown>[]));
const emptyTraceLabel = computed(() => {
if (isTerminalTraceStatus(props.trace?.status)) return terminalTraceEmptyLabel(props.trace?.status);
if (events.value.length > 0 || (props.trace?.fullTraceLoaded === true && eventCount.value > 0)) return "暂无可读 Trace";
return props.trace?.fullTraceLoaded === true ? "思考中..." : "加载中...";
});
@@ -92,6 +93,22 @@ function traceRecord(trace: RunnerTrace | null | undefined): Record<string, unkn
return trace && typeof trace === "object" ? trace as Record<string, unknown> : {};
}
function isTerminalTraceStatus(status: unknown): boolean {
return ["completed", "failed", "blocked", "timeout", "canceled", "cancelled"].includes(String(status ?? "").toLowerCase());
}
function terminalTraceEmptyLabel(status: unknown): string {
switch (String(status ?? "").toLowerCase()) {
case "completed": return "运行已完成,暂无可读 Trace";
case "failed":
case "blocked": return "运行失败,暂无可读 Trace";
case "timeout": return "运行超时,暂无可读 Trace";
case "canceled":
case "cancelled": return "运行已取消,暂无可读 Trace";
default: return "运行已结束,暂无可读 Trace";
}
}
</script>
<template>
@@ -25,3 +25,15 @@ test("failed trace exposes readable failure row", async ({ page }, testInfo) =>
await expect(page.locator(`${selectors.messageCard}[data-status="failed"]`)).toContainText("缺少受控依赖");
await saveScreenshot(page, testInfo, "trace-rendering-failed");
});
test.describe("terminal empty trace copy", () => {
test.use({ scenarioId: "terminal-empty-trace" });
test("completed message details do not retain thinking placeholder", async ({ page }) => {
await gotoWorkbench(page, "/workbench/sessions/cnv_terminal_empty");
const card = page.locator(`${selectors.messageCard}[data-status="completed"]`).last();
await expect(card).toContainText("终态空 Trace 已完成。");
await expect(card.locator(".trace-empty")).toContainText("运行已完成,暂无可读 Trace");
expect((await card.textContent()) ?? "").not.toContain("思考中");
});
});