Skip to content

Commit 797ecec

Browse files
committed
fix(ui): synchronize ToolGroupMessage static height calculation with rendering (address review feedback)
- Updates staticHeight to account for all rendered lines and boundaries. - Use layout constants TOOL_RESULT_STATIC_HEIGHT and TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT for height logic. - Update comments to exhaustively explain the line count breakdown for all message types.
1 parent fe9a429 commit 797ecec

File tree

1 file changed

+42
-26
lines changed

1 file changed

+42
-26
lines changed

packages/cli/src/ui/components/messages/ToolGroupMessage.tsx

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,6 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
221221

222222
const staticHeight = useMemo(() => {
223223
let height = 0;
224-
// To match rendering, we track if all tools so far have been topics
225-
let allPreviousWereTopics = true;
226224

227225
for (let i = 0; i < groupedTools.length; i++) {
228226
const group = groupedTools[i];
@@ -251,47 +249,65 @@ export const ToolGroupMessage: React.FC<ToolGroupMessageProps> = ({
251249
// Align isFirst logic with rendering
252250
let isFirst = i === 0;
253251
if (!isFirst) {
254-
isFirst = allPreviousWereTopics;
255-
}
256-
257-
// Update state for next tool
258-
if (isAgentGroup || !isTopicToolCall) {
259-
allPreviousWereTopics = false;
252+
// Check if all previous tools were topics (matches rendering logic exactly)
253+
let allPreviousTopics = true;
254+
for (let j = 0; j < i; j++) {
255+
const prevGroupItem = groupedTools[j];
256+
if (
257+
Array.isArray(prevGroupItem) ||
258+
!isTopicTool(prevGroupItem.name)
259+
) {
260+
allPreviousTopics = false;
261+
break;
262+
}
263+
}
264+
isFirst = allPreviousTopics;
260265
}
261266

262267
const isFirstProp = !!(isFirst
263268
? (borderTopOverride ?? true)
264269
: prevIsCompact);
265270

266-
// Align closing border logic
267271
const showClosingBorder =
268272
!isCompact &&
269273
!isTopicToolCall &&
270274
(nextIsCompact || nextIsTopicToolCall || isLast);
271275

272276
if (isAgentGroup) {
273-
height += 1; // Header
274-
height += group.length; // 1 line per agent
275-
if (isFirstProp) height += 1; // Top border
276-
if (showClosingBorder) height += 1; // Bottom border
277+
// Agent Group Spacing Breakdown:
278+
// 1. Top Boundary (0 or 1): Only present via borderTop if isFirstProp is true.
279+
// 2. Header Content (1): The "≡ Running Agent..." status text.
280+
// 3. Agent List (group.length lines): One line per agent in the group.
281+
// 4. Closing Border (1): Added if transition logic (showClosingBorder) requires it.
282+
height +=
283+
(isFirstProp ? 1 : 0) +
284+
1 +
285+
group.length +
286+
(showClosingBorder ? 1 : 0);
277287
} else if (isTopicToolCall) {
288+
// Topic Message Spacing Breakdown:
289+
// 1. Top Margin (1): Present unless it's the very first item following a boundary.
290+
// 2. Topic Content (1).
291+
// 3. Bottom Margin (1): Always present around TopicMessage for breathing room.
278292
const hasTopMargin = !(isFirst && isToolGroupBoundary);
279-
height += 1 + (hasTopMargin ? 1 : 0) + 1; // TopicMessage + top/bottom padding
293+
height += (hasTopMargin ? 1 : 0) + 1 + 1;
280294
} else if (isCompact) {
281-
height += 1; // Base height for compact tool header
295+
// Compact Tool: Always renders as a single dense line.
296+
height += 1;
282297
} else {
283-
// Standard tool (Shell or ToolMessage)
284-
if (isFirstProp) height += 1; // StickyHeader borderTop
285-
298+
// Standard Tool (ToolMessage / ShellToolMessage) Spacing Breakdown:
299+
// 1. TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT (4) accounts for the top boundary,
300+
// internal separator, header padding, and the group closing border.
301+
// (Subtract 1 to isolate the group-level closing border.)
302+
// 2. Header Content (1): TOOL_RESULT_STATIC_HEIGHT (the tool name/status).
303+
// 3. Output File Message (1): (conditional) if outputFile is present.
304+
// 4. Group Closing Border (1): (conditional) if transition logic (showClosingBorder) requires it.
286305
height +=
287-
TOOL_RESULT_STATIC_HEIGHT + TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT;
288-
289-
// Account for "Output saved to..." message
290-
if (group.outputFile) {
291-
height += 1;
292-
}
293-
294-
if (showClosingBorder) height += 1; // Bottom border
306+
TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT -
307+
1 +
308+
TOOL_RESULT_STATIC_HEIGHT +
309+
(group.outputFile ? 1 : 0) +
310+
(showClosingBorder ? 1 : 0);
295311
}
296312
}
297313
return height;

0 commit comments

Comments
 (0)