/** * ToolCallCard — 工具调用卡片 */ import { Box, Typography, Stack, Chip } from '@mui/material'; import { Wrench, Clock, CheckCircle, XCircle, Ban, Loader2 } from 'lucide-react'; import type { ToolCallInfo } from '@renderer/stores/agent-store'; import { formatDuration } from '@renderer/lib/formatters'; interface ToolCallCardProps { toolCall: ToolCallInfo; } const STATUS_ICONS = { pending: Clock, executing: Loader2, success: CheckCircle, error: XCircle, blocked: Ban }; const STATUS_LABELS = { pending: '等待中', executing: '执行中', success: '成功', error: '失败', blocked: '已阻止' }; const STATUS_COLORS: Record = { pending: '#fbbf24', executing: '#a855f7', success: '#34d399', error: '#f87171', blocked: '#fb923c' }; const CHIP_VARIANTS: Record = { pending: 'outlined', executing: 'filled', success: 'filled', error: 'filled', blocked: 'outlined' }; export function ToolCallCard({ toolCall }: ToolCallCardProps): React.JSX.Element { const Icon = STATUS_ICONS[toolCall.status]; const color = STATUS_COLORS[toolCall.status]; const label = STATUS_LABELS[toolCall.status]; return ( {toolCall.name} } label={label} size="small" variant={CHIP_VARIANTS[toolCall.status]} sx={{ height: 18, fontSize: 10, color, borderColor: color, '& .MuiChip-icon': { color } }} /> {toolCall.durationMs != null && ( {formatDuration(toolCall.durationMs)} )} {Object.keys(toolCall.args).length > 0 && ( {JSON.stringify(toolCall.args, null, 2)} )} {toolCall.status === 'error' && toolCall.error && ( {toolCall.error} )} ); }