diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/ExecuteToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/ExecuteToolCall.tsx index 6e8aef89..283b6dd6 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/ExecuteToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/ExecuteToolCall.tsx @@ -8,63 +8,82 @@ import type React from 'react'; import type { BaseToolCallProps } from './shared/types.js'; -import { - ToolCallCard, - ToolCallRow, - StatusIndicator, - CodeBlock, -} from './shared/LayoutComponents.js'; -import { formatValue, safeTitle, groupContent } from './shared/utils.js'; +import { ToolCallCard, ToolCallRow } from './shared/LayoutComponents.js'; +import { safeTitle, groupContent } from './shared/utils.js'; /** * Specialized component for Execute tool calls * Optimized for displaying command execution with stdout/stderr + * Shows command + output (if any) or error */ export const ExecuteToolCall: React.FC = ({ toolCall }) => { - const { title, status, rawInput, content } = toolCall; - const titleText = safeTitle(title); + const { title, content } = toolCall; + const commandText = safeTitle(title); // Group content by type - const { textOutputs, errors, otherData } = groupContent(content); + const { textOutputs, errors } = groupContent(content); - return ( - - {/* Title row */} - - - - - {/* Command */} - {rawInput && ( + // Error case: show command + error + if (errors.length > 0) { + return ( + - {formatValue(rawInput)} - - )} - - {/* Standard output */} - {textOutputs.length > 0 && ( - - {textOutputs.join('\n')} - - )} - - {/* Standard error / Errors */} - {errors.length > 0 && ( - -
- {errors.join('\n')} +
+ {commandText}
- )} - - {/* Exit code or other execution details */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - + +
+ {errors.join('\n')} +
- )} + + ); + } + + // Success with output: show command + output (limited) + if (textOutputs.length > 0) { + const output = textOutputs.join('\n'); + const truncatedOutput = + output.length > 500 ? output.substring(0, 500) + '...' : output; + + return ( + + +
+ {commandText} +
+
+ +
+ {truncatedOutput} +
+
+
+ ); + } + + // Success without output: show command only + return ( + + +
+ {commandText} +
+
); }; diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/GenericToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/GenericToolCall.tsx index 47d40ab2..960e4ac5 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/GenericToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/GenericToolCall.tsx @@ -11,86 +11,114 @@ import type { BaseToolCallProps } from './shared/types.js'; import { ToolCallCard, ToolCallRow, - StatusIndicator, - CodeBlock, LocationsList, } from './shared/LayoutComponents.js'; import { DiffDisplay } from './shared/DiffDisplay.js'; -import { - formatValue, - safeTitle, - getKindIcon, - groupContent, -} from './shared/utils.js'; +import { safeTitle, groupContent } from './shared/utils.js'; +import { useVSCode } from '../../hooks/useVSCode.js'; /** * Generic tool call component that can display any tool call type * Used as fallback for unknown tool call kinds + * Minimal display: show description and outcome */ export const GenericToolCall: React.FC = ({ toolCall }) => { - const { kind, title, status, rawInput, content, locations } = toolCall; - const kindIcon = getKindIcon(kind); - const titleText = safeTitle(title); + const { kind, title, content, locations } = toolCall; + const operationText = safeTitle(title); + const vscode = useVSCode(); // Group content by type - const { textOutputs, errors, diffs, otherData } = groupContent(content); + const { textOutputs, errors, diffs } = groupContent(content); - return ( - - {/* Title row */} - - - + const handleOpenDiff = ( + path: string | undefined, + oldText: string | null | undefined, + newText: string | undefined, + ) => { + if (path) { + vscode.postMessage({ + type: 'openDiff', + data: { path, oldText: oldText || '', newText: newText || '' }, + }); + } + }; - {/* Input row */} - {rawInput && ( - - {formatValue(rawInput)} + // Error case: show operation + error + if (errors.length > 0) { + return ( + + +
{operationText}
- )} + +
+ {errors.join('\n')} +
+
+
+ ); + } - {/* Locations row */} - {locations && locations.length > 0 && ( - + // Success with diff: show diff + if (diffs.length > 0) { + return ( + + {diffs.map( + (item: import('./shared/types.js').ToolCallContent, idx: number) => ( +
+ + handleOpenDiff(item.path, item.oldText, item.newText) + } + /> +
+ ), + )} +
+ ); + } + + // Success with output: show operation + output (truncated) + if (textOutputs.length > 0) { + const output = textOutputs.join('\n'); + const truncatedOutput = + output.length > 300 ? output.substring(0, 300) + '...' : output; + + return ( + + +
{operationText}
+
+ +
+ {truncatedOutput} +
+
+
+ ); + } + + // Success with files: show operation + file list + if (locations && locations.length > 0) { + return ( + + - )} + + ); + } - {/* Output row - combined text outputs */} - {textOutputs.length > 0 && ( - - {textOutputs.join('\n')} - - )} - - {/* Error row - combined errors */} - {errors.length > 0 && ( - -
{errors.join('\n')}
-
- )} - - {/* Diff rows */} - {diffs.map( - (item: import('./shared/types.js').ToolCallContent, idx: number) => ( - - - - ), - )} - - {/* Other data rows */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - - - )} -
- ); + // No output + return null; }; diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/ReadToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/ReadToolCall.tsx index 5190d960..2b64ed1d 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/ReadToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/ReadToolCall.tsx @@ -11,66 +11,45 @@ import type { BaseToolCallProps } from './shared/types.js'; import { ToolCallCard, ToolCallRow, - StatusIndicator, - CodeBlock, LocationsList, } from './shared/LayoutComponents.js'; -import { formatValue, safeTitle, groupContent } from './shared/utils.js'; +import { groupContent } from './shared/utils.js'; /** * Specialized component for Read tool calls * Optimized for displaying file reading operations + * Minimal display: just show file name, hide content (too verbose) */ export const ReadToolCall: React.FC = ({ toolCall }) => { - const { title, status, rawInput, content, locations } = toolCall; - const titleText = safeTitle(title); + const { content, locations } = toolCall; // Group content by type - const { textOutputs, errors, otherData } = groupContent(content); + const { errors } = groupContent(content); - return ( - - {/* Title row */} - - - + // Error case: show error with operation label + if (errors.length > 0) { + return ( + + +
+ {errors.join('\n')} +
+
+
+ ); + } - {/* File path(s) */} - {locations && locations.length > 0 && ( - + // Success case: show which file was read + if (locations && locations.length > 0) { + return ( + + - )} + + ); + } - {/* Input parameters (e.g., line range, offset) */} - {rawInput && ( - - {formatValue(rawInput)} - - )} - - {/* File content output */} - {textOutputs.length > 0 && ( - - {textOutputs.join('\n')} - - )} - - {/* Error handling */} - {errors.length > 0 && ( - -
{errors.join('\n')}
-
- )} - - {/* Other data */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - - - )} -
- ); + // No file info, don't show + return null; }; diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/SearchToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/SearchToolCall.tsx index 45bef89e..f3028083 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/SearchToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/SearchToolCall.tsx @@ -11,66 +11,56 @@ import type { BaseToolCallProps } from './shared/types.js'; import { ToolCallCard, ToolCallRow, - StatusIndicator, - CodeBlock, LocationsList, } from './shared/LayoutComponents.js'; -import { formatValue, safeTitle, groupContent } from './shared/utils.js'; +import { safeTitle, groupContent } from './shared/utils.js'; /** * Specialized component for Search tool calls * Optimized for displaying search operations and results + * Shows query + result count or file list */ export const SearchToolCall: React.FC = ({ toolCall }) => { - const { title, status, rawInput, content, locations } = toolCall; - const titleText = safeTitle(title); + const { title, content, locations } = toolCall; + const queryText = safeTitle(title); // Group content by type - const { textOutputs, errors, otherData } = groupContent(content); + const { errors } = groupContent(content); - return ( - - {/* Title row */} - - - - - {/* Search query/pattern */} - {rawInput && ( - - {formatValue(rawInput)} + // Error case: show search query + error + if (errors.length > 0) { + return ( + + +
+ {queryText} +
- )} + +
+ {errors.join('\n')} +
+
+
+ ); + } - {/* Search results - files found */} - {locations && locations.length > 0 && ( - + // Success case with results: show search query + file list + if (locations && locations.length > 0) { + return ( + + +
+ {queryText} +
+
+ - )} +
+ ); + } - {/* Search output details */} - {textOutputs.length > 0 && ( - - {textOutputs.join('\n')} - - )} - - {/* Error handling */} - {errors.length > 0 && ( - -
{errors.join('\n')}
-
- )} - - {/* Other search metadata */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - - - )} -
- ); + // No results + return null; }; diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/ThinkToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/ThinkToolCall.tsx index e25f11ba..58bf20f3 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/ThinkToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/ThinkToolCall.tsx @@ -8,63 +8,56 @@ import type React from 'react'; import type { BaseToolCallProps } from './shared/types.js'; -import { - ToolCallCard, - ToolCallRow, - StatusIndicator, - CodeBlock, -} from './shared/LayoutComponents.js'; -import { formatValue, safeTitle, groupContent } from './shared/utils.js'; +import { ToolCallCard, ToolCallRow } from './shared/LayoutComponents.js'; +import { groupContent } from './shared/utils.js'; /** * Specialized component for Think tool calls * Optimized for displaying AI reasoning and thought processes + * Minimal display: just show the thoughts (no context) */ export const ThinkToolCall: React.FC = ({ toolCall }) => { - const { title, status, rawInput, content } = toolCall; - const titleText = safeTitle(title); + const { content } = toolCall; // Group content by type - const { textOutputs, errors, otherData } = groupContent(content); + const { textOutputs, errors } = groupContent(content); - return ( - - {/* Title row */} - - - - - {/* Thinking context/prompt */} - {rawInput && ( - - {formatValue(rawInput)} - - )} - - {/* Thought content */} - {textOutputs.length > 0 && ( - -
- {textOutputs.join('\n\n')} + // Error case (rare for thinking) + if (errors.length > 0) { + return ( + + +
+ {errors.join('\n')}
- )} +
+ ); + } - {/* Error handling */} - {errors.length > 0 && ( - -
{errors.join('\n')}
-
- )} + // Show thoughts with label + if (textOutputs.length > 0) { + const thoughts = textOutputs.join('\n\n'); + const truncatedThoughts = + thoughts.length > 500 ? thoughts.substring(0, 500) + '...' : thoughts; - {/* Other reasoning data */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - + return ( + + +
+ {truncatedThoughts} +
- )} -
- ); + + ); + } + + // Empty thoughts + return null; }; diff --git a/packages/vscode-ide-companion/src/webview/components/toolcalls/WriteToolCall.tsx b/packages/vscode-ide-companion/src/webview/components/toolcalls/WriteToolCall.tsx index 2f13a2dd..1e50b063 100644 --- a/packages/vscode-ide-companion/src/webview/components/toolcalls/WriteToolCall.tsx +++ b/packages/vscode-ide-companion/src/webview/components/toolcalls/WriteToolCall.tsx @@ -11,26 +11,24 @@ import type { BaseToolCallProps } from './shared/types.js'; import { ToolCallCard, ToolCallRow, - StatusIndicator, - CodeBlock, LocationsList, } from './shared/LayoutComponents.js'; import { DiffDisplay } from './shared/DiffDisplay.js'; -import { formatValue, safeTitle, groupContent } from './shared/utils.js'; +import { groupContent } from './shared/utils.js'; import { useVSCode } from '../../hooks/useVSCode.js'; /** * Specialized component for Write/Edit tool calls * Optimized for displaying file writing and editing operations with diffs + * Follows minimal display principle: only show what matters */ export const WriteToolCall: React.FC = ({ toolCall }) => { - const { kind, title, status, rawInput, content, locations } = toolCall; - const titleText = safeTitle(title); + const { kind, status: _status, content, locations } = toolCall; const isEdit = kind.toLowerCase() === 'edit'; const vscode = useVSCode(); // Group content by type - const { textOutputs, errors, diffs, otherData } = groupContent(content); + const { errors, diffs } = groupContent(content); const handleOpenDiff = ( path: string | undefined, @@ -45,65 +43,52 @@ export const WriteToolCall: React.FC = ({ toolCall }) => { } }; - return ( - - {/* Title row */} - - - + // Error case: show error with operation label + if (errors.length > 0) { + return ( + + +
+ {errors.join('\n')} +
+
+
+ ); + } - {/* File path(s) */} - {locations && locations.length > 0 && ( - + // Success case with diff: show diff (already has file path) + if (diffs.length > 0) { + return ( + + {diffs.map( + (item: import('./shared/types.js').ToolCallContent, idx: number) => ( +
+ + handleOpenDiff(item.path, item.oldText, item.newText) + } + /> +
+ ), + )} +
+ ); + } + + // Success case without diff: show operation + file + if (locations && locations.length > 0) { + return ( + + - )} + + ); + } - {/* Input parameters (e.g., old_string, new_string for edits) */} - {rawInput && ( - - {formatValue(rawInput)} - - )} - - {/* Diff display - most important for write/edit operations */} - {diffs.map( - (item: import('./shared/types.js').ToolCallContent, idx: number) => ( - - - handleOpenDiff(item.path, item.oldText, item.newText) - } - /> - - ), - )} - - {/* Success message or output */} - {textOutputs.length > 0 && ( - - {textOutputs.join('\n')} - - )} - - {/* Error handling */} - {errors.length > 0 && ( - -
{errors.join('\n')}
-
- )} - - {/* Other data */} - {otherData.length > 0 && ( - - - {otherData.map((data: unknown) => formatValue(data)).join('\n\n')} - - - )} -
- ); + // No output, don't show anything + return null; };