mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 15:40:57 -07:00
Addressed case with 0 terminal height
This commit is contained in:
@@ -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) => (
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user