From 1635767730eca617cfb827625beb46f894d3f418 Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Thu, 18 Jun 2026 00:14:10 +0800 Subject: [PATCH] fix: stop terminal traces showing thinking placeholder (#1441) --- .../scripts/workbench-e2e-server.ts | 31 +++++++++++++++++++ .../src/components/agent/TraceTimeline.vue | 17 ++++++++++ .../specs/trace-rendering.spec.ts | 12 +++++++ 3 files changed, 60 insertions(+) diff --git a/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts b/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts index 6c0cf5a8..948f8a81 100644 --- a/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts +++ b/web/hwlab-cloud-web/scripts/workbench-e2e-server.ts @@ -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: [] }; diff --git a/web/hwlab-cloud-web/src/components/agent/TraceTimeline.vue b/web/hwlab-cloud-web/src/components/agent/TraceTimeline.vue index 367a9a21..9834f27e 100644 --- a/web/hwlab-cloud-web/src/components/agent/TraceTimeline.vue +++ b/web/hwlab-cloud-web/src/components/agent/TraceTimeline.vue @@ -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[])); 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 : {}; } +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"; + } +} +