@@ -24,7 +24,6 @@ import { listen, type UnlistenFn } from "@tauri-apps/api/event";
2424import { StreamMessage } from "./StreamMessage" ;
2525import { ExecutionControlBar } from "./ExecutionControlBar" ;
2626import { ErrorBoundary } from "./ErrorBoundary" ;
27- import { enhanceMessages , type EnhancedMessage } from "@/types/enhanced-messages" ;
2827import { useVirtualizer } from "@tanstack/react-virtual" ;
2928
3029interface AgentExecutionProps {
@@ -75,7 +74,6 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
7574 const [ model , setModel ] = useState ( agent . model || "sonnet" ) ;
7675 const [ isRunning , setIsRunning ] = useState ( false ) ;
7776 const [ messages , setMessages ] = useState < ClaudeStreamMessage [ ] > ( [ ] ) ;
78- const [ enhancedMessages , setEnhancedMessages ] = useState < EnhancedMessage [ ] > ( [ ] ) ;
7977 const [ rawJsonlOutput , setRawJsonlOutput ] = useState < string [ ] > ( [ ] ) ;
8078 const [ error , setError ] = useState < string | null > ( null ) ;
8179 const [ copyPopoverOpen , setCopyPopoverOpen ] = useState ( false ) ;
@@ -95,16 +93,74 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
9593 const unlistenRefs = useRef < UnlistenFn [ ] > ( [ ] ) ;
9694 const elapsedTimeIntervalRef = useRef < NodeJS . Timeout | null > ( null ) ;
9795
96+ // Filter out messages that shouldn't be displayed
97+ const displayableMessages = React . useMemo ( ( ) => {
98+ return messages . filter ( ( message , index ) => {
99+ // Skip meta messages that don't have meaningful content
100+ if ( message . isMeta && ! message . leafUuid && ! message . summary ) {
101+ return false ;
102+ }
103+
104+ // Skip empty user messages
105+ if ( message . type === "user" && message . message ) {
106+ const msg = message . message ;
107+ if ( ! msg . content || ( Array . isArray ( msg . content ) && msg . content . length === 0 ) ) {
108+ return false ;
109+ }
110+
111+ // Check if this is a user message with only tool results that are already displayed
112+ if ( Array . isArray ( msg . content ) ) {
113+ const hasOnlyHiddenToolResults = msg . content . every ( ( content : any ) => {
114+ if ( content . type !== "tool_result" ) return false ;
115+
116+ // Check if this tool result should be hidden
117+ let hasCorrespondingWidget = false ;
118+ if ( content . tool_use_id ) {
119+ // Look for the matching tool_use in previous assistant messages
120+ for ( let i = index - 1 ; i >= 0 ; i -- ) {
121+ const prevMsg = messages [ i ] ;
122+ if ( prevMsg . type === 'assistant' && prevMsg . message ?. content && Array . isArray ( prevMsg . message . content ) ) {
123+ const toolUse = prevMsg . message . content . find ( ( c : any ) =>
124+ c . type === 'tool_use' && c . id === content . tool_use_id
125+ ) ;
126+ if ( toolUse ) {
127+ const toolName = toolUse . name ?. toLowerCase ( ) ;
128+ const toolsWithWidgets = [
129+ 'task' , 'edit' , 'multiedit' , 'todowrite' , 'ls' , 'read' ,
130+ 'glob' , 'bash' , 'write' , 'grep'
131+ ] ;
132+ if ( toolsWithWidgets . includes ( toolName ) || toolUse . name ?. startsWith ( 'mcp__' ) ) {
133+ hasCorrespondingWidget = true ;
134+ }
135+ break ;
136+ }
137+ }
138+ }
139+ }
140+
141+ return hasCorrespondingWidget && ! content . is_error ;
142+ } ) ;
143+
144+ if ( hasOnlyHiddenToolResults ) {
145+ return false ;
146+ }
147+ }
148+ }
149+
150+ return true ;
151+ } ) ;
152+ } , [ messages ] ) ;
153+
98154 // Virtualizers for efficient, smooth scrolling of potentially very long outputs
99155 const rowVirtualizer = useVirtualizer ( {
100- count : enhancedMessages . length ,
156+ count : displayableMessages . length ,
101157 getScrollElement : ( ) => scrollContainerRef . current ,
102158 estimateSize : ( ) => 150 , // fallback estimate; dynamically measured afterwards
103159 overscan : 5 ,
104160 } ) ;
105161
106162 const fullscreenRowVirtualizer = useVirtualizer ( {
107- count : enhancedMessages . length ,
163+ count : displayableMessages . length ,
108164 getScrollElement : ( ) => fullscreenScrollRef . current ,
109165 estimateSize : ( ) => 150 ,
110166 overscan : 5 ,
@@ -132,19 +188,19 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
132188 } ;
133189
134190 useEffect ( ( ) => {
135- if ( enhancedMessages . length === 0 ) return ;
191+ if ( displayableMessages . length === 0 ) return ;
136192
137193 // Auto-scroll only if the user has not manually scrolled OR they are still at the bottom
138194 const shouldAutoScroll = ! hasUserScrolled || isAtBottom ( ) ;
139195
140196 if ( shouldAutoScroll ) {
141197 if ( isFullscreenModalOpen ) {
142- fullscreenRowVirtualizer . scrollToIndex ( enhancedMessages . length - 1 , { align : "end" , behavior : "smooth" } ) ;
198+ fullscreenRowVirtualizer . scrollToIndex ( displayableMessages . length - 1 , { align : "end" , behavior : "smooth" } ) ;
143199 } else {
144- rowVirtualizer . scrollToIndex ( enhancedMessages . length - 1 , { align : "end" , behavior : "smooth" } ) ;
200+ rowVirtualizer . scrollToIndex ( displayableMessages . length - 1 , { align : "end" , behavior : "smooth" } ) ;
145201 }
146202 }
147- } , [ enhancedMessages . length , hasUserScrolled , isFullscreenModalOpen , rowVirtualizer , fullscreenRowVirtualizer ] ) ;
203+ } , [ displayableMessages . length , hasUserScrolled , isFullscreenModalOpen , rowVirtualizer , fullscreenRowVirtualizer ] ) ;
148204
149205 // Update elapsed time while running
150206 useEffect ( ( ) => {
@@ -179,11 +235,6 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
179235 setTotalTokens ( tokens ) ;
180236 } , [ messages ] ) ;
181237
182- // Enhance messages whenever they change
183- useEffect ( ( ) => {
184- const enhanced = enhanceMessages ( messages ) ;
185- setEnhancedMessages ( enhanced ) ;
186- } , [ messages ] ) ;
187238
188239 const handleSelectPath = async ( ) => {
189240 try {
@@ -620,7 +671,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
620671 } }
621672 >
622673 < div ref = { messagesContainerRef } >
623- { enhancedMessages . length === 0 && ! isRunning && (
674+ { messages . length === 0 && ! isRunning && (
624675 < div className = "flex flex-col items-center justify-center h-full text-center" >
625676 < Terminal className = "h-16 w-16 text-muted-foreground mb-4" />
626677 < h3 className = "text-lg font-medium mb-2" > Ready to Execute</ h3 >
@@ -630,7 +681,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
630681 </ div >
631682 ) }
632683
633- { isRunning && enhancedMessages . length === 0 && (
684+ { isRunning && messages . length === 0 && (
634685 < div className = "flex items-center justify-center h-full" >
635686 < div className = "flex items-center gap-3" >
636687 < Loader2 className = "h-6 w-6 animate-spin" />
@@ -645,7 +696,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
645696 >
646697 < AnimatePresence >
647698 { rowVirtualizer . getVirtualItems ( ) . map ( ( virtualItem ) => {
648- const message = enhancedMessages [ virtualItem . index ] ;
699+ const message = displayableMessages [ virtualItem . index ] ;
649700 return (
650701 < motion . div
651702 key = { virtualItem . key }
@@ -658,7 +709,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
658709 style = { { top : virtualItem . start } }
659710 >
660711 < ErrorBoundary >
661- < StreamMessage message = { message } streamMessages = { enhancedMessages } />
712+ < StreamMessage message = { message } streamMessages = { messages } />
662713 </ ErrorBoundary >
663714 </ motion . div >
664715 ) ;
@@ -761,7 +812,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
761812 }
762813 } }
763814 >
764- { enhancedMessages . length === 0 && ! isRunning && (
815+ { messages . length === 0 && ! isRunning && (
765816 < div className = "flex flex-col items-center justify-center h-full text-center" >
766817 < Terminal className = "h-16 w-16 text-muted-foreground mb-4" />
767818 < h3 className = "text-lg font-medium mb-2" > Ready to Execute</ h3 >
@@ -771,7 +822,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
771822 </ div >
772823 ) }
773824
774- { isRunning && enhancedMessages . length === 0 && (
825+ { isRunning && messages . length === 0 && (
775826 < div className = "flex items-center justify-center h-full" >
776827 < div className = "flex items-center gap-3" >
777828 < Loader2 className = "h-6 w-6 animate-spin" />
@@ -786,7 +837,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
786837 >
787838 < AnimatePresence >
788839 { fullscreenRowVirtualizer . getVirtualItems ( ) . map ( ( virtualItem ) => {
789- const message = enhancedMessages [ virtualItem . index ] ;
840+ const message = displayableMessages [ virtualItem . index ] ;
790841 return (
791842 < motion . div
792843 key = { virtualItem . key }
@@ -799,7 +850,7 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
799850 style = { { top : virtualItem . start } }
800851 >
801852 < ErrorBoundary >
802- < StreamMessage message = { message } streamMessages = { enhancedMessages } />
853+ < StreamMessage message = { message } streamMessages = { messages } />
803854 </ ErrorBoundary >
804855 </ motion . div >
805856 ) ;
@@ -817,4 +868,4 @@ export const AgentExecution: React.FC<AgentExecutionProps> = ({
817868} ;
818869
819870// Import AGENT_ICONS for icon rendering
820- import { AGENT_ICONS } from "./CCAgents" ;
871+ import { AGENT_ICONS } from "./CCAgents" ;
0 commit comments