diff --git a/ui/desktop/src/components/ProgressiveMessageList.tsx b/ui/desktop/src/components/ProgressiveMessageList.tsx index 4386f38e6518..5c84cc657ed5 100644 --- a/ui/desktop/src/components/ProgressiveMessageList.tsx +++ b/ui/desktop/src/components/ProgressiveMessageList.tsx @@ -62,8 +62,6 @@ export default function ProgressiveMessageList({ const [isLoading, setIsLoading] = useState(() => messages.length > showLoadingThreshold); const timeoutRef = useRef(null); const mountedRef = useRef(true); - const hasOnlyToolResponses = (message: Message) => - message.content.every((c) => c.type === 'toolResponse'); // Try to use context manager, but don't require it for session history let hasContextHandlerContent: ((message: Message) => boolean) | undefined; @@ -201,7 +199,7 @@ export default function ProgressiveMessageList({ }} /> ) : ( - !hasOnlyToolResponses(message) && + )} ) : ( diff --git a/ui/desktop/src/components/sessions/SessionHistoryView.tsx b/ui/desktop/src/components/sessions/SessionHistoryView.tsx index e2bc544d7478..58b40d218bd5 100644 --- a/ui/desktop/src/components/sessions/SessionHistoryView.tsx +++ b/ui/desktop/src/components/sessions/SessionHistoryView.tsx @@ -43,8 +43,29 @@ const isUserMessage = (message: Message): boolean => { return true; }; +// Filter messages for display (same logic as useChatEngine) const filterMessagesForDisplay = (messages: Message[]): Message[] => { - return messages.filter((message) => message.display); + return messages.filter((message) => { + // Only filter out when display is explicitly false + if (message.display === false) return false; + + // Keep all assistant messages and user messages that aren't just tool responses + if (message.role === 'assistant') return true; + + // For user messages, check if they're only tool responses + if (message.role === 'user') { + const hasOnlyToolResponses = message.content.every((c) => c.type === 'toolResponse'); + const hasTextContent = message.content.some((c) => c.type === 'text'); + const hasToolConfirmation = message.content.every( + (c) => c.type === 'toolConfirmationRequest' + ); + + // Keep the message if it has text content or tool confirmation or is not just tool responses + return hasTextContent || !hasOnlyToolResponses || hasToolConfirmation; + } + + return true; + }); }; interface SessionHistoryViewProps { diff --git a/ui/desktop/src/hooks/useChatEngine.ts b/ui/desktop/src/hooks/useChatEngine.ts index c852b1699c7c..e8b16d50d9d6 100644 --- a/ui/desktop/src/hooks/useChatEngine.ts +++ b/ui/desktop/src/hooks/useChatEngine.ts @@ -326,8 +326,29 @@ export const useChatEngine = ({ } }, [stop, messages, _setInput, setMessages]); + // Filter out standalone tool response messages for rendering const filteredMessages = useMemo(() => { - return [...ancestorMessages, ...messages].filter((message) => message.display); + return [...ancestorMessages, ...messages].filter((message) => { + // Only filter out when display is explicitly false + if (message.display === false) return false; + + // Keep all assistant messages and user messages that aren't just tool responses + if (message.role === 'assistant') return true; + + // For user messages, check if they're only tool responses + if (message.role === 'user') { + const hasOnlyToolResponses = message.content.every((c) => c.type === 'toolResponse'); + const hasTextContent = message.content.some((c) => c.type === 'text'); + const hasToolConfirmation = message.content.every( + (c) => c.type === 'toolConfirmationRequest' + ); + + // Keep the message if it has text content or tool confirmation or is not just tool responses + return hasTextContent || !hasOnlyToolResponses || hasToolConfirmation; + } + + return true; + }); }, [ancestorMessages, messages]); // Generate command history from filtered messages