From ad3095106d89a4fde86d06470de643fa33fc2d93 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Mon, 27 Apr 2026 12:59:26 -0700 Subject: [PATCH] fix(site/src/pages/AgentsPage): align thinking disclosure (#24743) The agent chat thinking disclosure used a smaller label with the caret on the left, which made collapsed and in-progress thinking look different from collapsible tool calls. Align the thinking disclosure with the shared tool-call row treatment by using the same label size, trailing caret placement, and hover color while preserving the streaming shimmer. Adds a Storybook story that renders collapsed thinking next to a tool call.
Storybook screenshots Captured from Storybook: - `pages/AgentsPage/ChatConversation/ConversationTimeline/ThinkingBlockWithToolCall` - `pages/AgentsPage/ChatConversation/ConversationTimeline/ThinkingBlockWithToolCall` hovered - `pages/AgentsPage/ChatConversation/StreamingOutput/ThinkingDuringStreamingWithToolCalls` Screenshots are attached in the Coder task.
Generated by Coder Agents. --- .../ConversationTimeline.stories.tsx | 58 +++++++++++++++++++ .../ChatConversation/ConversationTimeline.tsx | 22 +++---- .../ChatConversation/StreamingOutput.tsx | 8 ++- .../ChatElements/tools/ToolCollapsible.tsx | 3 +- 4 files changed, 76 insertions(+), 15 deletions(-) diff --git a/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.stories.tsx b/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.stories.tsx index bf7ce4d984..150e5e7f63 100644 --- a/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.stories.tsx +++ b/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.stories.tsx @@ -1768,6 +1768,64 @@ export const ThinkingBlockAlwaysCollapsed: Story = { }, }; +/** Collapsed thinking should visually align with adjacent tool calls. */ +export const ThinkingBlockWithToolCall: Story = { + parameters: { + queries: [ + { + key: ["me", "preferences"], + data: { + task_notification_alert_dismissed: false, + thinking_display_mode: "always_collapsed" as const, + }, + }, + ], + }, + args: { + ...defaultArgs, + parsedMessages: buildMessages([ + { + ...baseMessage, + id: 1, + role: "assistant", + content: [ + { + type: "reasoning", + text: "I need to inspect the package metadata before answering.", + }, + { + type: "tool-call", + tool_call_id: "tool-1", + tool_name: "read_file", + args: { path: "package.json" }, + }, + ], + }, + { + ...baseMessage, + id: 2, + role: "tool", + content: [ + { + type: "tool-result", + tool_call_id: "tool-1", + result: { content: '{"name":"coder"}' }, + }, + ], + }, + ]), + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + expect( + canvas.getByRole("button", { name: /thinking/i }), + ).toBeInTheDocument(); + expect( + canvas.getByRole("button", { name: /read package\.json/i }), + ).toBeInTheDocument(); + }, +}; + /** * A completed thinking block with auto mode should be collapsed * (non-streaming state means auto collapses). diff --git a/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.tsx b/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.tsx index d9dcd2afc8..20fdf695c8 100644 --- a/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.tsx +++ b/site/src/pages/AgentsPage/components/ChatConversation/ConversationTimeline.tsx @@ -154,31 +154,31 @@ const ReasoningDisclosure = memo<{ > - {isStreaming ? ( - + Thinking ) : ( - Thinking + Thinking )} + {hasText && (
diff --git a/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx b/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx index ea634cf8c2..435b599d54 100644 --- a/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx +++ b/site/src/pages/AgentsPage/components/ChatConversation/StreamingOutput.tsx @@ -33,9 +33,11 @@ const hasTextOrReasoningBlock = (blocks: readonly RenderBlock[]): boolean => * collapsible thinking disclosure label. */ const StreamingThinkingPlaceholder: FC = () => ( - - Thinking - +
+ + Thinking + +
); export const StreamingOutput: FC<{ diff --git a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCollapsible.tsx b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCollapsible.tsx index ca41330ea6..0ea5df2a95 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCollapsible.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/tools/ToolCollapsible.tsx @@ -31,13 +31,14 @@ export const ToolCollapsible: FC = ({ className={cn( "border-0 bg-transparent p-0 m-0 font-[inherit] text-[inherit] text-left", "flex w-full items-center gap-2 cursor-pointer", + "text-content-secondary transition-colors hover:text-content-primary", headerClassName, )} > {header}