Richer tool call ui messages (#3104)
This commit is contained in:
committed by
GitHub
parent
8f52e17633
commit
666ce691d3
Generated
+18
-18
@@ -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"
|
||||
|
||||
@@ -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<string, ToolCallArgumentValue>;
|
||||
const entries = Object.entries(args);
|
||||
const toolName = toolCall.name.substring(toolCall.name.lastIndexOf('__') + 2);
|
||||
|
||||
if (entries.length === 0) return null;
|
||||
// Helper function to get string value safely
|
||||
const getStringValue = (value: ToolCallArgumentValue): string => {
|
||||
return typeof value === 'string' ? value : JSON.stringify(value);
|
||||
};
|
||||
|
||||
// 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;
|
||||
// Helper function to truncate long values
|
||||
const truncate = (str: string, maxLength: number = 50): string => {
|
||||
return str.length > maxLength ? str.substring(0, maxLength) + '...' : str;
|
||||
};
|
||||
|
||||
return (
|
||||
<span className="ml-2 text-textSubtle truncate text-xs opacity-70">
|
||||
{key}: {truncatedValue}
|
||||
</span>
|
||||
);
|
||||
// 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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 (
|
||||
<span className="ml-2 text-textSubtle truncate text-xs opacity-70">
|
||||
{entries.map(([key]) => key).join(', ')}
|
||||
</span>
|
||||
);
|
||||
return null;
|
||||
};
|
||||
|
||||
return (
|
||||
<ToolCallExpandable
|
||||
isStartExpanded={isShouldExpand || isRenderingProgress}
|
||||
isStartExpanded={isRenderingProgress}
|
||||
isForceExpand={isShouldExpand}
|
||||
label={
|
||||
<>
|
||||
<Dot size={2} loadingStatus={loadingStatus} />
|
||||
<span className="ml-[10px]">
|
||||
{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));
|
||||
})()}
|
||||
</span>
|
||||
{/* Display compact arguments inline */}
|
||||
{isToolDetails && getCompactArguments()}
|
||||
</>
|
||||
}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user