feat: support structured tool results and preserve terminal state context

Establishes core data contracts and state management for enhanced tool outputs.
- Introduces GrepResult, ListDirectoryResult, and ReadManyFilesResult types.
- Updates tools to return structured data instead of flat strings.
- Preserves confirmation details and diff stats in terminal tool states.
- Ensures backward compatibility in standard CLI views via safe type guards.
This commit is contained in:
Jarrod Whelan
2026-02-10 20:23:18 -08:00
parent 204d62980f
commit 2db8fb20fa
11 changed files with 133 additions and 9 deletions

View File

@@ -82,10 +82,26 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
);
const truncatedResultDisplay = React.useMemo(() => {
// Helper to handle structured objects that should be displayed as strings
// in the main view (grep, ls, read-many-files).
let displayContent: string | object | undefined = resultDisplay;
if (typeof resultDisplay === 'object' && resultDisplay !== null) {
// Use a type-safe check for structured results that contain a summary
// (e.g. GrepResult, ListDirectoryResult, ReadManyFilesResult)
const hasSummary = (obj: object): obj is { summary: string } =>
'summary' in obj &&
typeof (obj as { summary?: unknown }).summary === 'string';
if (hasSummary(resultDisplay)) {
displayContent = resultDisplay.summary;
}
}
// Only truncate string output if not in alternate buffer mode to ensure
// we can scroll through the full output.
if (typeof resultDisplay === 'string' && !isAlternateBuffer) {
let text = resultDisplay;
if (typeof displayContent === 'string' && !isAlternateBuffer) {
let text = displayContent;
if (text.length > MAXIMUM_RESULT_DISPLAY_CHARACTERS) {
text = '...' + text.slice(-MAXIMUM_RESULT_DISPLAY_CHARACTERS);
}
@@ -101,7 +117,7 @@ export const ToolResultDisplay: React.FC<ToolResultDisplayProps> = ({
}
return text;
}
return resultDisplay;
return displayContent;
}, [resultDisplay, isAlternateBuffer, maxLines]);
if (!truncatedResultDisplay) return null;

View File

@@ -15,11 +15,23 @@ import type {
RetrieveUserQuotaResponse,
SkillDefinition,
AgentDefinition,
GrepResult,
ListDirectoryResult,
ReadManyFilesResult,
FileDiff,
} from '@google/gemini-cli-core';
import type { PartListUnion } from '@google/genai';
import { type ReactNode } from 'react';
export type { ThoughtSummary, SkillDefinition, ToolResultDisplay };
export type {
ThoughtSummary,
SkillDefinition,
ToolResultDisplay,
GrepResult,
ListDirectoryResult,
ReadManyFilesResult,
FileDiff,
};
export enum AuthState {
// Attempting to authenticate or re-authenticate