feat(frontend): add tool detail panel with clickable tool blocks#620
feat(frontend): add tool detail panel with clickable tool blocks#620yixiangxx wants to merge 4 commits into
Conversation
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>
📝 WalkthroughWalkthroughAdds 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
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
Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 | 🟠 MajorIncrease 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 | 🟠 MajorLayout overflow when workbench was closed before opening tool detail.
The ChatArea width calculation at line 265 only considers
isWorkbenchOpen, notisToolDetailOpen. 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 staledefaultExpandedfromToolBlockAPI.
defaultExpandedis 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?: booleanfromfrontend/src/features/tasks/components/message/thinking/types.tsand stop passing it fromToolBlockGroup.🤖 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-1padding with asize-6(24px) icon, resulting in approximately 32px total. While this is a desktop component, consider usingp-2or addingmin-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
displayNamesmapping includes most tool types butUploadis missing, though it has a dedicated renderer at line 91-92. The fallback totool.displayNameor 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
📒 Files selected for processing (12)
frontend/src/app/(tasks)/code/CodePageDesktop.tsxfrontend/src/features/tasks/components/message/thinking/MixedContentView.tsxfrontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsxfrontend/src/features/tasks/components/message/thinking/components/ToolBlockGroup.tsxfrontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/BashToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/EditToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/GlobToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/GrepToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/ReadToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/components/tools/WriteToolRenderer.tsxfrontend/src/features/tasks/components/message/thinking/contexts/ToolDetailContext.tsx
| <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} | ||
| > |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx | head -200Repository: 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.
| <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>
There was a problem hiding this comment.
♻️ Duplicate comments (1)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)
115-127:⚠️ Potential issue | 🟠 MajorMeet 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]andaria-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 staledefaultExpandedprop after migration.
defaultExpandedis now intentionally unused (_defaultExpanded). If no callers still depend on it, remove it fromToolBlockPropsto 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
📒 Files selected for processing (2)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsxfrontend/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>
There was a problem hiding this comment.
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 | 🟠 MajorChatArea width does not account for ToolDetailPanel.
The
ChatAreawidth calculation on lines 267-269 only considersisWorkbenchOpen, but whenisToolDetailOpenis true, theToolDetailPanel(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.,
getToolDisplayNameusingt()), 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 totool-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 withw-2/5for 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
📒 Files selected for processing (6)
frontend/src/app/(tasks)/chat/ChatPageDesktop.tsxfrontend/src/app/(tasks)/chat/ChatPageMobile.tsxfrontend/src/app/(tasks)/code/CodePageDesktop.tsxfrontend/src/app/(tasks)/code/CodePageMobile.tsxfrontend/src/features/tasks/components/message/thinking/MixedContentView.tsxfrontend/src/features/tasks/components/message/thinking/components/ToolDetailPanel.tsx
There was a problem hiding this comment.
🧹 Nitpick comments (1)
frontend/src/features/tasks/components/message/thinking/components/ToolBlock.tsx (1)
23-40: Consider adding icons for remaining tool types.
getToolIconhandles 6 tools whilegetToolDisplayNamesupports 9 (also includingTodoWrite,knowledge_base_search,web_search). The fallback toBookOpenIconworks, 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.
feat(backend): 修复chunk无法跨进程广播的问题 (#620) See merge request weibo_rd/common/wecode/wegent!877
Refactored tool display system to show detailed tool information in a dedicated panel:
Technical changes:
Summary by CodeRabbit
New Features
Improvements