feat: prettify tool result rendering (#538)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -15,9 +15,11 @@ import {
|
||||
isFileEditTool,
|
||||
isFileReadTool,
|
||||
isFileWriteTool,
|
||||
isGlobTool,
|
||||
isMemoryTool,
|
||||
isPatchTool,
|
||||
isPlanTool,
|
||||
isSearchTool,
|
||||
isTaskTool,
|
||||
isTodoTool,
|
||||
} from "../helpers/toolNameMapping.js";
|
||||
@@ -614,6 +616,97 @@ export const ToolCallMessage = memo(
|
||||
);
|
||||
}
|
||||
|
||||
// Check if this is a search/grep tool - show line/file count summary
|
||||
if (isSearchTool(rawName) && line.resultOk !== false && line.resultText) {
|
||||
const text = line.resultText;
|
||||
// Match "Found N file(s)" at start of output (files_with_matches mode)
|
||||
const filesMatch = text.match(/^Found (\d+) files?/);
|
||||
const noFilesMatch = text === "No files found";
|
||||
const noMatchesMatch = text === "No matches found";
|
||||
|
||||
if (filesMatch?.[1]) {
|
||||
const count = parseInt(filesMatch[1], 10);
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text>
|
||||
Found <Text bold>{count}</Text> file{count !== 1 ? "s" : ""}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
} else if (noFilesMatch || noMatchesMatch) {
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text>
|
||||
Found <Text bold>0</Text> {noFilesMatch ? "files" : "matches"}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
} else {
|
||||
// Content mode - count lines in the output
|
||||
const lineCount = text.split("\n").length;
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text>
|
||||
Found <Text bold>{lineCount}</Text> line
|
||||
{lineCount !== 1 ? "s" : ""}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if this is a glob tool - show file count summary
|
||||
if (isGlobTool(rawName) && line.resultOk !== false && line.resultText) {
|
||||
const text = line.resultText;
|
||||
const filesMatch = text.match(/^Found (\d+) files?/);
|
||||
const noFilesMatch = text === "No files found";
|
||||
|
||||
if (filesMatch?.[1]) {
|
||||
const count = parseInt(filesMatch[1], 10);
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text>
|
||||
Found <Text bold>{count}</Text> file{count !== 1 ? "s" : ""}
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
} else if (noFilesMatch) {
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Box width={prefixWidth} flexShrink={0}>
|
||||
<Text>{prefix}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text>
|
||||
Found <Text bold>0</Text> files
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
// Fall through to default if no match pattern found
|
||||
}
|
||||
|
||||
// Regular result handling
|
||||
const isError = line.resultOk === false;
|
||||
|
||||
|
||||
@@ -210,3 +210,29 @@ export function isShellTool(name: string): boolean {
|
||||
n === "runshellcommand"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a tool is a search/grep tool
|
||||
*/
|
||||
export function isSearchTool(name: string): boolean {
|
||||
return (
|
||||
name === "grep" ||
|
||||
name === "Grep" ||
|
||||
name === "grep_files" ||
|
||||
name === "GrepFiles" ||
|
||||
name === "search_file_content" ||
|
||||
name === "SearchFileContent"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a tool is a glob tool
|
||||
*/
|
||||
export function isGlobTool(name: string): boolean {
|
||||
return (
|
||||
name === "glob" ||
|
||||
name === "Glob" ||
|
||||
name === "glob_gemini" ||
|
||||
name === "GlobGemini"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user