diff --git a/packages/cli/src/ui/components/HistoryItemDisplay.tsx b/packages/cli/src/ui/components/HistoryItemDisplay.tsx index 0ceb70f8d7..c1bdc02c75 100644 --- a/packages/cli/src/ui/components/HistoryItemDisplay.tsx +++ b/packages/cli/src/ui/components/HistoryItemDisplay.tsx @@ -50,7 +50,6 @@ interface HistoryItemDisplayProps { isFirstThinking?: boolean; isFirstAfterThinking?: boolean; isToolGroupBoundary?: boolean; - suppressNarration?: boolean; } export const HistoryItemDisplay: React.FC = ({ @@ -64,7 +63,6 @@ export const HistoryItemDisplay: React.FC = ({ isFirstThinking = false, isFirstAfterThinking = false, isToolGroupBoundary = false, - suppressNarration = false, }) => { const settings = useSettings(); const inlineThinkingMode = getInlineThinkingMode(settings); @@ -75,17 +73,6 @@ export const HistoryItemDisplay: React.FC = ({ isToolGroupBoundary ); - // If there's a topic update in this turn, we suppress the regular narration - // and thoughts as they are being "replaced" by the update_topic tool. - if ( - suppressNarration && - (itemForDisplay.type === 'thinking' || - itemForDisplay.type === 'gemini' || - itemForDisplay.type === 'gemini_content') - ) { - return null; - } - return ( = ({ borderTop={itemForDisplay.borderTop} borderBottom={itemForDisplay.borderBottom} isExpandable={isExpandable} - isToolGroupBoundary={isToolGroupBoundary} /> )} {itemForDisplay.type === 'subagent' && ( diff --git a/packages/cli/src/ui/components/MainContent.tsx b/packages/cli/src/ui/components/MainContent.tsx index b46af4965b..046550de51 100644 --- a/packages/cli/src/ui/components/MainContent.tsx +++ b/packages/cli/src/ui/components/MainContent.tsx @@ -7,7 +7,6 @@ import { Box, Static } from 'ink'; import { HistoryItemDisplay } from './HistoryItemDisplay.js'; import { useUIState } from '../contexts/UIStateContext.js'; -import { useSettings } from '../contexts/SettingsContext.js'; import { useAppContext } from '../contexts/AppContext.js'; import { AppHeader } from './AppHeader.js'; @@ -22,7 +21,6 @@ import { useMemo, memo, useCallback, useEffect, useRef } from 'react'; import { MAX_GEMINI_MESSAGE_LINES } from '../constants.js'; import { useConfirmingTool } from '../hooks/useConfirmingTool.js'; import { ToolConfirmationQueue } from './ToolConfirmationQueue.js'; -import { isTopicTool } from './messages/TopicMessage.js'; import { appEvents, AppEvent } from '../../utils/events.js'; const MemoizedHistoryItemDisplay = memo(HistoryItemDisplay); @@ -82,35 +80,6 @@ export const MainContent = () => { return -1; }, [uiState.history]); - const settings = useSettings(); - const topicUpdateNarrationEnabled = - settings.merged.experimental?.topicUpdateNarration === true; - - const suppressNarrationFlags = useMemo(() => { - const combinedHistory = [...uiState.history, ...pendingHistoryItems]; - const flags = new Array(combinedHistory.length).fill(false); - - if (topicUpdateNarrationEnabled) { - let toolGroupInTurn = false; - for (let i = combinedHistory.length - 1; i >= 0; i--) { - const item = combinedHistory[i]; - if (item.type === 'user' || item.type === 'user_shell') { - toolGroupInTurn = false; - } else if (item.type === 'tool_group') { - toolGroupInTurn = item.tools.some((t) => isTopicTool(t.name)); - } else if ( - (item.type === 'thinking' || - item.type === 'gemini' || - item.type === 'gemini_content') && - toolGroupInTurn - ) { - flags[i] = true; - } - } - } - return flags; - }, [uiState.history, pendingHistoryItems, topicUpdateNarrationEnabled]); - const augmentedHistory = useMemo( () => uiState.history.map((item, i) => { @@ -129,10 +98,9 @@ export const MainContent = () => { isFirstThinking, isFirstAfterThinking, isToolGroupBoundary, - suppressNarration: suppressNarrationFlags[i] ?? false, }; }), - [uiState.history, lastUserPromptIndex, suppressNarrationFlags], + [uiState.history, lastUserPromptIndex], ); const historyItems = useMemo( @@ -144,7 +112,6 @@ export const MainContent = () => { isFirstThinking, isFirstAfterThinking, isToolGroupBoundary, - suppressNarration, }) => ( { isFirstThinking={isFirstThinking} isFirstAfterThinking={isFirstAfterThinking} isToolGroupBoundary={isToolGroupBoundary} - suppressNarration={suppressNarration} /> ), ), @@ -201,9 +167,6 @@ export const MainContent = () => { (item.type !== 'tool_group' && prevType === 'tool_group') || (item.type === 'tool_group' && prevType !== 'tool_group'); - const suppressNarration = - suppressNarrationFlags[uiState.history.length + i] ?? false; - return ( { isFirstThinking={isFirstThinking} isFirstAfterThinking={isFirstAfterThinking} isToolGroupBoundary={isToolGroupBoundary} - suppressNarration={suppressNarration} /> ); })} @@ -237,7 +199,6 @@ export const MainContent = () => { showConfirmationQueue, confirmingTool, uiState.history, - suppressNarrationFlags, ], ); diff --git a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx index 38be3a24da..2e0406ee4e 100644 --- a/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolGroupMessage.tsx @@ -102,7 +102,6 @@ interface ToolGroupMessageProps { borderTop?: boolean; borderBottom?: boolean; isExpandable?: boolean; - isToolGroupBoundary?: boolean; } // Main component renders the border and maps the tools using ToolMessage @@ -116,7 +115,6 @@ export const ToolGroupMessage: React.FC = ({ borderTop: borderTopOverride, borderBottom: borderBottomOverride, isExpandable, - isToolGroupBoundary, }) => { const settings = useSettings(); const isLowErrorVerbosity = settings.merged.ui?.errorVerbosity !== 'full'; @@ -248,11 +246,11 @@ export const ToolGroupMessage: React.FC = ({ (showClosingBorder ? 1 : 0); } else if (isTopicToolCall) { // Topic Message Spacing Breakdown: - // 1. Top Margin (1): Present unless it's the very first item following a boundary. + // 1. Top Margin (1): Always present for spacing. // 2. Topic Content (1). // 3. Bottom Margin (1): Always present around TopicMessage for breathing room. - const hasTopMargin = !(isFirst && isToolGroupBoundary); - height += (hasTopMargin ? 1 : 0) + 1 + 1; + // 4. Closing Border (1): Added if transition logic (showClosingBorder) requires it. + height += 1 + 1 + 1 + (showClosingBorder ? 1 : 0); } else if (isCompact) { // Compact Tool: Always renders as a single dense line. height += 1; @@ -273,12 +271,7 @@ export const ToolGroupMessage: React.FC = ({ } } return height; - }, [ - groupedTools, - isCompactModeEnabled, - borderTopOverride, - isToolGroupBoundary, - ]); + }, [groupedTools, isCompactModeEnabled, borderTopOverride]); let countToolCallsWithResults = 0; for (const tool of visibleToolCalls) { @@ -446,10 +439,7 @@ export const ToolGroupMessage: React.FC = ({ {isCompact ? ( ) : isTopicToolCall ? ( - + ) : isShellToolCall ? (