Skip to content

feat(frontend): add tool detail panel with clickable tool blocks#620

Closed
yixiangxx wants to merge 4 commits into
mainfrom
wegent/tool-display
Closed

feat(frontend): add tool detail panel with clickable tool blocks#620
yixiangxx wants to merge 4 commits into
mainfrom
wegent/tool-display

Conversation

@yixiangxx
Copy link
Copy Markdown
Collaborator

@yixiangxx yixiangxx commented Feb 27, 2026

Refactored tool display system to show detailed tool information in a dedicated panel:

  • Added ToolDetailPanel component that appears on the right side (matches Workbench layout)
  • Converted ToolBlock from collapsible to clickable with selection state
  • Added ToolDetailContext to manage selected tool state and auto-expand behavior
  • Tool renderers now auto-expand content when displayed in detail panel
  • Detail panel replaces Workbench when open to maintain clean layout
  • Updated CodePageDesktop to integrate ToolDetailProvider and panel display

Technical changes:

  • New: ToolDetailPanel.tsx - shared panel component for tool details
  • New: ToolDetailContext.tsx - context for tool selection state
  • Modified: ToolBlock.tsx - simplified to clickable blocks with selection UI
  • Modified: All tool renderers - added auto-expand support via useIsInDetailPanel hook
  • Modified: CodePageDesktop.tsx - added provider and conditional panel display

Summary by CodeRabbit

  • New Features

    • Dedicated Tool Detail panel to view a selected tool with expanded info and full rendering.
    • Selectable tool pills to open/close the detail panel across desktop and mobile.
  • Improvements

    • Tool renderers auto-expand and simplify controls when shown in the detail panel.
    • Tools list now uses an inline, wrapped layout for compact display.
    • Page layouts adapt (hide/reshuffle workbench) when the detail panel is open.

Refactored tool display system to show detailed tool information in a dedicated panel:
- Added ToolDetailPanel component that appears on the right side (matches Workbench layout)
- Converted ToolBlock from collapsible to clickable with selection state
- Added ToolDetailContext to manage selected tool state and auto-expand behavior
- Tool renderers now auto-expand content when displayed in detail panel
- Detail panel replaces Workbench when open to maintain clean layout
- Updated CodePageDesktop to integrate ToolDetailProvider and panel display

Technical changes:
- New: ToolDetailPanel.tsx - shared panel component for tool details
- New: ToolDetailContext.tsx - context for tool selection state
- Modified: ToolBlock.tsx - simplified to clickable blocks with selection UI
- Modified: All tool renderers - added auto-expand support via useIsInDetailPanel hook
- Modified: CodePageDesktop.tsx - added provider and conditional panel display

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 27, 2026

📝 Walkthrough

Walkthrough

Adds a Tool Detail context and panel, integrates the provider into desktop/mobile chat and code pages, refactors tool pills to open a shared detail panel, and updates multiple tool renderers and MixedContent rendering to behave differently when rendered inside the detail panel.

Changes

