@huyooo/ai-chat-frontend-react 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapter.ts","../src/hooks/useChat.ts","../src/components/ChatPanel.tsx","../src/types/index.ts","../src/components/chat/ui/ChatHeader.tsx","../src/components/chat/ui/WelcomeMessage.tsx","../src/components/chat/messages/MessageBubble.tsx","../src/components/chat/messages/ExecutionSteps.tsx","../src/components/ChatInput.tsx"],"sourcesContent":["/**\n * Chat Adapter 接口定义\n * 解耦前端组件与后端通信方式\n * \n * 与 Vue 版本保持一致\n */\n\nimport type { SessionRecord, MessageRecord, ChatMode, ThinkingMode, SearchResult } from './types'\n\n/** 聊天进度类型 */\nexport type ChatProgressType =\n | 'thinking'\n | 'search_start'\n | 'search_result'\n | 'tool_call'\n | 'tool_result'\n | 'text_delta'\n | 'text'\n | 'done'\n | 'error'\n\n/** 思考数据 */\nexport interface ThinkingData {\n content: string\n isComplete: boolean\n}\n\n/** 工具调用数据 */\nexport interface ToolCallData {\n name: string\n args: Record<string, unknown>\n}\n\n/** 工具结果数据 */\nexport interface ToolResultData {\n name: string\n result: string\n}\n\n/** 图片数据 */\nexport interface ImageData {\n base64: string\n mimeType: string\n}\n\n/** 聊天进度事件 */\nexport interface ChatProgress {\n type: ChatProgressType\n data: string | ThinkingData | ToolCallData | ToolResultData | { results: SearchResult[] }\n}\n\n/** 发送消息选项 */\nexport interface SendMessageOptions {\n mode: ChatMode\n model: string\n enableWebSearch: boolean\n thinkingMode: ThinkingMode\n}\n\n/** 创建会话选项 */\nexport interface CreateSessionOptions {\n title: string\n model: string\n mode: ChatMode\n}\n\n/** 更新会话选项 */\nexport interface UpdateSessionOptions {\n title?: string\n model?: string\n mode?: ChatMode\n}\n\n/** 保存消息选项 */\nexport interface SaveMessageOptions {\n sessionId: string\n role: 'user' | 'assistant'\n content: string\n thinking?: string\n toolCalls?: string\n searchResults?: string\n}\n\n/**\n * Chat Adapter 接口\n * 所有后端通信实现都需要实现此接口\n */\nexport interface ChatAdapter {\n /** 获取所有会话 */\n getSessions(): Promise<SessionRecord[]>\n \n /** 创建新会话 */\n createSession(options: CreateSessionOptions): Promise<SessionRecord>\n \n /** 更新会话 */\n updateSession(sessionId: string, options: UpdateSessionOptions): Promise<void>\n \n /** 删除会话 */\n deleteSession(sessionId: string): Promise<void>\n \n /** 获取会话消息 */\n getMessages(sessionId: string): Promise<MessageRecord[]>\n \n /** 保存消息 */\n saveMessage(options: SaveMessageOptions): Promise<MessageRecord>\n \n /** 发送消息并获取流式响应 */\n sendMessage(\n content: string,\n options: SendMessageOptions,\n images?: string[]\n ): AsyncGenerator<ChatProgress, void, unknown>\n \n /** 取消当前请求 */\n cancel(): void\n \n /** 设置工作目录 */\n setWorkingDir?(dir: string): void\n}\n\n/**\n * 创建空 Adapter(用于测试或无后端场景)\n */\nexport function createNullAdapter(): ChatAdapter {\n return {\n async getSessions() {\n return []\n },\n async createSession(options) {\n return {\n id: Date.now().toString(),\n title: options.title,\n model: options.model,\n mode: options.mode,\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n },\n async updateSession() {},\n async deleteSession() {},\n async getMessages() {\n return []\n },\n async saveMessage(options) {\n return {\n id: Date.now().toString(),\n sessionId: options.sessionId,\n role: options.role,\n content: options.content,\n thinking: options.thinking,\n toolCalls: options.toolCalls,\n searchResults: options.searchResults,\n timestamp: new Date(),\n }\n },\n async *sendMessage() {\n yield { type: 'text', data: '无可用的 Adapter' }\n yield { type: 'done', data: '' }\n },\n cancel() {},\n }\n}\n","/**\n * useChat Hook\n * 管理聊天状态和与后端的通信\n * 使用 Adapter 模式解耦后端通信\n * \n * 与 Vue 版本 useChat composable 保持一致\n */\n\nimport { useState, useCallback, useRef } from 'react'\nimport type { ChatAdapter, ChatProgress } from '../adapter'\nimport { createNullAdapter } from '../adapter'\nimport type {\n ChatMessage,\n ChatMode,\n SessionRecord,\n MessageRecord,\n SearchResult,\n ToolCall,\n} from '../types'\n\n/** 生成唯一 ID */\nfunction generateId(): string {\n return Date.now().toString(36) + Math.random().toString(36).substr(2)\n}\n\n/** 转换存储的消息为显示格式 */\nfunction convertToMessage(record: MessageRecord): ChatMessage {\n return {\n id: record.id,\n role: record.role,\n content: record.content,\n thinking: record.thinking || undefined,\n thinkingComplete: true,\n toolCalls: record.toolCalls ? JSON.parse(record.toolCalls) : undefined,\n searchResults: record.searchResults ? JSON.parse(record.searchResults) : undefined,\n searching: false,\n timestamp: record.timestamp,\n }\n}\n\nexport interface UseChatOptions {\n /** Adapter 实例 */\n adapter?: ChatAdapter\n /** 默认模型 */\n defaultModel?: string\n /** 默认模式 */\n defaultMode?: ChatMode\n}\n\n/**\n * 聊天状态管理 Hook\n */\nexport function useChat(options: UseChatOptions = {}) {\n const {\n adapter = createNullAdapter(),\n defaultModel = 'anthropic/claude-opus-4.5',\n defaultMode = 'agent',\n } = options\n\n // 会话状态\n const [sessions, setSessions] = useState<SessionRecord[]>([])\n const [currentSessionId, setCurrentSessionId] = useState<string | null>(null)\n const [messages, setMessages] = useState<ChatMessage[]>([])\n\n // 配置状态\n const [mode, setModeState] = useState<ChatMode>(defaultMode)\n const [model, setModelState] = useState(defaultModel)\n const [webSearch, setWebSearchState] = useState(true)\n const [thinking, setThinkingState] = useState(true)\n\n // 加载状态\n const [isLoading, setIsLoading] = useState(false)\n\n // 取消控制器\n const abortControllerRef = useRef<AbortController | null>(null)\n\n // 用于在回调中访问最新状态\n const sessionsRef = useRef(sessions)\n const messagesRef = useRef(messages)\n const currentSessionIdRef = useRef(currentSessionId)\n const modeRef = useRef(mode)\n const modelRef = useRef(model)\n const webSearchRef = useRef(webSearch)\n const thinkingRef = useRef(thinking)\n\n // 同步 ref\n sessionsRef.current = sessions\n messagesRef.current = messages\n currentSessionIdRef.current = currentSessionId\n modeRef.current = mode\n modelRef.current = model\n webSearchRef.current = webSearch\n thinkingRef.current = thinking\n\n /** 加载会话列表 */\n const loadSessions = useCallback(async () => {\n try {\n const list = await adapter.getSessions()\n setSessions(list)\n // 如果有会话且没有当前会话,选择最新的\n if (list.length > 0 && !currentSessionIdRef.current) {\n const firstSession = list[0]\n setCurrentSessionId(firstSession.id)\n const savedMessages = await adapter.getMessages(firstSession.id)\n setMessages(savedMessages.map(convertToMessage))\n setModeState(firstSession.mode)\n setModelState(firstSession.model)\n }\n } catch (error) {\n console.error('加载会话失败:', error)\n }\n }, [adapter])\n\n /** 切换会话 */\n const switchSession = useCallback(async (sessionId: string) => {\n if (currentSessionIdRef.current === sessionId) return\n\n setCurrentSessionId(sessionId)\n\n try {\n const savedMessages = await adapter.getMessages(sessionId)\n setMessages(savedMessages.map(convertToMessage))\n\n // 更新配置\n const session = sessionsRef.current.find((s) => s.id === sessionId)\n if (session) {\n setModeState(session.mode)\n setModelState(session.model)\n }\n } catch (error) {\n console.error('加载消息失败:', error)\n setMessages([])\n }\n }, [adapter])\n\n /** 创建新会话 */\n const createNewSession = useCallback(async () => {\n try {\n const session = await adapter.createSession({\n title: '新对话',\n model: modelRef.current,\n mode: modeRef.current,\n })\n setSessions(prev => [session, ...prev])\n setCurrentSessionId(session.id)\n setMessages([])\n } catch (error) {\n console.error('创建会话失败:', error)\n }\n }, [adapter])\n\n /** 删除会话 */\n const deleteSession = useCallback(async (sessionId: string) => {\n try {\n await adapter.deleteSession(sessionId)\n setSessions(prev => prev.filter((s) => s.id !== sessionId))\n\n // 如果删除的是当前会话,切换到下一个\n if (currentSessionIdRef.current === sessionId) {\n const remaining = sessionsRef.current.filter((s) => s.id !== sessionId)\n if (remaining.length > 0) {\n await switchSession(remaining[0].id)\n } else {\n setCurrentSessionId(null)\n setMessages([])\n }\n }\n } catch (error) {\n console.error('删除会话失败:', error)\n }\n }, [adapter, switchSession])\n\n /** 删除当前会话 */\n const deleteCurrentSession = useCallback(async () => {\n if (currentSessionIdRef.current) {\n await deleteSession(currentSessionIdRef.current)\n }\n }, [deleteSession])\n\n /** 更新消息 */\n const updateMessage = useCallback((index: number, progress: ChatProgress) => {\n setMessages(prev => {\n const newMessages = [...prev]\n const msg = { ...newMessages[index] }\n if (!msg) return prev\n\n switch (progress.type) {\n case 'thinking': {\n const thinkingData = progress.data as { content: string; isComplete: boolean }\n if (thinkingData.content) {\n msg.thinking = (msg.thinking || '') + thinkingData.content\n }\n msg.thinkingComplete = thinkingData.isComplete\n break\n }\n\n case 'search_start':\n msg.searching = true\n break\n\n case 'search_result': {\n msg.searching = false\n const searchData = progress.data as { results: SearchResult[] }\n msg.searchResults = searchData.results || []\n break\n }\n\n case 'tool_call': {\n const toolData = progress.data as { name: string; args: Record<string, unknown> }\n if (!msg.toolCalls) msg.toolCalls = []\n msg.toolCalls = [...msg.toolCalls, {\n name: toolData.name,\n args: toolData.args,\n status: 'running' as const,\n }]\n break\n }\n\n case 'tool_result': {\n const resultData = progress.data as { name: string; result: string }\n if (msg.toolCalls) {\n msg.toolCalls = msg.toolCalls.map((t: ToolCall) => {\n if (t.name === resultData.name && t.status === 'running') {\n return { ...t, result: resultData.result, status: 'success' as const }\n }\n return t\n })\n }\n break\n }\n\n case 'text_delta':\n msg.content = (msg.content || '') + (progress.data as string)\n break\n\n case 'text':\n if (!msg.content) {\n msg.content = progress.data as string\n }\n break\n\n case 'error':\n msg.content = (msg.content || '') + `\\n\\n❌ 错误: ${progress.data}`\n break\n }\n\n newMessages[index] = msg\n return newMessages\n })\n }, [])\n\n /** 发送消息 */\n const sendMessage = useCallback(async (text: string, images?: string[]) => {\n if (!text.trim() || isLoading) return\n\n // 如果没有当前会话,先创建\n let sessionId = currentSessionIdRef.current\n if (!sessionId) {\n try {\n const session = await adapter.createSession({\n title: '新对话',\n model: modelRef.current,\n mode: modeRef.current,\n })\n setSessions(prev => [session, ...prev])\n setCurrentSessionId(session.id)\n sessionId = session.id\n } catch (error) {\n console.error('创建会话失败:', error)\n return\n }\n }\n\n // 添加用户消息\n const userMsg: ChatMessage = {\n id: generateId(),\n role: 'user',\n content: text,\n images,\n timestamp: new Date(),\n }\n \n const currentMessages = messagesRef.current\n setMessages([...currentMessages, userMsg])\n\n // 保存用户消息\n try {\n await adapter.saveMessage({\n sessionId,\n role: 'user',\n content: text,\n })\n\n // 更新会话标题(如果是第一条消息)\n if (currentMessages.length === 0) {\n const title = text.slice(0, 20) + (text.length > 20 ? '...' : '')\n await adapter.updateSession(sessionId, { title })\n setSessions(prev => prev.map((s) =>\n s.id === sessionId ? { ...s, title } : s\n ))\n }\n } catch (error) {\n console.error('保存消息失败:', error)\n }\n\n // 创建助手消息\n const assistantMsgIndex = currentMessages.length + 1\n const assistantMsg: ChatMessage = {\n id: generateId(),\n role: 'assistant',\n content: '',\n toolCalls: [],\n thinkingComplete: false,\n searching: false,\n loading: true,\n timestamp: new Date(),\n }\n setMessages(prev => [...prev, assistantMsg])\n\n setIsLoading(true)\n abortControllerRef.current = new AbortController()\n\n try {\n // 使用异步迭代器接收消息流\n for await (const progress of adapter.sendMessage(\n text,\n {\n mode: modeRef.current,\n model: modelRef.current,\n enableWebSearch: webSearchRef.current,\n thinkingMode: thinkingRef.current ? 'enabled' : 'disabled',\n },\n images\n )) {\n // 检查是否被取消\n if (abortControllerRef.current?.signal.aborted) break\n\n updateMessage(assistantMsgIndex, progress)\n\n if (progress.type === 'done' || progress.type === 'error') {\n break\n }\n }\n } catch (error) {\n console.error('发送消息失败:', error)\n updateMessage(assistantMsgIndex, {\n type: 'error',\n data: error instanceof Error ? error.message : String(error),\n })\n } finally {\n setIsLoading(false)\n\n // 标记加载完成并保存\n setMessages(prev => {\n const newMessages = [...prev]\n const finalMsg = newMessages[assistantMsgIndex]\n if (finalMsg) {\n newMessages[assistantMsgIndex] = { ...finalMsg, loading: false }\n\n // 保存助手消息\n if (sessionId) {\n adapter.saveMessage({\n sessionId,\n role: 'assistant',\n content: finalMsg.content,\n thinking: finalMsg.thinking,\n toolCalls: finalMsg.toolCalls ? JSON.stringify(finalMsg.toolCalls) : undefined,\n searchResults: finalMsg.searchResults\n ? JSON.stringify(finalMsg.searchResults)\n : undefined,\n }).catch((e: Error) => console.error('保存助手消息失败:', e))\n }\n }\n return newMessages\n })\n\n abortControllerRef.current = null\n }\n }, [adapter, isLoading, updateMessage])\n\n /** 取消请求 */\n const cancelRequest = useCallback(() => {\n adapter.cancel()\n abortControllerRef.current?.abort()\n setIsLoading(false)\n }, [adapter])\n\n /** 复制消息 */\n const copyMessage = useCallback(async (messageId: string) => {\n const msg = messagesRef.current.find((m) => m.id === messageId)\n if (!msg) return\n\n try {\n await navigator.clipboard.writeText(msg.content)\n setMessages(prev => prev.map((m) =>\n m.id === messageId ? { ...m, copied: true } : m\n ))\n setTimeout(() => {\n setMessages(prev => prev.map((m) =>\n m.id === messageId ? { ...m, copied: false } : m\n ))\n }, 2000)\n } catch (err) {\n console.error('复制失败:', err)\n }\n }, [])\n\n /** 重新生成消息 */\n const regenerateMessage = useCallback((messageIndex: number) => {\n const currentMsgs = messagesRef.current\n if (messageIndex > 0 && currentMsgs[messageIndex - 1]?.role === 'user') {\n const userMsg = currentMsgs[messageIndex - 1]\n setMessages(prev => prev.slice(0, messageIndex - 1))\n sendMessage(userMsg.content, userMsg.images)\n }\n }, [sendMessage])\n\n /** 设置工作目录 */\n const setWorkingDirectory = useCallback((dir: string) => {\n if (adapter.setWorkingDir) {\n adapter.setWorkingDir(dir)\n }\n }, [adapter])\n\n // 配置方法\n const setMode = useCallback((value: ChatMode) => setModeState(value), [])\n const setModel = useCallback((value: string) => setModelState(value), [])\n const setWebSearch = useCallback((value: boolean) => setWebSearchState(value), [])\n const setThinking = useCallback((value: boolean) => setThinkingState(value), [])\n\n return {\n // 状态\n sessions,\n currentSessionId,\n messages,\n isLoading,\n mode,\n model,\n webSearch,\n thinking,\n\n // 会话方法\n loadSessions,\n switchSession,\n createNewSession,\n deleteSession,\n deleteCurrentSession,\n\n // 消息方法\n sendMessage,\n cancelRequest,\n copyMessage,\n regenerateMessage,\n\n // 配置方法\n setMode,\n setModel,\n setWebSearch,\n setThinking,\n\n // 工具方法\n setWorkingDirectory,\n }\n}\n","/**\n * ChatPanel Component\n * 与 Vue 版本 ChatPanel.vue 保持一致\n */\n\nimport { useEffect, useRef, useCallback, type FC, type ReactNode } from 'react'\nimport { useChat } from '../hooks/useChat'\nimport type { ChatAdapter } from '../adapter'\nimport type { ModelConfig, ChatMode } from '../types'\nimport { DEFAULT_MODELS } from '../types'\nimport { ChatHeader } from './chat/ui/ChatHeader'\nimport { WelcomeMessage } from './chat/ui/WelcomeMessage'\nimport { MessageBubble } from './chat/messages/MessageBubble'\nimport { ChatInput } from './ChatInput'\n\ninterface ChatPanelProps {\n /** Adapter 实例 */\n adapter?: ChatAdapter\n /** 工作目录 */\n workingDir?: string\n /** 默认模型 */\n defaultModel?: string\n /** 默认模式 */\n defaultMode?: ChatMode\n /** 可用模型列表 */\n models?: ModelConfig[]\n /** 隐藏标题栏 */\n hideHeader?: boolean\n /** 关闭回调(有此属性时显示关闭按钮) */\n onClose?: () => void\n /** 自定义类名 */\n className?: string\n /** 自定义 Markdown 渲染器 */\n renderMarkdown?: (content: string) => ReactNode\n}\n\nexport const ChatPanel: FC<ChatPanelProps> = ({\n adapter,\n workingDir,\n defaultModel = 'anthropic/claude-opus-4.5',\n defaultMode = 'agent',\n models = DEFAULT_MODELS,\n hideHeader = false,\n onClose,\n className = '',\n renderMarkdown,\n}) => {\n const messagesRef = useRef<HTMLDivElement>(null)\n\n const {\n sessions,\n currentSessionId,\n messages,\n isLoading,\n mode,\n model,\n webSearch,\n thinking,\n loadSessions,\n switchSession,\n createNewSession,\n deleteSession,\n sendMessage,\n cancelRequest,\n copyMessage,\n regenerateMessage,\n setMode,\n setModel,\n setWebSearch,\n setThinking,\n setWorkingDirectory,\n } = useChat({\n adapter,\n defaultModel,\n defaultMode,\n })\n\n // 选中的图片\n // const [selectedImages, setSelectedImages] = useState<string[]>([])\n\n // 初始化\n useEffect(() => {\n loadSessions()\n }, [loadSessions])\n\n // 工作目录变化时更新\n useEffect(() => {\n if (workingDir) {\n setWorkingDirectory(workingDir)\n }\n }, [workingDir, setWorkingDirectory])\n\n // 滚动到底部\n const scrollToBottom = useCallback(() => {\n if (messagesRef.current) {\n messagesRef.current.scrollTop = messagesRef.current.scrollHeight\n }\n }, [])\n\n // 消息变化时滚动\n useEffect(() => {\n scrollToBottom()\n }, [messages, scrollToBottom])\n\n // 发送消息\n const handleSend = useCallback(\n (text: string) => {\n sendMessage(text)\n },\n [sendMessage]\n )\n\n // 快捷操作\n const handleQuickAction = useCallback(\n (text: string) => {\n sendMessage(text)\n },\n [sendMessage]\n )\n\n // 重新发送(编辑后)\n const handleResend = useCallback(\n (index: number, text: string) => {\n // 删除当前消息及后续消息,然后重新发送\n // 这里简化处理,实际需要更完善的逻辑\n sendMessage(text)\n },\n [sendMessage]\n )\n\n // 关闭\n const handleClose = useCallback(() => {\n onClose?.()\n }, [onClose])\n\n // 清空所有对话\n const handleClearAll = useCallback(() => {\n console.log('清空所有对话')\n }, [])\n\n // 关闭其他对话\n const handleCloseOthers = useCallback(() => {\n console.log('关闭其他对话')\n }, [])\n\n // 导出对话\n const handleExport = useCallback(() => {\n console.log('导出对话')\n }, [])\n\n // 复制请求 ID\n const handleCopyId = useCallback(() => {\n if (currentSessionId) {\n navigator.clipboard.writeText(currentSessionId)\n console.log('已复制请求 ID:', currentSessionId)\n }\n }, [currentSessionId])\n\n // 反馈\n const handleFeedback = useCallback(() => {\n console.log('反馈')\n }, [])\n\n // 设置\n const handleSettings = useCallback(() => {\n console.log('Agent 设置')\n }, [])\n\n return (\n <div className={`chat-panel ${className}`.trim()}>\n {/* 顶部标题栏 */}\n {!hideHeader && (\n <ChatHeader\n sessions={sessions}\n currentSessionId={currentSessionId}\n showClose={!!onClose}\n onNewSession={createNewSession}\n onSwitchSession={switchSession}\n onDeleteSession={deleteSession}\n onClose={handleClose}\n onClearAll={handleClearAll}\n onCloseOthers={handleCloseOthers}\n onExport={handleExport}\n onCopyId={handleCopyId}\n onFeedback={handleFeedback}\n onSettings={handleSettings}\n />\n )}\n\n {/* 消息列表 */}\n <div ref={messagesRef} className=\"messages-container\">\n {messages.length === 0 ? (\n <WelcomeMessage onQuickAction={handleQuickAction} />\n ) : (\n messages.map((msg, index) => (\n <MessageBubble\n key={msg.id}\n role={msg.role}\n content={msg.content}\n images={msg.images}\n thinking={msg.thinking}\n thinkingComplete={msg.thinkingComplete}\n searchResults={msg.searchResults}\n searching={msg.searching}\n toolCalls={msg.toolCalls}\n copied={msg.copied}\n loading={msg.loading}\n onCopy={() => copyMessage(msg.id)}\n onRegenerate={() => regenerateMessage(index)}\n onSend={(text) => handleResend(index, text)}\n renderMarkdown={renderMarkdown}\n />\n ))\n )}\n </div>\n\n {/* 输入区域 */}\n <ChatInput\n selectedImages={[]}\n isLoading={isLoading}\n mode={mode}\n model={model}\n models={models}\n webSearchEnabled={webSearch}\n thinkingEnabled={thinking}\n onSend={handleSend}\n onCancel={cancelRequest}\n onModeChange={setMode}\n onModelChange={setModel}\n onWebSearchChange={setWebSearch}\n onThinkingChange={setThinking}\n />\n </div>\n )\n}\n","/**\n * AI Chat 前端类型定义\n * 与 Vue 版本保持一致\n */\n\n/** 搜索结果 */\nexport interface SearchResult {\n title: string\n url: string\n snippet: string\n}\n\n/** 工具调用 */\nexport interface ToolCall {\n name: string\n args?: Record<string, unknown>\n result?: string\n status: 'running' | 'success' | 'error'\n}\n\n/** 模型提供商 */\nexport type ModelProvider = 'openrouter' | 'doubao' | 'deepseek' | 'qwen' | 'gemini' | 'ark'\n\n/** 模型配置 */\nexport interface ModelConfig {\n provider: ModelProvider\n model: string\n displayName: string\n supportsTools: boolean\n supportsWebSearch: boolean\n supportedThinkingModes: ThinkingMode[]\n}\n\n/** 思考模式 */\nexport type ThinkingMode = 'enabled' | 'disabled'\n\n/** 聊天模式 */\nexport type ChatMode = 'agent' | 'ask'\n\n/** 聊天消息 */\nexport interface ChatMessage {\n id: string\n role: 'user' | 'assistant'\n content: string\n images?: string[]\n thinking?: string\n thinkingComplete?: boolean\n searchResults?: SearchResult[]\n searching?: boolean\n toolCalls?: ToolCall[]\n copied?: boolean\n loading?: boolean\n timestamp?: Date\n}\n\n/** 会话记录 */\nexport interface SessionRecord {\n id: string\n title: string\n model: string\n mode: ChatMode\n createdAt: Date\n updatedAt: Date\n}\n\n/** 消息记录 */\nexport interface MessageRecord {\n id: string\n sessionId: string\n role: 'user' | 'assistant'\n content: string\n thinking?: string\n toolCalls?: string\n searchResults?: string\n timestamp: Date\n}\n\n/** 默认模型列表 */\nexport const DEFAULT_MODELS: ModelConfig[] = [\n {\n provider: 'openrouter',\n model: 'anthropic/claude-opus-4.5',\n displayName: 'Claude Opus 4.5',\n supportsTools: true,\n supportsWebSearch: true,\n supportedThinkingModes: ['enabled', 'disabled'],\n },\n {\n provider: 'doubao',\n model: 'doubao-seed-1-6-251015',\n displayName: 'Doubao Seed',\n supportsTools: true,\n supportsWebSearch: true,\n supportedThinkingModes: ['enabled', 'disabled'],\n },\n {\n provider: 'deepseek',\n model: 'deepseek-v3-1-terminus',\n displayName: 'DeepSeek V3',\n supportsTools: true,\n supportsWebSearch: true,\n supportedThinkingModes: ['enabled', 'disabled'],\n },\n {\n provider: 'qwen',\n model: 'qwen3-max-preview',\n displayName: 'Qwen Max',\n supportsTools: true,\n supportsWebSearch: true,\n supportedThinkingModes: ['enabled', 'disabled'],\n },\n {\n provider: 'gemini',\n model: 'gemini-3-pro-preview',\n displayName: 'Gemini 3 Pro',\n supportsTools: true,\n supportsWebSearch: true,\n supportedThinkingModes: ['enabled', 'disabled'],\n },\n]\n\n// ================ 以下为向后兼容的类型 ================\n\n/** @deprecated 使用 SessionRecord */\nexport interface ChatSession {\n id: string\n title: string\n messages: ChatMessage[]\n createdAt: Date\n updatedAt: Date\n}\n\n/** 音视频操作类型 */\nexport interface MediaOperation {\n id: string\n type: 'clip' | 'transcode' | 'merge' | 'extract_audio' | 'add_subtitle' | 'analyze'\n description: string\n sourceFiles: string[]\n targetFile?: string\n parameters?: Record<string, unknown>\n status?: 'pending' | 'applied' | 'rejected'\n preview?: string\n}\n\n/** @deprecated 使用字符串枚举 */\nexport type AiModel = 'gemini-3-pro-preview' | 'gemini-3-pro-image-preview'\n\nexport enum FileType {\n FOLDER = 'folder',\n IMAGE = 'image',\n VIDEO = 'video',\n AUDIO = 'audio',\n TEXT = 'text',\n PDF = 'pdf',\n CODE = 'code',\n ARCHIVE = 'archive',\n OTHER = 'other'\n}\n\nexport interface DiffStat {\n file: string\n additions: number\n deletions: number\n type: 'modified' | 'added' | 'deleted'\n}\n","/**\n * ChatHeader Component\n * 与 Vue 版本 ChatHeader.vue 保持一致\n */\n\nimport { useState, useRef, useEffect, useCallback, type FC } from 'react'\nimport { Plus, Clock, MoreHorizontal, X, MessageSquare, Pencil, Trash2 } from 'lucide-react'\nimport type { SessionRecord } from '../../../types'\n\ninterface ChatHeaderProps {\n /** 当前会话列表 */\n sessions: SessionRecord[]\n /** 当前会话 ID */\n currentSessionId?: string | null\n /** 是否显示关闭按钮 */\n showClose?: boolean\n /** 创建新会话 */\n onNewSession?: () => void\n /** 切换会话 */\n onSwitchSession?: (sessionId: string) => void\n /** 删除会话 */\n onDeleteSession?: (sessionId: string) => void\n /** 关闭面板 */\n onClose?: () => void\n /** 清空所有对话 */\n onClearAll?: () => void\n /** 关闭其他对话 */\n onCloseOthers?: () => void\n /** 导出对话 */\n onExport?: () => void\n /** 复制请求 ID */\n onCopyId?: () => void\n /** 反馈 */\n onFeedback?: () => void\n /** Agent 设置 */\n onSettings?: () => void\n}\n\n/** 格式化时间 */\nfunction formatTime(date: Date | string | undefined): string {\n if (!date) return ''\n const d = new Date(date)\n const now = new Date()\n const diff = now.getTime() - d.getTime()\n const days = Math.floor(diff / (1000 * 60 * 60 * 24))\n \n if (days === 0) {\n return d.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })\n } else if (days === 1) {\n return '昨天'\n } else if (days < 7) {\n return `${days}天前`\n } else {\n return d.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' })\n }\n}\n\nexport const ChatHeader: FC<ChatHeaderProps> = ({\n sessions,\n currentSessionId,\n showClose = false,\n onNewSession,\n onSwitchSession,\n onDeleteSession,\n onClose,\n onClearAll,\n onCloseOthers,\n onExport,\n onCopyId,\n onFeedback,\n onSettings,\n}) => {\n const [historyOpen, setHistoryOpen] = useState(false)\n const [moreMenuOpen, setMoreMenuOpen] = useState(false)\n const [hiddenTabs, setHiddenTabs] = useState<Set<string>>(new Set())\n\n const historyRef = useRef<HTMLDivElement>(null)\n const moreMenuRef = useRef<HTMLDivElement>(null)\n\n // 可见的会话\n const visibleSessions = sessions.filter((s) => !hiddenTabs.has(s.id))\n\n // 点击外部关闭菜单\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (historyRef.current && !historyRef.current.contains(target)) {\n setHistoryOpen(false)\n }\n if (moreMenuRef.current && !moreMenuRef.current.contains(target)) {\n setMoreMenuOpen(false)\n }\n }\n\n document.addEventListener('click', handleClickOutside)\n return () => document.removeEventListener('click', handleClickOutside)\n }, [])\n\n // 切换会话\n const handleSwitchSession = useCallback(\n (sessionId: string) => {\n onSwitchSession?.(sessionId)\n setHistoryOpen(false)\n },\n [onSwitchSession]\n )\n\n // 隐藏 tab\n const handleHideTab = useCallback(\n (sessionId: string, e: React.MouseEvent) => {\n e.stopPropagation()\n setHiddenTabs((prev) => new Set([...prev, sessionId]))\n if (sessionId === currentSessionId) {\n const remaining = sessions.filter((s) => s.id !== sessionId && !hiddenTabs.has(s.id))\n if (remaining.length > 0) {\n onSwitchSession?.(remaining[0].id)\n }\n }\n },\n [currentSessionId, sessions, hiddenTabs, onSwitchSession]\n )\n\n // 删除会话\n const handleDeleteSession = (sessionId: string, e: React.MouseEvent) => {\n e.stopPropagation()\n if (window.confirm('确定要删除这个对话吗?')) {\n onDeleteSession?.(sessionId)\n }\n }\n\n // 菜单项点击\n const handleMenuClick = (callback?: () => void) => {\n callback?.()\n setMoreMenuOpen(false)\n }\n\n return (\n <div className=\"chat-header\">\n {/* 左侧:Tabs */}\n <div className=\"chat-tabs\">\n {visibleSessions.length === 0 ? (\n <span className=\"chat-tab active\">\n <span className=\"chat-tab-title\">New Chat</span>\n </span>\n ) : (\n visibleSessions.map((session) => {\n const title = session.title === '新对话' ? 'New Chat' : session.title\n const isActive = session.id === currentSessionId\n return (\n <div\n key={session.id}\n className={`chat-tab${isActive ? ' active' : ''}`}\n onClick={() => handleSwitchSession(session.id)}\n title={session.title}\n >\n <span className=\"chat-tab-title\">{title}</span>\n <span\n className=\"chat-tab-close\"\n onClick={(e) => handleHideTab(session.id, e)}\n title=\"关闭标签\"\n >\n <X size={12} />\n </span>\n </div>\n )\n })\n )}\n </div>\n\n {/* 右侧:操作按钮 */}\n <div className=\"chat-header-actions\">\n {/* 新建会话 */}\n <button className=\"header-btn\" onClick={onNewSession} title=\"新建对话\">\n <Plus size={14} />\n </button>\n\n {/* 历史记录 */}\n <div ref={historyRef} style={{ position: 'relative' }}>\n <button\n className={`header-btn${historyOpen ? ' active' : ''}`}\n onClick={(e) => {\n e.stopPropagation()\n setHistoryOpen(!historyOpen)\n setMoreMenuOpen(false)\n }}\n title=\"历史记录\"\n >\n <Clock size={14} />\n </button>\n\n {/* 历史记录面板 */}\n {historyOpen && (\n <div className=\"history-panel\">\n {sessions.length === 0 ? (\n <div className=\"history-empty\">暂无历史对话</div>\n ) : (\n sessions.map((session) => {\n const isCurrent = session.id === currentSessionId\n return (\n <div\n key={session.id}\n className={`history-item${isCurrent ? ' active' : ''}`}\n >\n <button\n className=\"history-item-content\"\n onClick={() => handleSwitchSession(session.id)}\n >\n <MessageSquare size={12} />\n <span className=\"history-item-title\">\n {session.title === '新对话' ? 'New Chat' : session.title}\n </span>\n <span className=\"history-item-time\">\n {isCurrent ? 'Current' : formatTime(session.updatedAt)}\n </span>\n </button>\n <div className=\"history-item-actions\">\n <button className=\"history-action-btn\" title=\"编辑\">\n <Pencil size={10} />\n </button>\n <button\n className=\"history-action-btn delete\"\n title=\"删除\"\n onClick={(e) => handleDeleteSession(session.id, e)}\n >\n <Trash2 size={10} />\n </button>\n </div>\n </div>\n )\n })\n )}\n </div>\n )}\n </div>\n\n {/* 更多选项 */}\n <div ref={moreMenuRef} style={{ position: 'relative' }}>\n <button\n className={`header-btn${moreMenuOpen ? ' active' : ''}`}\n onClick={(e) => {\n e.stopPropagation()\n setMoreMenuOpen(!moreMenuOpen)\n setHistoryOpen(false)\n }}\n title=\"更多选项\"\n >\n <MoreHorizontal size={14} />\n </button>\n\n {/* 更多选项菜单 */}\n {moreMenuOpen && (\n <div className=\"more-menu\">\n {showClose && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onClose)}>\n <span>关闭对话</span>\n <span className=\"menu-shortcut\">⌘ W</span>\n </button>\n )}\n {onClearAll && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onClearAll)}>\n 清空所有对话\n </button>\n )}\n {onCloseOthers && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onCloseOthers)}>\n 关闭其他对话\n </button>\n )}\n \n {(showClose || onClearAll || onCloseOthers) && <div className=\"menu-divider\" />}\n \n {onExport && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onExport)}>\n 导出对话\n </button>\n )}\n {onCopyId && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onCopyId)}>\n 复制请求 ID\n </button>\n )}\n {onFeedback && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onFeedback)}>\n 反馈\n </button>\n )}\n \n {(onExport || onCopyId || onFeedback) && onSettings && <div className=\"menu-divider\" />}\n \n {onSettings && (\n <button className=\"menu-item\" onClick={() => handleMenuClick(onSettings)}>\n Agent 设置\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n","/**\n * WelcomeMessage Component\n * 与 Vue 版本 WelcomeMessage.vue 保持一致\n */\n\nimport { type FC } from 'react'\nimport { Wand2, ImageIcon, Video, Terminal } from 'lucide-react'\n\ninterface WelcomeMessageProps {\n /** 快捷操作回调 */\n onQuickAction: (text: string) => void\n}\n\n/** 快捷操作配置 */\nconst QUICK_ACTIONS = [\n {\n id: 'txt2img',\n Icon: Wand2,\n label: '文生图',\n desc: 'AI 绘制创意图像',\n prompt: '帮我生成一张图片:',\n gradient: 'purple',\n iconColor: 'purple',\n featured: true,\n },\n {\n id: 'img2img',\n Icon: ImageIcon,\n label: '图生图',\n desc: '风格迁移',\n prompt: '基于这张图片进行风格转换',\n gradient: 'blue',\n iconColor: 'blue',\n featured: false,\n },\n {\n id: 'img2vid',\n Icon: Video,\n label: '图生视频',\n desc: '动态化',\n prompt: '将这张图片转换成视频',\n gradient: 'emerald',\n iconColor: 'emerald',\n featured: false,\n },\n {\n id: 'cmd',\n Icon: Terminal,\n label: '执行命令',\n desc: '系统管理',\n prompt: '执行命令:',\n gradient: 'orange',\n iconColor: 'orange',\n featured: true,\n },\n]\n\nexport const WelcomeMessage: FC<WelcomeMessageProps> = ({ onQuickAction }) => {\n return (\n <div className=\"welcome-message\">\n {/* 动态极光背景 */}\n <div className=\"welcome-glow purple\" />\n <div className=\"welcome-glow blue\" />\n\n {/* 标题区域 */}\n <div className=\"welcome-title-area\">\n <h1 className=\"welcome-title\">\n Create\n <br />\n <span className=\"welcome-title-accent\">Everything</span>\n </h1>\n <p className=\"welcome-subtitle\">释放 AI 的无限创造力</p>\n </div>\n\n {/* 快捷操作网格 */}\n <div className=\"quick-actions\">\n {QUICK_ACTIONS.map((action) => (\n <button\n key={action.id}\n className={`quick-action-btn${action.featured ? ' featured' : ''}`}\n onClick={() => onQuickAction(action.prompt)}\n >\n {/* 卡片背景渐变 */}\n <div className={`quick-action-gradient ${action.gradient}`} />\n\n {/* 图标 */}\n <action.Icon className={`quick-action-icon ${action.iconColor}`} />\n\n {/* 文字 */}\n <div className=\"quick-action-text\">\n <span className=\"quick-action-label\">{action.label}</span>\n <span className=\"quick-action-desc\">{action.desc}</span>\n </div>\n\n {/* 装饰性光斑 */}\n <div className=\"quick-action-glow\" />\n </button>\n ))}\n </div>\n\n {/* 底部装饰 */}\n <div className=\"welcome-footer\">\n <div className=\"welcome-footer-line\" />\n </div>\n </div>\n )\n}\n","/**\n * MessageBubble Component\n * 与 Vue 版本 MessageBubble.vue 保持一致\n */\n\nimport { type FC, type ReactNode } from 'react'\nimport { Copy, Check, RefreshCw } from 'lucide-react'\nimport { ExecutionSteps } from './ExecutionSteps'\nimport { ChatInput } from '../../ChatInput'\nimport type { SearchResult, ToolCall } from '../../../types'\n\ninterface MessageBubbleProps {\n role: 'user' | 'assistant'\n content: string\n images?: string[]\n thinking?: string\n thinkingComplete?: boolean\n thinkingDuration?: number\n searchResults?: SearchResult[]\n searching?: boolean\n toolCalls?: ToolCall[]\n copied?: boolean\n loading?: boolean\n onCopy?: () => void\n onRegenerate?: () => void\n /** 编辑用户消息后重新发送 */\n onSend?: (text: string) => void\n /** 自定义 Markdown 渲染器 */\n renderMarkdown?: (content: string) => ReactNode\n}\n\n/** 默认 Markdown 渲染(简单处理) */\nfunction defaultRenderMarkdown(content: string): ReactNode {\n // 简单的 Markdown 处理:代码块\n const parts = content.split(/(```[\\s\\S]*?```)/g)\n \n return parts.map((part, i) => {\n if (part.startsWith('```') && part.endsWith('```')) {\n const code = part.slice(3, -3)\n const firstLine = code.indexOf('\\n')\n const lang = firstLine > 0 ? code.slice(0, firstLine).trim() : ''\n const codeContent = firstLine > 0 ? code.slice(firstLine + 1) : code\n return (\n <pre key={i}>\n <code>{codeContent}</code>\n </pre>\n )\n }\n // 处理行内代码\n const inlineParts = part.split(/(`[^`]+`)/g)\n return (\n <span key={i}>\n {inlineParts.map((p, j) => {\n if (p.startsWith('`') && p.endsWith('`')) {\n return <code key={j}>{p.slice(1, -1)}</code>\n }\n return p\n })}\n </span>\n )\n })\n}\n\nexport const MessageBubble: FC<MessageBubbleProps> = ({\n role,\n content,\n images,\n thinking,\n thinkingComplete = true,\n thinkingDuration,\n searchResults,\n searching,\n toolCalls,\n copied,\n loading,\n onCopy,\n onRegenerate,\n onSend,\n renderMarkdown = defaultRenderMarkdown,\n}) => {\n const isUser = role === 'user'\n\n return (\n <div className=\"message-bubble\">\n {/* 用户消息 - 复用 ChatInput 组件 */}\n {isUser ? (\n <ChatInput\n variant=\"message\"\n value={content}\n selectedImages={images}\n onSend={onSend}\n />\n ) : (\n /* AI 消息 */\n <div className=\"assistant-message\">\n {/* 执行步骤列表 */}\n <ExecutionSteps\n loading={loading}\n hasContent={!!content}\n thinking={thinking}\n thinkingComplete={thinkingComplete}\n thinkingDuration={thinkingDuration}\n searching={searching}\n searchResults={searchResults}\n toolCalls={toolCalls}\n />\n\n {/* 消息内容 */}\n {content && (\n <div className=\"message-content\">\n {renderMarkdown(content)}\n </div>\n )}\n\n {/* 操作按钮 */}\n {content && !loading && (\n <div className=\"message-actions\">\n <button className={`action-btn${copied ? ' copied' : ''}`} onClick={onCopy} title=\"复制\">\n {copied ? <Check size={14} /> : <Copy size={14} />}\n </button>\n <button className=\"action-btn\" onClick={onRegenerate} title=\"重新生成\">\n <RefreshCw size={14} />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n","/**\n * ExecutionSteps Component\n * 与 Vue 版本 ExecutionSteps.vue 保持一致\n */\n\nimport { useState, type FC, type ReactNode } from 'react'\nimport {\n ChevronDown,\n ChevronUp,\n Sparkles,\n Globe,\n FileText,\n FileEdit,\n Terminal,\n Search,\n Folder,\n FolderPlus,\n Trash2,\n Image,\n Video,\n Wrench,\n ExternalLink,\n} from 'lucide-react'\nimport type { SearchResult, ToolCall } from '../../../types'\n\ninterface ExecutionStepsProps {\n /** 是否正在加载 */\n loading?: boolean\n /** 是否有消息内容 */\n hasContent?: boolean\n /** 思考内容 */\n thinking?: string\n /** 思考是否完成 */\n thinkingComplete?: boolean\n /** 思考耗时 */\n thinkingDuration?: number\n /** 是否正在搜索 */\n searching?: boolean\n /** 搜索结果 */\n searchResults?: SearchResult[]\n /** 工具调用列表 */\n toolCalls?: ToolCall[]\n}\n\n/** 步骤项组件 */\ninterface StepItemProps {\n icon: ReactNode\n title: string\n status: 'running' | 'completed' | 'error'\n extra?: string\n detail?: ReactNode\n defaultExpanded?: boolean\n}\n\nconst StepItem: FC<StepItemProps> = ({\n icon,\n title,\n status,\n extra,\n detail,\n defaultExpanded = false,\n}) => {\n const [expanded, setExpanded] = useState(defaultExpanded)\n const isRunning = status === 'running'\n const hasDetail = !!detail\n\n return (\n <div className=\"step-item\">\n <button\n className={`step-header${isRunning ? ' running' : ''}`}\n onClick={() => hasDetail && setExpanded(!expanded)}\n disabled={!hasDetail}\n style={{ cursor: hasDetail ? 'pointer' : 'default' }}\n >\n <span className={`step-icon${isRunning ? ' pulse' : ''}`}>{icon}</span>\n <span className=\"step-title\">{title}</span>\n {hasDetail && (\n expanded ? <ChevronUp className=\"step-chevron\" size={12} /> : <ChevronDown className=\"step-chevron\" size={12} />\n )}\n {extra && <span className=\"step-extra\">{extra}</span>}\n </button>\n\n {expanded && detail && (\n <div className=\"step-detail\">\n {typeof detail === 'string' ? <pre>{detail}</pre> : detail}\n </div>\n )}\n </div>\n )\n}\n\n/** 获取工具调用的显示名称 */\nfunction getToolDisplayName(name: string): string {\n const nameMap: Record<string, string> = {\n read_file: '读取文件',\n write_file: '写入文件',\n execute_command: '执行命令',\n search_files: '搜索文件',\n list_directory: '列出目录',\n create_directory: '创建目录',\n delete_file: '删除文件',\n web_search: '网页搜索',\n generate_image: '生成图片',\n image_to_video: '图片转视频',\n }\n return nameMap[name] || name\n}\n\n/** 获取工具调用的图标 */\nfunction getToolIcon(name: string) {\n switch (name) {\n case 'read_file': return <FileText size={14} />\n case 'write_file': return <FileEdit size={14} />\n case 'execute_command': return <Terminal size={14} />\n case 'search_files': return <Search size={14} />\n case 'list_directory': return <Folder size={14} />\n case 'create_directory': return <FolderPlus size={14} />\n case 'delete_file': return <Trash2 size={14} />\n case 'web_search': return <Globe size={14} />\n case 'generate_image': return <Image size={14} />\n case 'image_to_video': return <Video size={14} />\n default: return <Wrench size={14} />\n }\n}\n\n/** 格式化工具调用参数 */\nfunction formatToolArgs(args?: Record<string, unknown>): string {\n if (!args) return ''\n return Object.entries(args)\n .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)\n .join('\\n')\n}\n\nexport const ExecutionSteps: FC<ExecutionStepsProps> = ({\n loading,\n hasContent,\n thinking,\n thinkingComplete = true,\n thinkingDuration,\n searching,\n searchResults,\n toolCalls,\n}) => {\n // 判断是否有任何执行步骤\n const hasSteps =\n thinking ||\n searching ||\n (searchResults && searchResults.length > 0) ||\n (toolCalls && toolCalls.length > 0) ||\n (loading && !hasContent)\n\n if (!hasSteps) return null\n\n return (\n <div className=\"execution-steps\">\n {/* 正在规划 */}\n {loading && !hasContent && !thinking && !searching && (!toolCalls || toolCalls.length === 0) && (\n <StepItem\n icon={<Sparkles size={14} />}\n title=\"正在规划下一步...\"\n status=\"running\"\n />\n )}\n\n {/* 思考过程 */}\n {thinking && (\n <StepItem\n icon={<Sparkles size={14} />}\n title={thinkingComplete ? '思考完成' : '思考中...'}\n status={thinkingComplete ? 'completed' : 'running'}\n extra={thinkingDuration ? `${thinkingDuration}s` : undefined}\n detail={thinking}\n />\n )}\n\n {/* 搜索 */}\n {(searching || (searchResults && searchResults.length > 0)) && (\n <StepItem\n icon={<Globe size={14} />}\n title={searching ? '搜索中...' : `搜索完成 ${searchResults?.length || 0} 条结果`}\n status={searching ? 'running' : 'completed'}\n detail={\n searchResults && searchResults.length > 0 ? (\n <div>\n {searchResults.map((result, i) => (\n <a\n key={i}\n href={result.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"search-result-item\"\n >\n <div className=\"search-result-title\">\n <span>{result.title}</span>\n <ExternalLink size={12} style={{ opacity: 0.5 }} />\n </div>\n <div className=\"search-result-snippet\">{result.snippet}</div>\n </a>\n ))}\n </div>\n ) : undefined\n }\n />\n )}\n\n {/* 工具调用 */}\n {toolCalls &&\n toolCalls.map((call, index) => (\n <StepItem\n key={`tool-${index}`}\n icon={getToolIcon(call.name)}\n title={`${getToolDisplayName(call.name)}${call.status === 'running' ? '...' : ''}`}\n status={call.status === 'running' ? 'running' : call.status === 'error' ? 'error' : 'completed'}\n detail={\n <div>\n {call.args && (\n <div style={{ marginBottom: call.result ? 8 : 0 }}>\n <div style={{ fontSize: 10, color: 'var(--chat-text-muted)', marginBottom: 4 }}>参数</div>\n <pre style={{ margin: 0 }}>{formatToolArgs(call.args)}</pre>\n </div>\n )}\n {call.result && (\n <div>\n <div style={{ fontSize: 10, color: 'var(--chat-text-muted)', marginBottom: 4 }}>结果</div>\n <pre style={{ margin: 0, maxHeight: 160, overflow: 'auto' }}>{call.result}</pre>\n </div>\n )}\n </div>\n }\n />\n ))}\n </div>\n )\n}\n","/**\n * ChatInput Component\n * 与 Vue 版本 ChatInput.vue 保持一致\n */\n\nimport { useState, useRef, useCallback, useEffect, type FC } from 'react'\nimport {\n X,\n ChevronDown,\n Check,\n Globe,\n Sparkles,\n ImageIcon,\n Square,\n ArrowUp,\n Zap,\n MessageCircle,\n AtSign,\n Mic,\n} from 'lucide-react'\nimport type { ChatMode, ModelConfig } from '../types'\nimport { DEFAULT_MODELS } from '../types'\n\ninterface ChatInputProps {\n /** 变体模式:input-底部输入框,message-历史消息 */\n variant?: 'input' | 'message'\n /** 受控值(用于历史消息编辑) */\n value?: string\n selectedImages?: string[]\n isLoading?: boolean\n mode?: ChatMode\n model?: string\n models?: ModelConfig[]\n webSearchEnabled?: boolean\n thinkingEnabled?: boolean\n onSend?: (text: string) => void\n onRemoveImage?: (index: number) => void\n onCancel?: () => void\n onUploadImage?: () => void\n onAtContext?: () => void\n onModeChange?: (mode: ChatMode) => void\n onModelChange?: (model: string) => void\n onWebSearchChange?: (enabled: boolean) => void\n onThinkingChange?: (enabled: boolean) => void\n}\n\n/** 模式配置 */\nconst MODES = [\n { value: 'agent' as const, label: 'Agent', Icon: Zap },\n { value: 'ask' as const, label: 'Ask', Icon: MessageCircle },\n]\n\nexport const ChatInput: FC<ChatInputProps> = ({\n variant = 'input',\n value = '',\n selectedImages = [],\n isLoading = false,\n mode = 'agent',\n model = '',\n models = DEFAULT_MODELS,\n webSearchEnabled = false,\n thinkingEnabled = false,\n onSend,\n onRemoveImage,\n onCancel,\n onUploadImage,\n onAtContext,\n onModeChange,\n onModelChange,\n onWebSearchChange,\n onThinkingChange,\n}) => {\n const isMessageVariant = variant === 'message'\n\n const [inputText, setInputText] = useState(value)\n const [isFocused, setIsFocused] = useState(false)\n const [modeMenuOpen, setModeMenuOpen] = useState(false)\n const [modelMenuOpen, setModelMenuOpen] = useState(false)\n\n const inputRef = useRef<HTMLTextAreaElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n // 同步外部 value\n useEffect(() => {\n setInputText(value)\n }, [value])\n\n const currentMode = MODES.find((m) => m.value === mode) || MODES[0]\n const currentModel = models.find((m) => m.model === model)\n\n // 是否显示工具栏\n const showToolbar = !isMessageVariant || isFocused\n\n // 预览\n const selectedPreview = selectedImages.slice(0, 3)\n\n // 占位符\n const placeholder = selectedImages.length > 0\n ? '描述你想要的效果...'\n : mode === 'ask'\n ? '有什么问题想问我?'\n : '描述任务,@ 添加上下文'\n\n // 自动调整高度\n const adjustTextareaHeight = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.style.height = 'auto'\n const scrollHeight = inputRef.current.scrollHeight\n inputRef.current.style.height = `${Math.min(scrollHeight, 150)}px`\n }\n }, [])\n\n // 发送或取消\n const handleSendOrCancel = useCallback(() => {\n if (isLoading) {\n onCancel?.()\n return\n }\n\n const text = inputText.trim()\n if (!text) return\n\n onSend?.(text)\n\n if (!isMessageVariant) {\n setInputText('')\n if (inputRef.current) {\n inputRef.current.style.height = 'auto'\n }\n inputRef.current?.focus()\n } else {\n setIsFocused(false)\n }\n }, [isLoading, inputText, onSend, onCancel, isMessageVariant])\n\n // 键盘事件\n const handleKeydown = useCallback(\n (event: React.KeyboardEvent) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault()\n handleSendOrCancel()\n } else {\n setTimeout(adjustTextareaHeight, 0)\n }\n },\n [handleSendOrCancel, adjustTextareaHeight]\n )\n\n // 选择模式\n const selectMode = useCallback(\n (value: ChatMode) => {\n onModeChange?.(value)\n setModeMenuOpen(false)\n },\n [onModeChange]\n )\n\n // 选择模型\n const selectModel = useCallback(\n (m: ModelConfig) => {\n onModelChange?.(m.model)\n setModelMenuOpen(false)\n },\n [onModelChange]\n )\n\n // 图片 URL 处理\n const getImageUrl = (path: string): string => {\n if (\n path.startsWith('app://') ||\n path.startsWith('file://') ||\n path.startsWith('data:') ||\n path.startsWith('http')\n ) {\n return path\n }\n if (path.match(/^[A-Z]:\\\\/i)) {\n return `app://file${encodeURIComponent(path.replace(/\\\\/g, '/'))}`\n }\n return `app://file${encodeURIComponent(path)}`\n }\n\n // 点击外部关闭菜单\n useEffect(() => {\n const handleClickOutside = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (!target.closest('.selector')) {\n setModeMenuOpen(false)\n setModelMenuOpen(false)\n }\n if (\n isMessageVariant &&\n containerRef.current &&\n !containerRef.current.contains(target)\n ) {\n setIsFocused(false)\n }\n }\n\n document.addEventListener('click', handleClickOutside)\n return () => document.removeEventListener('click', handleClickOutside)\n }, [isMessageVariant])\n\n const CurrentModeIcon = currentMode.Icon\n\n return (\n <div className={`chat-input${isMessageVariant ? ' message-variant' : ''}`}>\n <div\n ref={containerRef}\n className={`input-container${isFocused ? ' focused' : ''}`}\n >\n {/* 附件预览 */}\n {selectedImages.length > 0 && (\n <div className=\"attachment-preview\">\n <div className=\"preview-images\">\n {selectedPreview.map((img, index) => (\n <div key={`${img}-${index}`} className=\"preview-item\">\n <img\n src={getImageUrl(img)}\n className=\"preview-thumb\"\n alt={`附件 ${index + 1}`}\n onError={(e) => {\n (e.target as HTMLImageElement).style.display = 'none'\n }}\n />\n {!isMessageVariant && (\n <button\n className=\"remove-btn\"\n title={`移除图片 ${index + 1}`}\n onClick={() => onRemoveImage?.(index)}\n >\n <X size={10} />\n </button>\n )}\n </div>\n ))}\n {selectedImages.length > 3 && (\n <div className=\"preview-more\">+{selectedImages.length - 3}</div>\n )}\n </div>\n </div>\n )}\n\n {/* 输入框 */}\n <div className=\"input-field-wrapper\">\n <textarea\n ref={inputRef}\n value={inputText}\n onChange={(e) => setInputText(e.target.value)}\n onKeyDown={handleKeydown}\n onInput={adjustTextareaHeight}\n onFocus={() => setIsFocused(true)}\n placeholder={placeholder}\n rows={1}\n className=\"input-field\"\n />\n </div>\n\n {/* 底部控制栏 */}\n {showToolbar && (\n <div className=\"input-controls\">\n {/* 左侧:模式和模型选择 */}\n <div className=\"input-left\">\n {/* 模式选择 */}\n <div\n className=\"selector mode-selector\"\n onClick={(e) => {\n e.stopPropagation()\n setModeMenuOpen(!modeMenuOpen)\n setModelMenuOpen(false)\n }}\n >\n <CurrentModeIcon size={12} />\n <span>{currentMode.label}</span>\n <ChevronDown size={10} className=\"chevron\" />\n\n {modeMenuOpen && (\n <div className=\"dropdown-menu\" onClick={(e) => e.stopPropagation()}>\n {MODES.map((m) => (\n <button\n key={m.value}\n className={`dropdown-item${mode === m.value ? ' active' : ''}`}\n onClick={() => selectMode(m.value)}\n >\n <m.Icon size={14} />\n <span>{m.label}</span>\n {mode === m.value && <Check size={14} className=\"check-icon\" />}\n </button>\n ))}\n </div>\n )}\n </div>\n\n {/* 模型选择 */}\n <div\n className=\"selector model-selector\"\n onClick={(e) => {\n e.stopPropagation()\n setModelMenuOpen(!modelMenuOpen)\n setModeMenuOpen(false)\n }}\n >\n <span>{currentModel?.displayName || 'Auto'}</span>\n <ChevronDown size={10} className=\"chevron\" />\n\n {modelMenuOpen && (\n <div className=\"dropdown-menu\" onClick={(e) => e.stopPropagation()}>\n {models.map((m) => (\n <button\n key={m.model}\n className={`dropdown-item${model === m.model ? ' active' : ''}`}\n onClick={() => selectModel(m)}\n >\n <span>{m.displayName}</span>\n {model === m.model && <Check size={14} className=\"check-icon\" />}\n </button>\n ))}\n </div>\n )}\n </div>\n </div>\n\n {/* 右侧:功能按钮 */}\n <div className=\"input-right\">\n <button className=\"icon-btn\" title=\"提及上下文 (@)\" onClick={onAtContext}>\n <AtSign size={14} />\n </button>\n\n <button\n className={`toggle-btn${thinkingEnabled ? ' active' : ''}`}\n title=\"深度思考\"\n onClick={() => onThinkingChange?.(!thinkingEnabled)}\n >\n <Sparkles size={14} />\n </button>\n\n <button\n className={`toggle-btn${webSearchEnabled ? ' active' : ''}`}\n title=\"联网搜索\"\n onClick={() => onWebSearchChange?.(!webSearchEnabled)}\n >\n <Globe size={14} />\n </button>\n\n <button className=\"icon-btn\" title=\"上传图片\" onClick={onUploadImage}>\n <ImageIcon size={14} />\n </button>\n\n {inputText.trim() || isLoading ? (\n <button\n className={`send-btn${isLoading ? ' loading' : ''}`}\n title={isLoading ? '停止' : isMessageVariant ? '重新发送' : '发送'}\n onClick={handleSendOrCancel}\n >\n {isLoading ? <Square size={14} /> : <ArrowUp size={14} />}\n </button>\n ) : (\n <button className=\"icon-btn\" title=\"语音输入\">\n <Mic size={14} />\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n </div>\n )\n}\n"],"mappings":"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","names":["useEffect","useRef","useCallback","FileType","useState","useRef","useCallback","jsx","jsxs","Check","useState","Terminal","Trash2","Video","jsx","jsxs","useState","useRef","useCallback","useEffect","X","ChevronDown","Globe","Sparkles","ImageIcon","jsx","jsxs","useState","useRef","useEffect","useCallback","value","X","ChevronDown","Sparkles","Globe","ImageIcon","jsx","jsxs","Check","jsx","jsxs","useRef","useEffect","useCallback"]}