import { memo, useState } from 'react' import { cn } from '@/lib/utils' import type { ReactNode } from 'react' import { TimeLine, CheckboxCircleLine, CloseCircleLine, ArrowDownSLine } from '../basic/icons-inline' import { Scrollbar } from '../basic/scrollbar' export type ToolInvocationStatus = 'running' | 'success' | 'error' export interface ToolInvocationCardProps { toolName: string params?: string status: ToolInvocationStatus response?: string defaultExpanded?: boolean statusText?: string className?: string timeIcon?: ReactNode checkboxCircleIcon?: ReactNode closeCircleIcon?: ReactNode arrowDownIcon?: ReactNode /** @deprecated Use arrowDownIcon. */ arrowRightIcon?: ReactNode runningText?: string ranText?: string failedText?: string responseLabel?: string } /* 左侧状态图标随 token:容器 text-xs 使 1em = var(--font-size-xs),图标 size-[1em] 继承 */ const statusIconClass = 'size-[1em] shrink-0' const timeClass = `${statusIconClass} text-text-tertiary` const checkboxClass = `${statusIconClass} text-success` const closeCircleClass = `${statusIconClass} text-text-tertiary` const arrowClass = 'w-3.5 h-3.5 text-text-tertiary transition-all duration-200' export const ToolInvocationCard = memo(function ToolInvocationCard({ toolName, params, status, response, defaultExpanded = false, statusText: statusTextProp, className, timeIcon, checkboxCircleIcon, closeCircleIcon, arrowDownIcon, arrowRightIcon, runningText = 'Running', ranText = 'Ran', failedText = 'Failed', responseLabel = 'Response', }: ToolInvocationCardProps) { const [isExpanded, setIsExpanded] = useState(defaultExpanded) const hasResponse = response != null && response.length > 0 const isRunning = status === 'running' const isSuccess = status === 'success' const isError = status === 'error' const defaultStatusText = isRunning ? runningText : isSuccess ? ranText : failedText const statusText = statusTextProp !== undefined ? statusTextProp : defaultStatusText const showStatusText = statusText !== '' const defaultTime = timeIcon ?? const defaultCheck = checkboxCircleIcon ?? const defaultCloseCircle = closeCircleIcon ?? const defaultArrow = arrowDownIcon ?? arrowRightIcon ?? return (
hasResponse && !isRunning && setIsExpanded(!isExpanded)} className={cn( 'group flex items-center gap-1.5 min-h-5', hasResponse && !isRunning && 'cursor-pointer hover:opacity-80 transition-opacity' )} >
{isRunning && defaultTime} {isSuccess && defaultCheck} {isError && defaultCloseCircle}
{showStatusText && ( {statusText} )} {toolName} {params != null && params !== '' && ( {params} )} {hasResponse && !isRunning && (
{defaultArrow}
)}
{hasResponse && isExpanded && (
{responseLabel}
              {response}
            
)}
) }) ToolInvocationCard.displayName = 'ToolInvocationCard' export const ToolCallCard = ToolInvocationCard export type ToolCallCardProps = ToolInvocationCardProps export type ToolCallStatus = ToolInvocationStatus