Cohort / File(s) Summary
Context System
frontend/src/features/tasks/components/message/thinking/contexts/ToolDetailContext.tsx
New context and providers: ToolDetailProvider, ToolDetailPanelContentProvider, useToolDetail, useIsToolDetailOpen, useIsInDetailPanel. Manages selectedTool, isToolDetailOpen, and in-panel flag.
Detail Panel Component
frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx
New memoized ToolDetailPanel that renders selected tool details (header, status icon, input preview, specialized renderer) and a close action; uses PanelContentProvider for in-panel context.
Page Integration
frontend/src/app/(tasks)/code/CodePageDesktop.tsx, frontend/src/app/(tasks)/chat/ChatPageDesktop.tsx, frontend/src/app/(tasks)/chat/ChatPageMobile.tsx, frontend/src/app/(tasks)/code/CodePageMobile.tsx
Wraps page content in ToolDetailProvider via new internal Content components; CodePageDesktop now conditionally hides Workbench when the tool detail panel is open and renders ToolDetailPanel.
Tool Block & Group
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx, .../ToolBlockGroup.tsx
ToolBlock simplified to a selectable pill that toggles selection via ToolDetailContext; _defaultExpanded rename in signature. ToolBlockGroup layout changed to inline flex-wrap with gap-2.
Tool Renderers (detail-aware)
frontend/src/features/tasks/components/message/thinking/components/tools/*.tsx
Bash, Edit, Glob, Grep, Read, Write renderers: add useIsInDetailPanel, auto-expand when in detail panel, hide collapse controls/ellipsis, and adjust maxHeight/visibility for in-panel rendering.
Mixed Content Rendering
frontend/src/features/tasks/components/message/thinking/MixedContentView.tsx
Refactors grouping: batches consecutive content vs. tool groups, flattens to JSX with new key-generation, and preserves the "Processing..." indicator in the new flow.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ToolBlock
    participant ToolDetailContext
    participant ToolDetailPanel
    participant ToolRenderer

    User->>ToolBlock: click tool pill
    ToolBlock->>ToolDetailContext: setSelectedTool(tool or null)
    ToolDetailContext->>ToolDetailContext: update selectedTool / isToolDetailOpen
    ToolDetailContext-->>ToolDetailPanel: provide selectedTool
    ToolDetailPanel->>ToolDetailContext: read selectedTool
    ToolDetailPanel->>ToolRenderer: render tool inside PanelContentProvider
    ToolRenderer->>ToolRenderer: useIsInDetailPanel() -> auto-expand, hide toggles
    ToolRenderer-->>User: display expanded detail view
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested reviewers

  • feifei325
  • qdaxb

Poem

🐇 I hopped through code and found a slot,
A pill to click, a panel I got,
Details unfurl where tools once hid,
Renderers stretch — my whiskers did!
Hooray — a rabbit’s small applause for this spot.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a tool detail panel with clickable tool blocks, which aligns with the primary objective of refactoring the tool display system.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch wegent/tool-display

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/src/features/tasks/components/message/thinking/components/tools/BashToolRenderer.tsx (1)

72-76: ⚠️ Potential issue | 🟠 Major

Increase expand/collapse button hit area to meet mobile accessibility rules.

The toggle button does not enforce a 44×44 touch target.

Suggested fix
             {isOutputCollapsible && !isInDetailPanel && (
               <button
+                type="button"
                 onClick={() => setIsOutputExpanded(!isOutputExpanded)}
-                className="text-xs text-blue-400 hover:text-blue-500 hover:font-semibold transition-colors"
+                className="h-11 min-w-[44px] px-2 text-xs text-blue-400 hover:text-blue-500 hover:font-semibold transition-colors"
               >

As per coding guidelines: "All interactive elements on mobile must be at least 44px × 44px - use h-11 min-w-[44px] for buttons."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/tools/BashToolRenderer.tsx`
around lines 72 - 76, The expand/collapse button in BashToolRenderer (the JSX
block guarded by isOutputCollapsible && !isInDetailPanel that calls
setIsOutputExpanded and reads isOutputExpanded) has too small a touch target;
update the button's className to include the mobile minimum touch size (e.g. add
h-11 and min-w-[44px]) while preserving the existing text sizing and color
classes so the visual styling remains the same; ensure the same change is
applied to any sibling toggle buttons in this component to keep behavior
consistent.
frontend/src/app/(tasks)/code/CodePageDesktop.tsx (1)

262-275: ⚠️ Potential issue | 🟠 Major

Layout overflow when workbench was closed before opening tool detail.

The ChatArea width calculation at line 265 only considers isWorkbenchOpen, not isToolDetailOpen. If a user had the workbench closed (isWorkbenchOpen = false) and then clicks a tool to open the detail panel, the ChatArea will be 100% wide while ToolDetailPanel is 40% wide, causing a total of 140% and horizontal overflow.

🔧 Proposed fix to account for tool detail panel in width calculation
           <div
             className="transition-all duration-300 ease-in-out flex flex-col min-h-0"
             style={{
-              width: hasTaskId && isWorkbenchOpen ? '60%' : '100%',
+              width: hasTaskId && (isWorkbenchOpen || isToolDetailOpen) ? '60%' : '100%',
             }}
           >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/app/`(tasks)/code/CodePageDesktop.tsx around lines 262 - 275,
The ChatArea container width only checks isWorkbenchOpen causing overflow when
the tool detail panel (isToolDetailOpen) is open; update the width calculation
in CodePageDesktop (the div wrapping <ChatArea>) to use hasTaskId &&
(isWorkbenchOpen || isToolDetailOpen) so the ChatArea becomes 60% whenever
either the workbench or the tool detail is open, preventing the 100%+40%
overflow.
🧹 Nitpick comments (4)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)

120-123: Remove stale defaultExpanded from ToolBlock API.

defaultExpanded is now dead API surface in this component. Cleaning it up will reduce confusion and keep types aligned with behavior.

Suggested cleanup
 export const ToolBlock = memo(function ToolBlock({
   tool,
-  defaultExpanded: _defaultExpanded = false,
 }: ToolBlockProps) {

Also remove defaultExpanded?: boolean from frontend/src/features/tasks/components/message/thinking/types.ts and stop passing it from ToolBlockGroup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`
around lines 120 - 123, ToolBlock currently accepts a dead prop defaultExpanded;
remove defaultExpanded from the ToolBlock signature and its props type
(ToolBlockProps) in the component file and the corresponding declaration in
frontend/src/features/tasks/components/message/thinking/types.ts, then remove
any passage of defaultExpanded from the parent ToolBlockGroup so the prop is no
longer passed down or referenced; update any internal references/usages inside
the ToolBlock function to stop reading _defaultExpanded and run a quick grep for
defaultExpanded to clean up remaining usages and type imports.
frontend/src/features/tasks/components/message/thinking/components/tools/WriteToolRenderer.tsx (1)

19-27: Consider extracting the repeated detail-panel expansion pattern into a shared hook.

This same state/effect block is now duplicated across Bash/Read/Grep/Glob/Write renderers; a shared hook would reduce drift and keep behavior synchronized.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/tools/WriteToolRenderer.tsx`
around lines 19 - 27, Extract the repeated state/effect pattern that syncs local
expansion with useIsInDetailPanel into a reusable hook (e.g.,
useDetailPanelExpansion) that internally calls useIsInDetailPanel, manages
isContentExpanded via useState, and runs the useEffect to set the expanded state
when the panel becomes active; have the hook return the expansion state and
setter (the same shape as [isContentExpanded, setIsContentExpanded]) so
WriteToolRenderer and the Bash/Read/Grep/Glob renderers can replace their local
useState/useEffect blocks (the ones referencing useIsInDetailPanel,
isContentExpanded, setIsContentExpanded) with a single call to the new hook to
remove duplication and keep behavior synchronized.
frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx (2)

202-208: Consider larger touch target for close button.

The close button has p-1 padding with a size-6 (24px) icon, resulting in approximately 32px total. While this is a desktop component, consider using p-2 or adding min-h-[44px] min-w-[44px] for better accessibility, especially for users with motor impairments.

♿ Optional fix for larger touch target
               <button
                 onClick={() => setSelectedTool(null)}
-                className="relative rounded-full p-1 text-text-muted hover:text-text-primary focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-primary"
+                className="relative rounded-full p-2 text-text-muted hover:text-text-primary focus:outline focus:outline-2 focus:outline-offset-2 focus:outline-primary"
               >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`
around lines 202 - 208, The close button in the ToolDetailPanel (the button
calling setSelectedTool(null) and rendering XMarkIcon) has only p-1 and a size-6
icon making the touch target small; increase its tappable area by changing the
className to use p-2 or adding explicit min dimensions such as min-h-[44px]
min-w-[44px] (and keep visual centering for XMarkIcon), so update the button's
className accordingly to improve accessibility without altering its behavior.

47-57: Missing display name entry for 'Upload' tool.

The displayNames mapping includes most tool types but Upload is missing, though it has a dedicated renderer at line 91-92. The fallback to tool.displayName or raw name will work, but for consistency you may want to add an entry.

📝 Optional: Add Upload to displayNames
   const displayNames: Record<string, string> = {
     Bash: t('thinking.tools.bash') || 'Execute Command',
     Read: t('thinking.tools.read') || 'Read File',
     Edit: t('thinking.tools.edit') || 'Edit File',
     Write: t('thinking.tools.write') || 'Write File',
     Grep: t('thinking.tools.grep') || 'Search Code',
     Glob: t('thinking.tools.glob') || 'Find Files',
     TodoWrite: t('thinking.tools.todo') || 'Update Tasks',
+    Upload: t('thinking.tools.upload') || 'Upload File',
     knowledge_base_search: t('thinking.tools.kb_search') || 'Search Knowledge Base',
     web_search: t('thinking.tools.web_search') || 'Web Search',
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`
around lines 47 - 57, Add a missing "Upload" entry to the displayNames mapping
in ToolDetailPanel.tsx so the Upload tool uses a localized label; update the
displayNames Record<string,string> (the constant named displayNames) to include
"Upload": t('thinking.tools.upload') || 'Upload File' to match the existing
pattern and the Upload renderer used elsewhere in this component.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`:
- Around line 162-169: Change the interactive row in ToolBlock from a
non-semantic <div> to a semantic <button> (type="button") so keyboard and screen
reader users can activate it; ensure the click handler (handleClick) is only
attached when isExpandable is true (or have the button disabled when not
expandable) and preserve visual state classes (isSelected) while adding the
mobile touch target classes h-11 and min-w-[44px]; also keep cursor logic
(cursor-pointer vs cursor-default) and add an accessible pressed state
(aria-pressed={isSelected}) so screen readers know selection state.

---

Outside diff comments:
In `@frontend/src/app/`(tasks)/code/CodePageDesktop.tsx:
- Around line 262-275: The ChatArea container width only checks isWorkbenchOpen
causing overflow when the tool detail panel (isToolDetailOpen) is open; update
the width calculation in CodePageDesktop (the div wrapping <ChatArea>) to use
hasTaskId && (isWorkbenchOpen || isToolDetailOpen) so the ChatArea becomes 60%
whenever either the workbench or the tool detail is open, preventing the
100%+40% overflow.

In
`@frontend/src/features/tasks/components/message/thinking/components/tools/BashToolRenderer.tsx`:
- Around line 72-76: The expand/collapse button in BashToolRenderer (the JSX
block guarded by isOutputCollapsible && !isInDetailPanel that calls
setIsOutputExpanded and reads isOutputExpanded) has too small a touch target;
update the button's className to include the mobile minimum touch size (e.g. add
h-11 and min-w-[44px]) while preserving the existing text sizing and color
classes so the visual styling remains the same; ensure the same change is
applied to any sibling toggle buttons in this component to keep behavior
consistent.

---

Nitpick comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`:
- Around line 120-123: ToolBlock currently accepts a dead prop defaultExpanded;
remove defaultExpanded from the ToolBlock signature and its props type
(ToolBlockProps) in the component file and the corresponding declaration in
frontend/src/features/tasks/components/message/thinking/types.ts, then remove
any passage of defaultExpanded from the parent ToolBlockGroup so the prop is no
longer passed down or referenced; update any internal references/usages inside
the ToolBlock function to stop reading _defaultExpanded and run a quick grep for
defaultExpanded to clean up remaining usages and type imports.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`:
- Around line 202-208: The close button in the ToolDetailPanel (the button
calling setSelectedTool(null) and rendering XMarkIcon) has only p-1 and a size-6
icon making the touch target small; increase its tappable area by changing the
className to use p-2 or adding explicit min dimensions such as min-h-[44px]
min-w-[44px] (and keep visual centering for XMarkIcon), so update the button's
className accordingly to improve accessibility without altering its behavior.
- Around line 47-57: Add a missing "Upload" entry to the displayNames mapping in
ToolDetailPanel.tsx so the Upload tool uses a localized label; update the
displayNames Record<string,string> (the constant named displayNames) to include
"Upload": t('thinking.tools.upload') || 'Upload File' to match the existing
pattern and the Upload renderer used elsewhere in this component.

In
`@frontend/src/features/tasks/components/message/thinking/components/tools/WriteToolRenderer.tsx`:
- Around line 19-27: Extract the repeated state/effect pattern that syncs local
expansion with useIsInDetailPanel into a reusable hook (e.g.,
useDetailPanelExpansion) that internally calls useIsInDetailPanel, manages
isContentExpanded via useState, and runs the useEffect to set the expanded state
when the panel becomes active; have the hook return the expansion state and
setter (the same shape as [isContentExpanded, setIsContentExpanded]) so
WriteToolRenderer and the Bash/Read/Grep/Glob renderers can replace their local
useState/useEffect blocks (the ones referencing useIsInDetailPanel,
isContentExpanded, setIsContentExpanded) with a single call to the new hook to
remove duplication and keep behavior synchronized.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 178df2b and a547f23.

📒 Files selected for processing (12)
  • frontend/src/app/(tasks)/code/CodePageDesktop.tsx
  • frontend/src/features/tasks/components/message/thinking/MixedContentView.tsx
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlockGroup.tsx
  • frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/BashToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/EditToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/GlobToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/GrepToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/ReadToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/components/tools/WriteToolRenderer.tsx
  • frontend/src/features/tasks/components/message/thinking/contexts/ToolDetailContext.tsx

Comment on lines +162 to +169
<div
className={`flex items-center gap-2 px-3 py-2 rounded-md mb-1 transition-colors ${
isSelected
? 'bg-primary/10 border-2 border-primary'
: 'bg-fill-tert border-2 border-transparent hover:bg-fill-secondary'
} ${isExpandable ? 'cursor-pointer' : 'cursor-default'}`}
onClick={handleClick}
>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx | head -200

Repository: wecode-ai/Wegent

Length of output: 7913


Convert to semantic button with proper touch target size.

This row is interactive (toggles tool selection via onClick when isExpandable is true) but rendered as a <div>, which weakens keyboard navigation and screen reader support. Additionally, with only py-2 padding, it doesn't meet the 44×44px mobile touch target requirement.

Suggested fix
-    <div
+    <button
+      type="button"
       className={`flex items-center gap-2 px-3 py-2 rounded-md mb-1 transition-colors ${
         isSelected
           ? 'bg-primary/10 border-2 border-primary'
           : 'bg-fill-tert border-2 border-transparent hover:bg-fill-secondary'
-      } ${isExpandable ? 'cursor-pointer' : 'cursor-default'}`}
+      } ${isExpandable ? 'cursor-pointer' : 'cursor-default'} h-11 min-w-[44px] text-left`}
       onClick={handleClick}
+      disabled={!isExpandable}
+      aria-pressed={isSelected}
     >
@@
-    </div>
+    </button>

Per coding guidelines: "All interactive elements on mobile must be at least 44px × 44px - use h-11 min-w-[44px] for buttons."

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div
className={`flex items-center gap-2 px-3 py-2 rounded-md mb-1 transition-colors ${
isSelected
? 'bg-primary/10 border-2 border-primary'
: 'bg-fill-tert border-2 border-transparent hover:bg-fill-secondary'
} ${isExpandable ? 'cursor-pointer' : 'cursor-default'}`}
onClick={handleClick}
>
<button
type="button"
className={`flex items-center gap-2 px-3 py-2 rounded-md mb-1 transition-colors ${
isSelected
? 'bg-primary/10 border-2 border-primary'
: 'bg-fill-tert border-2 border-transparent hover:bg-fill-secondary'
} ${isExpandable ? 'cursor-pointer' : 'cursor-default'} h-11 min-w-[44px] text-left`}
onClick={handleClick}
disabled={!isExpandable}
aria-pressed={isSelected}
>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`
around lines 162 - 169, Change the interactive row in ToolBlock from a
non-semantic <div> to a semantic <button> (type="button") so keyboard and screen
reader users can activate it; ensure the click handler (handleClick) is only
attached when isExpandable is true (or have the button disabled when not
expandable) and preserve visual state classes (isSelected) while adding the
mobile touch target classes h-11 and min-w-[44px]; also keep cursor logic
(cursor-pointer vs cursor-default) and add an accessible pressed state
(aria-pressed={isSelected}) so screen readers know selection state.

Updated tool blocks to use a cleaner pill/tag style matching reference design:
- Simplified ToolBlock to display as inline pill buttons (rounded-full)
- Removed status icons, chevron, and input preview from tool blocks
- Changed layout from vertical stacked blocks to horizontal flex-wrap
- Used existing project colors (bg-muted/bg-hover) instead of custom gray scale
- Maintained original tool name display logic (i18n → displayName → toolName)
- Tool icons now use Heroicons outline style for consistency
- Selection state shown via background color change (muted → hover)

Technical changes:
- ToolBlock: Changed from div to button element with pill styling
- ToolBlockGroup: Changed tools list from space-y-2 to flex flex-wrap gap-2
- Removed unused status/preview rendering logic from ToolBlock
- Color mapping: bg-muted (unselected) → bg-hover (selected/hover)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)

115-127: ⚠️ Potential issue | 🟠 Major

Meet mobile touch target and expose toggle state for accessibility.

This interactive button does not satisfy the required 44×44 mobile target, and toggle state is not announced to assistive tech. Add h-11 min-w-[44px] and aria-pressed.

Suggested patch
   return (
     <button
       type="button"
-      className={`inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full text-sm transition-colors ${
+      className={`inline-flex h-11 min-w-[44px] items-center gap-1.5 px-3 py-1.5 rounded-full text-sm transition-colors ${
         isSelected
           ? 'bg-hover text-text-primary'
           : 'bg-muted text-text-secondary hover:bg-hover'
       } ${isExpandable ? 'cursor-pointer' : 'cursor-default'}`}
       onClick={handleClick}
       disabled={!isExpandable}
+      aria-pressed={isSelected}
     >

As per coding guidelines: "All interactive elements on mobile must be at least 44px × 44px - use h-11 min-w-[44px] for buttons".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`
around lines 115 - 127, Update the ToolBlock button to meet mobile touch targets
and expose toggle state: add the classes h-11 and min-w-[44px] to the button's
className string so the interactive area is at least 44×44, and add
aria-pressed={isSelected} to announce toggle state to assistive tech (keep
existing disabled behavior via disabled={!isExpandable} and
onClick={handleClick}); locate these changes in the ToolBlock component where
the <button> renders ToolIcon and toolDisplayName.
🧹 Nitpick comments (1)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)

80-83: Trim stale defaultExpanded prop after migration.

defaultExpanded is now intentionally unused (_defaultExpanded). If no callers still depend on it, remove it from ToolBlockProps to keep the component API accurate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`
around lines 80 - 83, The ToolBlock component is keeping a now-unused prop
(defaultExpanded renamed to _defaultExpanded) after a migration; remove
defaultExpanded from the ToolBlockProps type/interface and from the ToolBlock
parameter list so the component API matches usage (update any import/type
definitions that declare ToolBlockProps and the ToolBlock function signature to
drop defaultExpanded/_defaultExpanded and run a project-wide typecheck to catch
any remaining callers that still pass the prop).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`:
- Around line 115-127: Update the ToolBlock button to meet mobile touch targets
and expose toggle state: add the classes h-11 and min-w-[44px] to the button's
className string so the interactive area is at least 44×44, and add
aria-pressed={isSelected} to announce toggle state to assistive tech (keep
existing disabled behavior via disabled={!isExpandable} and
onClick={handleClick}); locate these changes in the ToolBlock component where
the <button> renders ToolIcon and toolDisplayName.

---

Nitpick comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`:
- Around line 80-83: The ToolBlock component is keeping a now-unused prop
(defaultExpanded renamed to _defaultExpanded) after a migration; remove
defaultExpanded from the ToolBlockProps type/interface and from the ToolBlock
parameter list so the component API matches usage (update any import/type
definitions that declare ToolBlockProps and the ToolBlock function signature to
drop defaultExpanded/_defaultExpanded and run a project-wide typecheck to catch
any remaining callers that still pass the prop).

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a547f23 and 24cc5ae.

📒 Files selected for processing (2)
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlockGroup.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlockGroup.tsx

- Replace emoji status icons with Heroicons in ToolDetailPanel for consistency with ToolBlock
- Group consecutive tool blocks in MixedContentView using flex layout
- Reduce spacing between text content and tool blocks (-mt-1)
- Add ToolDetailProvider to Chat and Code pages for proper context management
- Fix TypeScript type issues in MixedContentView grouping logic

This improves visual consistency across tool displays and makes the UI more compact.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
frontend/src/app/(tasks)/code/CodePageDesktop.tsx (1)

265-278: ⚠️ Potential issue | 🟠 Major

ChatArea width does not account for ToolDetailPanel.

The ChatArea width calculation on lines 267-269 only considers isWorkbenchOpen, but when isToolDetailOpen is true, the ToolDetailPanel (40% width) is rendered instead of the Workbench. The ChatArea should also shrink to 60% when the tool detail panel is open to prevent layout overflow.

🐛 Proposed fix
           <div
             className="transition-all duration-300 ease-in-out flex flex-col min-h-0"
             style={{
-              width: hasTaskId && isWorkbenchOpen ? '60%' : '100%',
+              width: hasTaskId && (isWorkbenchOpen || isToolDetailOpen) ? '60%' : '100%',
             }}
           >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@frontend/src/app/`(tasks)/code/CodePageDesktop.tsx around lines 265 - 278,
The ChatArea container currently sets width based only on hasTaskId &&
isWorkbenchOpen; update the condition to also account for isToolDetailOpen so
the ChatArea shrinks to '60%' whenever either the workbench or ToolDetailPanel
is open (ToolDetailPanel is rendered at 40% width). Modify the style expression
used in the div wrapping <ChatArea ...> (the width calculation referencing
hasTaskId and isWorkbenchOpen) to use hasTaskId && (isWorkbenchOpen ||
isToolDetailOpen) so layout doesn't overflow when the tool detail panel is
shown.
🧹 Nitpick comments (3)
frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx (3)

230-232: Hardcoded "Input" string should use translation.

The label "Input" on line 232 is hardcoded in English. For consistency with the internationalization approach used elsewhere (e.g., getToolDisplayName using t()), this should use a translation key.

♻️ Proposed fix
-                <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
-                  Input
-                </h4>
+                <h4 className="text-xs font-semibold text-text-muted uppercase tracking-wider mb-2">
+                  {t('thinking.toolDetail.input') || 'Input'}
+                </h4>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`
around lines 230 - 232, The hardcoded "Input" header in the ToolDetailPanel
component should be replaced with a translatable string; locate the h4 in
ToolDetailPanel.tsx and swap the literal "Input" for a call to the i18n
translator (e.g., use t('tool.input') or an existing appropriate key) consistent
with how getToolDisplayName uses t(), and add the new translation key to the
locale resources if it doesn't already exist.

1-6: Filename should use kebab-case per coding guidelines.

The file is located under components/ and should follow the kebab-case naming convention. Consider renaming to tool-detail-panel.tsx.

As per coding guidelines: "/components//*.{ts,tsx}": Component names should use PascalCase, file names should use kebab-case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`
around lines 1 - 6, Rename the file from ToolDetailPanel.tsx to kebab-case as
tool-detail-panel.tsx and update all imports that reference the component (e.g.,
any import of ToolDetailPanel) to the new filename; keep the React
component/class name inside the file as PascalCase (ToolDetailPanel) and ensure
any barrel/index exports are updated to reference "./tool-detail-panel" so
imports across the codebase continue to work.

196-201: Consider using Tailwind width class instead of inline style.

The inline style={{ width: '40%' }} could be replaced with w-2/5 for consistency with Tailwind-based styling elsewhere. However, if this matches the Workbench's approach for layout consistency, it's acceptable to keep as-is.

♻️ Optional: Use Tailwind class
     <div
       className="transition-all duration-300 ease-in-out bg-surface overflow-hidden"
-      style={{ width: '40%' }}
+      className="w-2/5 transition-all duration-300 ease-in-out bg-surface overflow-hidden"
     >
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`
around lines 196 - 201, The right-panel div in ToolDetailPanel currently uses an
inline style width: '40%'; replace that inline style with the Tailwind width
utility by removing style={{ width: '40%' }} and adding "w-2/5" to the div's
className (preserve the existing classes "transition-all duration-300
ease-in-out bg-surface overflow-hidden"); update any className string
construction accordingly in the ToolDetailPanel component so layout matches
Tailwind conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@frontend/src/app/`(tasks)/code/CodePageDesktop.tsx:
- Around line 265-278: The ChatArea container currently sets width based only on
hasTaskId && isWorkbenchOpen; update the condition to also account for
isToolDetailOpen so the ChatArea shrinks to '60%' whenever either the workbench
or ToolDetailPanel is open (ToolDetailPanel is rendered at 40% width). Modify
the style expression used in the div wrapping <ChatArea ...> (the width
calculation referencing hasTaskId and isWorkbenchOpen) to use hasTaskId &&
(isWorkbenchOpen || isToolDetailOpen) so layout doesn't overflow when the tool
detail panel is shown.

---

Nitpick comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx`:
- Around line 230-232: The hardcoded "Input" header in the ToolDetailPanel
component should be replaced with a translatable string; locate the h4 in
ToolDetailPanel.tsx and swap the literal "Input" for a call to the i18n
translator (e.g., use t('tool.input') or an existing appropriate key) consistent
with how getToolDisplayName uses t(), and add the new translation key to the
locale resources if it doesn't already exist.
- Around line 1-6: Rename the file from ToolDetailPanel.tsx to kebab-case as
tool-detail-panel.tsx and update all imports that reference the component (e.g.,
any import of ToolDetailPanel) to the new filename; keep the React
component/class name inside the file as PascalCase (ToolDetailPanel) and ensure
any barrel/index exports are updated to reference "./tool-detail-panel" so
imports across the codebase continue to work.
- Around line 196-201: The right-panel div in ToolDetailPanel currently uses an
inline style width: '40%'; replace that inline style with the Tailwind width
utility by removing style={{ width: '40%' }} and adding "w-2/5" to the div's
className (preserve the existing classes "transition-all duration-300
ease-in-out bg-surface overflow-hidden"); update any className string
construction accordingly in the ToolDetailPanel component so layout matches
Tailwind conventions.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 24cc5ae and e1e5bfa.

📒 Files selected for processing (6)
  • frontend/src/app/(tasks)/chat/ChatPageDesktop.tsx
  • frontend/src/app/(tasks)/chat/ChatPageMobile.tsx
  • frontend/src/app/(tasks)/code/CodePageDesktop.tsx
  • frontend/src/app/(tasks)/code/CodePageMobile.tsx
  • frontend/src/features/tasks/components/message/thinking/MixedContentView.tsx
  • frontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)

23-40: Consider adding icons for remaining tool types.

getToolIcon handles 6 tools while getToolDisplayName supports 9 (also including TodoWrite, knowledge_base_search, web_search). The fallback to BookOpenIcon works, but dedicated icons would improve visual consistency.

Suggested additions
+import {
+  BookOpenIcon,
+  CommandLineIcon,
+  PencilSquareIcon,
+  DocumentPlusIcon,
+  MagnifyingGlassIcon,
+  FolderIcon,
+  ClipboardDocumentListIcon,
+  BookmarkSquareIcon,
+  GlobeAltIcon,
+} from '@heroicons/react/24/outline'

 function getToolIcon(toolName: string): React.ComponentType<{ className?: string }> {
   switch (toolName) {
     // ... existing cases ...
+    case 'TodoWrite':
+      return ClipboardDocumentListIcon
+    case 'knowledge_base_search':
+      return BookmarkSquareIcon
+    case 'web_search':
+      return GlobeAltIcon
     default:
       return BookOpenIcon
   }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`
around lines 23 - 40, getToolIcon currently maps six tool names but
getToolDisplayName supports nine; add explicit icon mappings for the remaining
tool types (TodoWrite, knowledge_base_search, web_search) in the getToolIcon
function so they no longer fall back to BookOpenIcon. Update the switch in
getToolIcon to include cases for 'TodoWrite', 'knowledge_base_search', and
'web_search' returning appropriate React.ComponentType icons (pick existing
icons from the codebase or import new ones) and ensure imports at the top
include any newly used icon components so the component renders consistently
with getToolDisplayName.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx`:
- Around line 23-40: getToolIcon currently maps six tool names but
getToolDisplayName supports nine; add explicit icon mappings for the remaining
tool types (TodoWrite, knowledge_base_search, web_search) in the getToolIcon
function so they no longer fall back to BookOpenIcon. Update the switch in
getToolIcon to include cases for 'TodoWrite', 'knowledge_base_search', and
'web_search' returning appropriate React.ComponentType icons (pick existing
icons from the codebase or import new ones) and ensure imports at the top
include any newly used icon components so the component renders consistently
with getToolDisplayName.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1e5bfa and 8fc14f2.

📒 Files selected for processing (1)
  • frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx

fengkuizhi pushed a commit that referenced this pull request Mar 3, 2026
feat(backend): 修复chunk无法跨进程广播的问题 (#620)

See merge request weibo_rd/common/wecode/wegent!877
@qdaxb qdaxb closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants