From 2ade5f8877fadd3b0ff0ec47e3c2b9bc258f6a28 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 13 Jun 2026 00:07:47 -0700 Subject: [PATCH] FN-6339: combine consecutive thinking entries Render grouped task-chat thinking logs as one continuous section. - Concatenate grouped thinking entry text before markdown rendering. - Keep the thinking disclosure summary stable as "Thinking" instead of showing entry counts. - Move spacing to tool groups and remove multi-thinking divider styling. - Cover the combined thinking rendering behavior in TaskChatTab tests. Files changed: packages/dashboard/app/components/TaskChatTab.css | 10 ++++----- packages/dashboard/app/components/TaskChatTab.tsx | 25 ++++++++++------------ .../app/components/__tests__/TaskChatTab.test.tsx | 23 +++++++++++++++++++- 3 files changed, 37 insertions(+), 21 deletions(-) Fusion-Task-Id: FN-6339 Fusion-Task-Lineage: 51a2ea27-a56a-4844-a27b-389d1d24613f --- .../dashboard/app/components/TaskChatTab.css | 10 +++----- .../dashboard/app/components/TaskChatTab.tsx | 25 ++++++++----------- .../components/__tests__/TaskChatTab.test.tsx | 23 ++++++++++++++++- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/packages/dashboard/app/components/TaskChatTab.css b/packages/dashboard/app/components/TaskChatTab.css index bd5ec69fc9..d134830503 100644 --- a/packages/dashboard/app/components/TaskChatTab.css +++ b/packages/dashboard/app/components/TaskChatTab.css @@ -147,10 +147,13 @@ .task-chat-thinking-body { display: flex; flex-direction: column; - gap: var(--space-sm); padding: 0 var(--space-md) var(--space-md); } +.task-chat-tool-group-entries { + gap: var(--space-sm); +} + .task-chat-tool-entry { min-width: 0; padding: var(--space-sm) var(--space-md); @@ -176,11 +179,6 @@ font-weight: 600; } -.task-chat-thinking-markdown + .task-chat-thinking-markdown { - padding-top: var(--space-sm); - border-top: var(--btn-border-width) solid color-mix(in srgb, var(--color-warning) 24%, var(--border)); -} - .task-chat-entry-kicker { margin-bottom: var(--space-xs); color: var(--text-muted); diff --git a/packages/dashboard/app/components/TaskChatTab.tsx b/packages/dashboard/app/components/TaskChatTab.tsx index e1f5884478..ba8d8a1592 100644 --- a/packages/dashboard/app/components/TaskChatTab.tsx +++ b/packages/dashboard/app/components/TaskChatTab.tsx @@ -301,23 +301,20 @@ function TaskChatToolGroup({ entries }: { entries: AgentLogEntry[] }) { } function TaskChatThinking({ entries }: { entries: AgentLogEntry[] }) { + const combinedThinkingText = entries.map((entry) => entry.text).join(""); + return (
- - {entries.length === 1 ? "Thinking" : `${entries.length} thinking entries`} - + Thinking
- {entries.map((entry, entryIndex) => ( -
- - {entry.text} - -
- ))} +
+ + {combinedThinkingText} + +
); diff --git a/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx b/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx index 660e5f4c05..b5e82ae35a 100644 --- a/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx +++ b/packages/dashboard/app/components/__tests__/TaskChatTab.test.tsx @@ -377,8 +377,9 @@ describe("TaskChatTab", () => { const thinking = screen.getByTestId("task-chat-thinking"); expect(thinking).toHaveAttribute("open"); - expect(screen.getByText("Thinking")).toBeVisible(); + expect(within(thinking).getByText("Thinking")).toBeVisible(); expect(screen.getByText("I am considering options")).toBeVisible(); + expect(within(thinking).getAllByTestId("task-chat-entry-thinking")).toHaveLength(1); await user.click(within(thinking).getByText("Thinking")); @@ -386,6 +387,25 @@ describe("TaskChatTab", () => { expect(screen.getByText("I am considering options")).not.toBeVisible(); }); + it("renders consecutive thinking entries as one continuous section", () => { + mockLogs([ + makeEntry({ agent: "triage", type: "thinking", text: "First" }), + makeEntry({ agent: "triage", type: "thinking", text: "Second", timestamp: "2026-06-12T00:00:01.000Z" }), + ]); + + render(); + + const thinking = screen.getByTestId("task-chat-thinking"); + const summary = thinking.querySelector("summary"); + expect(summary).toBeTruthy(); + expect(within(summary as HTMLElement).getByText("Thinking")).toBeVisible(); + expect(screen.queryByText("2 thinking entries")).not.toBeInTheDocument(); + const thinkingBlocks = within(thinking).getAllByTestId("task-chat-entry-thinking"); + expect(thinkingBlocks).toHaveLength(1); + expect(thinkingBlocks[0]).toHaveTextContent("FirstSecond"); + expect(thinkingBlocks[0].nextElementSibling).toBeNull(); + }); + it("creates distinct tool segments when text or thinking entries are interleaved", () => { mockLogs([ makeEntry({ agent: "executor", type: "tool", text: "first tool", detail: "first detail" }), @@ -820,5 +840,6 @@ describe("TaskChatTab", () => { expect(css).toContain(".task-chat-tool-group-names"); expect(css).toContain(".task-chat-tool-group-error-count"); expect(css).toContain(".task-chat-thinking-summary"); + expect(css).not.toContain(".task-chat-thinking-markdown + .task-chat-thinking-markdown"); }); });