Addressed case with 0 terminal height

This commit is contained in:
Dev Randalpura
2026-03-12 14:27:32 -05:00
parent d2e5ae7750
commit 558f1c96c7
4 changed files with 36 additions and 41 deletions

View File

@@ -35,7 +35,11 @@ export const AnsiOutputText: React.FC<AnsiOutputProps> = ({
? Math.min(availableHeightLimit, maxLines)
: (availableHeightLimit ?? maxLines ?? DEFAULT_HEIGHT);
const lastLines = disableTruncation ? data : data.slice(-numLinesRetained);
const lastLines = disableTruncation
? data
: numLinesRetained === 0
? []
: data.slice(-numLinesRetained);
return (
<Box flexDirection="column" width={width} flexShrink={0} overflow="hidden">
{lastLines.map((line: AnsiLine, lineIndex: number) => (

View File

@@ -87,7 +87,7 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
if (text.length > MAXIMUM_RESULT_DISPLAY_CHARACTERS) {
text = '...' + text.slice(-MAXIMUM_RESULT_DISPLAY_CHARACTERS);
}
if (maxLines) {
if (maxLines !== undefined) {
const hasTrailingNewline = text.endsWith('\n');
const contentText = hasTrailingNewline ? text.slice(0, -1) : text;
const lines = contentText.split('\n');
@@ -103,7 +103,11 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
return { truncatedResultDisplay: text, hiddenLinesCount: hiddenLines };
}
if (Array.isArray(resultDisplay) && !isAlternateBuffer && maxLines) {
if (
Array.isArray(resultDisplay) &&
!isAlternateBuffer &&
maxLines !== undefined
) {
if (resultDisplay.length > maxLines) {
// We will have a label from MaxSizedBox. Reserve space for it.
const targetLines = Math.max(1, maxLines - 1);

View File

@@ -8,8 +8,6 @@ import { describe, it, expect } from 'vitest';
import {
calculateToolContentMaxLines,
calculateShellMaxLines,
TOOL_RESULT_STATIC_HEIGHT,
TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT,
} from './toolLayoutUtils.js';
import { CoreToolCallStatus } from '@google/gemini-cli-core';
import {
@@ -36,26 +34,26 @@ describe('toolLayoutUtils', () => {
expect(result).toBe(10);
});
it('caps height to prevent overflow in constrained terminal (Standard mode)', () => {
it('returns available space directly in constrained terminal (Standard mode)', () => {
const availableTerminalHeight = 2; // Very small
const result = calculateToolContentMaxLines({
availableTerminalHeight,
isAlternateBuffer: false,
});
// Math.max(0, 2 - 1 - 2) = 0
expect(result).toBe(0);
// Math.max(0, 2) = 2
expect(result).toBe(2);
});
it('caps height to prevent overflow in constrained terminal (ASB mode)', () => {
it('returns available space directly in constrained terminal (ASB mode)', () => {
const availableTerminalHeight = 4; // Very small
const result = calculateToolContentMaxLines({
availableTerminalHeight,
isAlternateBuffer: true,
});
// Math.max(0, 4 - 1 - 6) = 0
expect(result).toBe(0);
// Math.max(0, 4) = 4
expect(result).toBe(4);
});
it('returns remaining space if sufficient space exists (Standard mode)', () => {
@@ -65,8 +63,8 @@ describe('toolLayoutUtils', () => {
isAlternateBuffer: false,
});
// Space remaining is 20 - 1 - 2 = 17
expect(result).toBe(17);
// Math.max(0, 20) = 20
expect(result).toBe(20);
});
it('returns remaining space if sufficient space exists (ASB mode)', () => {
@@ -76,19 +74,8 @@ describe('toolLayoutUtils', () => {
isAlternateBuffer: true,
});
// Space remaining is 20 - 1 - 6 = 13
expect(result).toBe(13);
});
it('returns 0 if availableTerminalHeight is <= TOOL_RESULT_STATIC_HEIGHT + reservedLines', () => {
const result = calculateToolContentMaxLines({
availableTerminalHeight:
TOOL_RESULT_STATIC_HEIGHT + TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT,
isAlternateBuffer: false,
});
// Cap at 3 - 1 - 2 = 0
expect(result).toBe(0);
// Math.max(0, 20) = 20
expect(result).toBe(20);
});
});
@@ -129,32 +116,32 @@ describe('toolLayoutUtils', () => {
expect(result).toBeUndefined();
});
it('handles small availableTerminalHeight gracefully to prevent overflow in Standard mode', () => {
it('handles small availableTerminalHeight gracefully without overflow in Standard mode', () => {
const result = calculateShellMaxLines({
status: CoreToolCallStatus.Executing,
isAlternateBuffer: false,
isThisShellFocused: false,
availableTerminalHeight: 2, // Too small to subtract 1 + 2
availableTerminalHeight: 2,
constrainHeight: true,
isExpandable: false,
});
// Math.max(0, 2 - 1 - 2) = 0
expect(result).toBe(0);
// Math.max(0, 2) = 2
expect(result).toBe(2);
});
it('handles small availableTerminalHeight gracefully to prevent overflow in ASB mode', () => {
it('handles small availableTerminalHeight gracefully without overflow in ASB mode', () => {
const result = calculateShellMaxLines({
status: CoreToolCallStatus.Executing,
isAlternateBuffer: true,
isThisShellFocused: false,
availableTerminalHeight: 6, // Too small to subtract 1 + 6
availableTerminalHeight: 6,
constrainHeight: true,
isExpandable: false,
});
// Math.max(0, 6 - 1 - 6) = 0
expect(result).toBe(0);
// Math.max(0, 6) = 6
expect(result).toBe(6);
});
it('handles negative availableTerminalHeight gracefully', () => {
@@ -180,8 +167,8 @@ describe('toolLayoutUtils', () => {
isExpandable: false,
});
// 30 - 1 (static) - 6 (ASB reserved) = 23
expect(result).toBe(23);
// 30
expect(result).toBe(30);
});
it('falls back to COMPLETED_SHELL_MAX_LINES for completed shells if space allows', () => {

View File

@@ -15,7 +15,6 @@ import { CoreToolCallStatus } from '@google/gemini-cli-core';
* These MUST be kept in sync between ToolGroupMessage (for overflow detection)
* and ToolResultDisplay (for actual truncation).
*/
export const TOOL_RESULT_STATIC_HEIGHT = 1;
export const TOOL_RESULT_ASB_RESERVED_LINE_COUNT = 6;
export const TOOL_RESULT_STANDARD_RESERVED_LINE_COUNT = 2;
export const TOOL_RESULT_MIN_LINES_SHOWN = 2;
@@ -35,9 +34,10 @@ export function calculateToolContentMaxLines(options: {
}): number | undefined {
const { availableTerminalHeight, maxLinesLimit } = options;
let contentHeight = availableTerminalHeight
? Math.max(TOOL_RESULT_STATIC_HEIGHT, availableTerminalHeight)
: undefined;
let contentHeight =
availableTerminalHeight !== undefined
? Math.max(0, availableTerminalHeight)
: undefined;
if (maxLinesLimit) {
contentHeight =
@@ -84,7 +84,7 @@ export function calculateShellMaxLines(options: {
return isAlternateBuffer ? ACTIVE_SHELL_MAX_LINES : undefined;
}
const maxLinesBasedOnHeight = Math.max(1, availableTerminalHeight);
const maxLinesBasedOnHeight = Math.max(0, availableTerminalHeight);
// 3. Handle ASB mode focus expansion.
// We allow a focused shell in ASB mode to take up the full available height,