import { TOOL_ICON_MAP } from './icons'; type ToolPayload = Record | null | undefined; const RUNNING_ANIMATIONS: Record = { create_file: 'file-animation', read_file: 'read-animation', delete_file: 'file-animation', rename_file: 'file-animation', modify_file: 'file-animation', append_to_file: 'file-animation', create_folder: 'file-animation', focus_file: 'focus-animation', unfocus_file: 'focus-animation', web_search: 'search-animation', extract_webpage: 'search-animation', save_webpage: 'file-animation', run_python: 'code-animation', run_command: 'terminal-animation', update_memory: 'memory-animation', sleep: 'wait-animation', terminal_session: 'terminal-animation', terminal_input: 'terminal-animation', terminal_snapshot: 'terminal-animation', terminal_reset: 'terminal-animation', todo_create: 'file-animation', todo_update_task: 'file-animation', todo_finish: 'file-animation', todo_finish_confirm: 'file-animation', create_sub_agent: 'terminal-animation', wait_sub_agent: 'wait-animation' }; const RUNNING_STATUS_TEXTS: Record = { create_file: '正在创建文件...', sleep: '正在等待...', delete_file: '正在删除文件...', rename_file: '正在重命名文件...', modify_file: '正在修改文件...', append_to_file: '正在追加文件...', create_folder: '正在创建文件夹...', focus_file: '正在聚焦文件...', unfocus_file: '正在取消聚焦...', web_search: '正在搜索网络...', extract_webpage: '正在提取网页...', save_webpage: '正在保存网页...', run_python: '调用 run_python', run_command: '调用 run_command', update_memory: '正在更新记忆...', terminal_session: '正在管理终端会话...', terminal_input: '调用 terminal_input', terminal_snapshot: '正在获取终端快照...', terminal_reset: '正在重置终端...' }; const COMPLETED_STATUS_TEXTS: Record = { create_file: '文件创建成功', delete_file: '文件删除成功', sleep: '等待完成', rename_file: '文件重命名成功', modify_file: '文件修改成功', append_to_file: '文件追加完成', create_folder: '文件夹创建成功', focus_file: '文件聚焦成功', unfocus_file: '取消聚焦成功', web_search: '搜索完成', extract_webpage: '网页提取完成', save_webpage: '网页保存完成(纯文本)', run_python: '代码执行完成', run_command: '命令执行完成', update_memory: '记忆更新成功', terminal_session: '终端操作完成', terminal_input: '终端输入完成', terminal_snapshot: '终端快照已返回', terminal_reset: '终端已重置' }; const LANGUAGE_CLASS_MAP: Record = { py: 'language-python', js: 'language-javascript', html: 'language-html', css: 'language-css', json: 'language-json', md: 'language-markdown', txt: 'language-plain' }; const SEARCH_TOPIC_MAP: Record = { general: '通用', news: '新闻', finance: '金融' }; const RELATIVE_TIME_RANGE_MAP: Record = { day: '过去24小时', week: '过去7天', month: '过去30天', year: '过去365天' }; export function getToolIcon(tool: any): string { const toolName = typeof tool === 'string' ? tool : tool?.name; return TOOL_ICON_MAP[toolName as keyof typeof TOOL_ICON_MAP] || 'settings'; } export function getToolAnimationClass(tool: any): string { if (!tool) { return ''; } if (tool.status === 'hinted') { return 'hint-animation pulse-slow'; } if (tool.status === 'preparing') { return 'preparing-animation'; } if (tool.status === 'running') { return RUNNING_ANIMATIONS[tool.name] || 'default-animation'; } return ''; } function describeReadFileResult(tool: any): string { if (!tool?.result || typeof tool.result !== 'object') { return '文件读取完成'; } const readType = String(tool.result.type || 'read').toLowerCase(); if (readType === 'search') { const query = tool.result.query ? `「${tool.result.query}」` : ''; const count = typeof tool.result.returned_matches === 'number' ? tool.result.returned_matches : tool.result.actual_matches || 0; return `搜索${query},得到${count}个结果`; } if (readType === 'extract') { const segments = Array.isArray(tool.result.segments) ? tool.result.segments : []; const totalLines = segments.reduce((sum: number, seg: any) => { const start = Number(seg.line_start) || 0; const end = Number(seg.line_end) || 0; if (!start || !end || end < start) { return sum; } return sum + (end - start + 1); }, 0); const displayLines = totalLines || tool.result.char_count || 0; return `提取了${displayLines}行`; } return '文件读取完成'; } export function getToolStatusText(tool: any): string { if (!tool) { return ''; } if (tool.message) { return tool.message; } if (tool.status === 'hinted') { return `可能需要 ${tool.name}...`; } if (tool.status === 'preparing') { return `准备调用 ${tool.name}...`; } if (tool.status === 'running') { if (tool.name === 'read_file') { const readType = String( tool.argumentSnapshot?.type || tool.arguments?.type || 'read' ).toLowerCase(); const runningMap: Record = { read: '正在读取文件...', search: '正在执行搜索...', extract: '正在提取内容...' }; return runningMap[readType] || '正在读取文件...'; } const label = RUNNING_STATUS_TEXTS[tool.name] || tool.display_name || tool.name || ''; return label ? label : '调用工具中'; } if (tool.status === 'completed') { if (tool.name === 'read_file') { return describeReadFileResult(tool); } return COMPLETED_STATUS_TEXTS[tool.name] || '执行完成'; } return `${tool.name} - ${tool.status}`; } export function getToolDescription(tool: any): string { if (!tool) { return ''; } const args = tool.argumentSnapshot || tool.arguments; const argumentLabel = tool.argumentLabel || buildToolLabel(args); if (argumentLabel) { return argumentLabel; } if (tool.statusDetail) { return tool.statusDetail; } if (tool.result && typeof tool.result === 'object' && tool.result.path) { return String(tool.result.path).split('/').pop() || ''; } return ''; } export function cloneToolArguments(args: any): any { if (!args || typeof args !== 'object') { return null; } try { return JSON.parse(JSON.stringify(args)); } catch (error) { console.warn('无法克隆工具参数:', error); return { ...args }; } } export function buildToolLabel(args: any): string { if (!args || typeof args !== 'object') { return ''; } if (args.command) { return args.command; } if (args.path) { return String(args.path).split('/').pop() || ''; } if (args.target_path) { return String(args.target_path).split('/').pop() || ''; } if (args.query) { return `"${args.query}"`; } if (typeof args.seconds !== 'undefined') { return `${args.seconds} 秒`; } if (args.name) { return args.name; } return ''; } export function formatSearchTopic(filters: ToolPayload): string { const topic = filters?.topic ? String(filters.topic).toLowerCase() : 'general'; return SEARCH_TOPIC_MAP[topic] || '通用'; } export function formatSearchTime(filters: ToolPayload): string { if (!filters) { return '未限定时间'; } if (filters.time_range) { const key = String(filters.time_range).toLowerCase(); return RELATIVE_TIME_RANGE_MAP[key] || `相对范围:${filters.time_range}`; } if (typeof filters.days === 'number') { return `过去${filters.days}天`; } if (filters.start_date && filters.end_date) { return `${filters.start_date} 至 ${filters.end_date}`; } return '未限定时间'; } export function getLanguageClass(path: string): string { if (!path) { return 'language-plain'; } const ext = path.split('.').pop()?.toLowerCase() || ''; return LANGUAGE_CLASS_MAP[ext] || 'language-plain'; }