diff --git a/web/hwlab-cloud-web/scripts/workbench-server-state.test.ts b/web/hwlab-cloud-web/scripts/workbench-server-state.test.ts index 1fdf5c1b..508e4d1f 100644 --- a/web/hwlab-cloud-web/scripts/workbench-server-state.test.ts +++ b/web/hwlab-cloud-web/scripts/workbench-server-state.test.ts @@ -73,8 +73,11 @@ test("Workbench session tab status is read from server projection", () => { ] }; - const tab = sessionToSessionTab(session, "ses_tab_projection"); + const rawTab = sessionToSessionTab(session, "ses_tab_projection"); + const tab = sessionToSessionTab(session, "ses_tab_projection", { ses_tab_projection: { sessionId: "ses_tab_projection", status: "running", lastTraceId: "trc_tab_projection" } }); + assert.equal(rawTab.status, "unknown"); + assert.equal(rawTab.running, false); assert.equal(tab.status, "running"); assert.equal(tab.running, true); }); diff --git a/web/hwlab-cloud-web/src/components/workbench/ConversationPanel.vue b/web/hwlab-cloud-web/src/components/workbench/ConversationPanel.vue index cd6ad4cb..75c07f83 100644 --- a/web/hwlab-cloud-web/src/components/workbench/ConversationPanel.vue +++ b/web/hwlab-cloud-web/src/components/workbench/ConversationPanel.vue @@ -23,9 +23,10 @@ const clipboard = useClipboard(); const panelRef = ref(null); const following = ref(true); const detailMessageId = ref(null); -const detailMessage = computed(() => workbench.messages.find((message) => message.id === detailMessageId.value) ?? null); +const visibleMessages = computed(() => workbench.sessionDetailLoading ? [] : workbench.activeMessages); +const detailMessage = computed(() => workbench.activeMessages.find((message) => message.id === detailMessageId.value) ?? null); const traceTimelinePolicy = computed(() => workbenchTraceTimelinePolicy()); -const scrollSignature = computed(() => workbench.messages.map((message) => [ +const scrollSignature = computed(() => workbench.activeMessages.map((message) => [ message.id, message.status, message.text?.length ?? 0, @@ -69,7 +70,12 @@ function isAwaitingAgentBody(message: ChatMessage): boolean { } function showMessageText(message: ChatMessage): boolean { - return message.role !== "agent" || Boolean(String(message.text ?? "").trim()); + return !messageDiagnosticText(message) && (message.role !== "agent" || Boolean(String(message.text ?? "").trim())); +} + +function messageDiagnosticText(message: ChatMessage): string | null { + if (message.role !== "user" || String(message.text ?? "").trim()) return null; + return "消息内容缺失:Workbench read model 未返回 user text。"; } function onPanelScroll(): void { @@ -85,7 +91,7 @@ function scrollToBottom(): void { } function acknowledgeVisibleMessages(): void { - acknowledgeWorkbenchVisibleAfterPaint({ messages: workbench.messages, activeSessionId: workbench.activeSessionId, detailLoading: workbench.sessionDetailLoading }); + acknowledgeWorkbenchVisibleAfterPaint({ messages: workbench.activeMessages, activeSessionId: workbench.activeSessionId, detailLoading: workbench.sessionDetailLoading }); } function traceStorageKey(message: ChatMessage): string { @@ -100,7 +106,7 @@ function traceAutoExpanded(message: ChatMessage): boolean | null {