summarizeToolResult function
Short result lines shown under a finished tool call, unstyled except for errors.
Implementation
List<String> summarizeToolResult(String name, String output, {required bool isError}) {
final text = output.trim();
if (isError) {
final message = text.startsWith('Error: ') ? text.substring(7) : text;
if (message.startsWith('The user declined')) {
return <String>[Style.red('User declined')];
}
return _fold(_nonEmptyLines(message)).map(Style.red).toList();
}
if (text.isEmpty) {
return const <String>['(No content)'];
}
switch (name) {
case 'read':
final count = RegExp(r'^\s*\d+\t', multiLine: true).allMatches(text).length;
return count == 0 ? <String>[_firstLine(text)] : <String>['Read ${_plural(count, 'line')}'];
case 'write':
final match = RegExp(r'^(Created|Overwrote) .* \((\d+) lines\)\.$').firstMatch(text);
if (match != null) {
return <String>['Wrote ${_plural(int.parse(match[2]!), 'line')}'];
}
case 'edit':
final snippet = text.indexOf('\n');
if (snippet >= 0) {
final lines = text.substring(snippet + 1).split('\n').map((line) => line.replaceFirst('\t', ' '));
return _fold(lines.toList()).map(Style.dim).toList();
}
if (text.startsWith('Replaced ')) {
return <String>[text.substring(0, text.indexOf(' in ')).replaceFirst('Replaced', 'Updated')];
}
case 'bash' || 'powershell':
return _summarizeCommand(text);
case 'glob':
if (text != 'No files found.') {
return <String>['Found ${_plural(_listedLines(text), 'file')}'];
}
case 'grep':
if (text != 'No matches found.') {
return <String>['Found ${_plural(_listedLines(text), 'line')}'];
}
}
return <String>[_firstLine(text)];
}