import { ToolCallPart, ToolResultPart } from "ai"; import { Book, Globe, Search, Presentation, Wrench } from "lucide-react"; import { Shimmer } from "../ai-elements/shimmer"; export interface ToolDisplay { call_label: string; call_icon: React.ReactNode; result_label: string; result_icon: React.ReactNode; formatArgs?: (toolName: string, input: unknown) => string; }; function formatWebSearchArgs(_: string, input: unknown): string { try { if (typeof input !== 'object' || input === null) { return ""; } const args = input as Record; return args.query ? String(args.query) : ""; } catch { return ""; } } const TOOL_DISPLAY_MAP: Record = { webSearch: { call_label: "Searching the web", call_icon: , result_label: "Searched the web", result_icon: , formatArgs: formatWebSearchArgs, }, }; const DEFAULT_TOOL_DISPLAY: ToolDisplay = { call_label: "Using tool", call_icon: , result_label: "Used tool", result_icon: }; function extractToolName(part: ToolCallPart | ToolResultPart): string | undefined { const partWithType = part as unknown as { type?: string; toolName?: string }; if (partWithType.type && partWithType.type.startsWith("tool-")) { return partWithType.type.slice(5); } if (partWithType.toolName) { return partWithType.toolName; } if ('toolName' in part && part.toolName) { return part.toolName; } return undefined; } function formatToolArguments(toolName: string, input: unknown, toolDisplay?: ToolDisplay): string { if (toolDisplay?.formatArgs) { return toolDisplay.formatArgs(toolName, input); } try { if (typeof input !== 'object' || input === null) { return String(input); } const args = input as Record; if (args.query) { return String(args.query); } return "Arguments not available"; } catch { return "Arguments not available"; } } export function ToolCall({ part }: { part: ToolCallPart }) { const { input } = part; const toolName = extractToolName(part); const toolDisplay = toolName ? (TOOL_DISPLAY_MAP[toolName] || DEFAULT_TOOL_DISPLAY) : DEFAULT_TOOL_DISPLAY; const formattedArgs = formatToolArguments(toolName || "", input, toolDisplay); return (
{toolDisplay.call_icon} {toolDisplay.call_label}
{toolDisplay.formatArgs && formattedArgs && ( {formattedArgs} )}
); } export function ToolResult({ part }: { part: ToolResultPart }) { const { output } = part; const toolName = extractToolName(part); const toolDisplay = toolName ? (TOOL_DISPLAY_MAP[toolName] || DEFAULT_TOOL_DISPLAY) : DEFAULT_TOOL_DISPLAY; const input = 'input' in part ? part.input : undefined; const formattedArgs = input !== undefined ? formatToolArguments(toolName || "", input, toolDisplay) : ""; return (
{toolDisplay.result_icon} {toolDisplay.result_label}
{toolDisplay.formatArgs && formattedArgs && ( {formattedArgs} )}
); }