feat(core): improve subagent result display (#20378)

This commit is contained in:
joshualitt
2026-03-09 12:20:15 -07:00
committed by GitHub
parent d246315cea
commit a17691f0fc
21 changed files with 925 additions and 238 deletions
@@ -9,7 +9,11 @@ import { ToolMessage, type ToolMessageProps } from './ToolMessage.js';
import { describe, it, expect, vi } from 'vitest';
import { StreamingState } from '../../types.js';
import { Text } from 'ink';
import { type AnsiOutput, CoreToolCallStatus } from '@google/gemini-cli-core';
import {
type AnsiOutput,
CoreToolCallStatus,
Kind,
} from '@google/gemini-cli-core';
import { renderWithProviders } from '../../../test-utils/render.js';
import { tryParseJSON } from '../../../utils/jsonoutput.js';
@@ -435,4 +439,99 @@ describe('<ToolMessage />', () => {
expect(output).toMatchSnapshot();
unmount();
});
describe('Truncation', () => {
it('applies truncation for Kind.Agent when availableTerminalHeight is provided', async () => {
const multilineString = Array.from(
{ length: 30 },
(_, i) => `Line ${i + 1}`,
).join('\n');
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ToolMessage
{...baseProps}
kind={Kind.Agent}
resultDisplay={multilineString}
renderOutputAsMarkdown={false}
availableTerminalHeight={40}
/>,
{
uiActions,
uiState: {
streamingState: StreamingState.Idle,
constrainHeight: true,
},
width: 80,
useAlternateBuffer: false,
},
);
await waitUntilReady();
const output = lastFrame();
// Since kind=Kind.Agent and availableTerminalHeight is provided, it should truncate to SUBAGENT_MAX_LINES (15)
// and show the FIRST lines (overflowDirection='bottom')
expect(output).toContain('Line 1');
expect(output).toContain('Line 14');
expect(output).not.toContain('Line 16');
expect(output).not.toContain('Line 30');
unmount();
});
it('does NOT apply truncation for Kind.Agent when availableTerminalHeight is undefined', async () => {
const multilineString = Array.from(
{ length: 30 },
(_, i) => `Line ${i + 1}`,
).join('\n');
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ToolMessage
{...baseProps}
kind={Kind.Agent}
resultDisplay={multilineString}
renderOutputAsMarkdown={false}
availableTerminalHeight={undefined}
/>,
{
uiActions,
uiState: { streamingState: StreamingState.Idle },
width: 80,
useAlternateBuffer: false,
},
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Line 1');
expect(output).toContain('Line 30');
unmount();
});
it('does NOT apply truncation for Kind.Read', async () => {
const multilineString = Array.from(
{ length: 30 },
(_, i) => `Line ${i + 1}`,
).join('\n');
const { lastFrame, waitUntilReady, unmount } = renderWithProviders(
<ToolMessage
{...baseProps}
kind={Kind.Read}
resultDisplay={multilineString}
renderOutputAsMarkdown={false}
/>,
{
uiActions,
uiState: { streamingState: StreamingState.Idle },
width: 80,
useAlternateBuffer: false,
},
);
await waitUntilReady();
const output = lastFrame();
expect(output).toContain('Line 1');
expect(output).toContain('Line 30');
unmount();
});
});
});