diff --git a/ui/desktop/package-lock.json b/ui/desktop/package-lock.json index 00e5e0bafd77..57ec7c18674e 100644 --- a/ui/desktop/package-lock.json +++ b/ui/desktop/package-lock.json @@ -1252,9 +1252,9 @@ } }, "node_modules/@electron/node-gyp/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1459,9 +1459,9 @@ } }, "node_modules/@electron/universal/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -4593,9 +4593,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5465,9 +5465,9 @@ "optional": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -5644,9 +5644,9 @@ } }, "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -15476,9 +15476,9 @@ } }, "node_modules/sucrase/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" diff --git a/ui/desktop/src/components/ToolCallWithResponse.tsx b/ui/desktop/src/components/ToolCallWithResponse.tsx index 1bf602ef1e31..ec598d19fd21 100644 --- a/ui/desktop/src/components/ToolCallWithResponse.tsx +++ b/ui/desktop/src/components/ToolCallWithResponse.tsx @@ -163,49 +163,169 @@ function ToolCallView({ const isRenderingProgress = loadingStatus === 'loading' && (progressEntries.length > 0 || (logs || []).length > 0); - const isShouldExpand = isExpandToolDetails || toolResults.some((v) => v.isExpandToolResults); + // Only expand if there are actual results that need to be shown, not just for tool details + const isShouldExpand = toolResults.some((v) => v.isExpandToolResults); - // Function to create a compact representation of arguments - const getCompactArguments = () => { + // Function to create a descriptive representation of what the tool is doing + const getToolDescription = () => { const args = toolCall.arguments as Record; - const entries = Object.entries(args); + const toolName = toolCall.name.substring(toolCall.name.lastIndexOf('__') + 2); + + // Helper function to get string value safely + const getStringValue = (value: ToolCallArgumentValue): string => { + return typeof value === 'string' ? value : JSON.stringify(value); + }; + + // Helper function to truncate long values + const truncate = (str: string, maxLength: number = 50): string => { + return str.length > maxLength ? str.substring(0, maxLength) + '...' : str; + }; + + // Generate descriptive text based on tool type + switch (toolName) { + case 'text_editor': + if (args.command === 'write' && args.path) { + return `writing ${truncate(getStringValue(args.path))}`; + } + if (args.command === 'view' && args.path) { + return `reading ${truncate(getStringValue(args.path))}`; + } + if (args.command === 'str_replace' && args.path) { + return `editing ${truncate(getStringValue(args.path))}`; + } + if (args.command && args.path) { + return `${getStringValue(args.command)} ${truncate(getStringValue(args.path))}`; + } + break; + + case 'shell': + if (args.command) { + return `running ${truncate(getStringValue(args.command))}`; + } + break; + + case 'search': + if (args.name) { + return `searching for "${truncate(getStringValue(args.name))}"`; + } + if (args.mimeType) { + return `searching for ${getStringValue(args.mimeType)} files`; + } + break; + + case 'read': { + if (args.uri) { + const uri = getStringValue(args.uri); + const fileId = uri.replace('gdrive:///', ''); + return `reading file ${truncate(fileId)}`; + } + if (args.url) { + return `reading ${truncate(getStringValue(args.url))}`; + } + break; + } - if (entries.length === 0) return null; + case 'create_file': + if (args.name) { + return `creating ${truncate(getStringValue(args.name))}`; + } + break; + + case 'update_file': + if (args.fileId) { + return `updating file ${truncate(getStringValue(args.fileId))}`; + } + break; + + case 'sheets_tool': { + if (args.operation && args.spreadsheetId) { + const operation = getStringValue(args.operation); + const sheetId = truncate(getStringValue(args.spreadsheetId)); + return `${operation} in sheet ${sheetId}`; + } + break; + } - // For a single parameter, show key and truncated value - if (entries.length === 1) { - const [key, value] = entries[0]; - const stringValue = typeof value === 'string' ? value : JSON.stringify(value); - const truncatedValue = - stringValue.length > 30 ? stringValue.substring(0, 30) + '...' : stringValue; + case 'docs_tool': { + if (args.operation && args.documentId) { + const operation = getStringValue(args.operation); + const docId = truncate(getStringValue(args.documentId)); + return `${operation} in document ${docId}`; + } + break; + } - return ( - - {key}: {truncatedValue} - - ); + case 'web_scrape': + if (args.url) { + return `scraping ${truncate(getStringValue(args.url))}`; + } + break; + + case 'remember_memory': + if (args.category && args.data) { + return `storing ${getStringValue(args.category)}: ${truncate(getStringValue(args.data))}`; + } + break; + + case 'retrieve_memories': + if (args.category) { + return `retrieving ${getStringValue(args.category)} memories`; + } + break; + + case 'screen_capture': + if (args.window_title) { + return `capturing window "${truncate(getStringValue(args.window_title))}"`; + } + return 'capturing screen'; + + case 'automation_script': + if (args.language) { + return `running ${getStringValue(args.language)} script`; + } + break; + + case 'computer_control': + return 'poking around...'; + + default: { + // Fallback to showing key parameters for unknown tools + const entries = Object.entries(args); + if (entries.length === 0) return null; + + // For a single parameter, show key and truncated value + if (entries.length === 1) { + const [key, value] = entries[0]; + const stringValue = getStringValue(value); + const truncatedValue = truncate(stringValue, 30); + return `${key}: ${truncatedValue}`; + } + + // For multiple parameters, just show the keys + return entries.map(([key]) => key).join(', '); + } } - // For multiple parameters, just show the keys - return ( - - {entries.map(([key]) => key).join(', ')} - - ); + return null; }; return ( - {snakeToTitleCase(toolCall.name.substring(toolCall.name.lastIndexOf('__') + 2))} + {(() => { + const description = getToolDescription(); + if (description) { + return description; + } + // Fallback to the original tool name formatting + return snakeToTitleCase(toolCall.name.substring(toolCall.name.lastIndexOf('__') + 2)); + })()} - {/* Display compact arguments inline */} - {isToolDetails && getCompactArguments()} } >