diff --git a/src/app/chat/[id]/page.tsx b/src/app/chat/[id]/page.tsx index 9e11413..ca8d10a 100644 --- a/src/app/chat/[id]/page.tsx +++ b/src/app/chat/[id]/page.tsx @@ -89,10 +89,14 @@ export default function ChatPage({ params }: PageProps) { outputTokens: msg.outputTokens || undefined, // 从数据库加载图片数据(代码执行产生的) images: (msg.images as string[]) || undefined, + // 从数据库加载搜索到的图片(图片搜索工具结果) + searchImages: (msg.searchImages as { title: string; imageUrl: string; width: number; height: number; score: string; position: number; sourceUrl?: string }[]) || undefined, // 从数据库加载用户上传的图片 uploadedImages: (msg.uploadedImages as string[]) || undefined, // 从数据库加载用户上传的文档 uploadedDocuments: (msg.uploadedDocuments as { name: string; size: number; type: string; content: string }[]) || undefined, + // 从数据库加载使用的工具列表 + usedTools: (msg.usedTools as string[]) || undefined, })); setInitialMessages(historyMessages); } @@ -563,8 +567,10 @@ export default function ChatPage({ params }: PageProps) { isStreaming={message.status === 'streaming'} error={message.error} images={message.images} + searchImages={message.searchImages} uploadedImages={message.uploadedImages} uploadedDocuments={message.uploadedDocuments} + usedTools={message.usedTools} pyodideStatus={message.pyodideStatus} onRegenerate={message.role === 'assistant' && !isStreaming ? handleRegenerate : undefined} onSaveToNote={message.role === 'assistant' && !isStreaming ? handleSaveToNote : undefined} diff --git a/src/app/settings/page.tsx b/src/app/settings/page.tsx index 9e7344c..99e372f 100644 --- a/src/app/settings/page.tsx +++ b/src/app/settings/page.tsx @@ -56,6 +56,11 @@ export default function SettingsPage() { const [showApiKey, setShowApiKey] = useState(false); const [saveStatus, setSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle'); + // 秘塔AI 配置状态 + const [metasoApiKey, setMetasoApiKey] = useState(''); + const [showMetasoApiKey, setShowMetasoApiKey] = useState(false); + const [metasoSaveStatus, setMetasoSaveStatus] = useState<'idle' | 'saving' | 'saved' | 'error'>('idle'); + // AI 行为设置状态 const [systemPrompt, setSystemPrompt] = useState(''); const [temperature, setTemperature] = useState('0.7'); @@ -107,6 +112,31 @@ export default function SettingsPage() { } }; + // 保存秘塔AI API Key + const handleSaveMetasoConfig = async () => { + setMetasoSaveStatus('saving'); + try { + if (metasoApiKey) { + await updateSettings({ metasoApiKey }); + } + setMetasoSaveStatus('saved'); + setMetasoApiKey(''); // 清除输入的 API Key + setTimeout(() => setMetasoSaveStatus('idle'), 2000); + } catch { + setMetasoSaveStatus('error'); + setTimeout(() => setMetasoSaveStatus('idle'), 2000); + } + }; + + // 清除秘塔 API Key + const handleClearMetasoApiKey = async () => { + try { + await updateSettings({ metasoApiKey: '' }); + } catch (error) { + console.error('Failed to clear Metaso API key:', error); + } + }; + // 更新默认模型 const handleModelChange = async (modelId: string) => { try { @@ -476,6 +506,95 @@ export default function SettingsPage() { + {/* 秘塔AI 配置 */} + + + 配置后可使用 Metaso Search 和 Metaso Reader 工具。 + + 前往秘塔平台获取 API Key → + + + ) + } + > + + {settings?.metasoApiKeyConfigured ? ( + <> + + + 已配置 + + + 清除 + + > + ) : ( + + setMetasoApiKey(e.target.value)} + placeholder="输入秘塔 API Key" + /> + setShowMetasoApiKey(!showMetasoApiKey)} + > + {showMetasoApiKey ? : } + + + )} + + + + {!settings?.metasoApiKeyConfigured && ( + + + {metasoSaveStatus === 'saving' ? ( + + ) : metasoSaveStatus === 'saved' ? ( + + ) : null} + {metasoSaveStatus === 'saving' ? '保存中...' : metasoSaveStatus === 'saved' ? '已保存' : '保存秘塔配置'} + + {metasoSaveStatus === 'error' && ( + 保存失败 + )} + + )} + + + + 💡 秘塔工具说明:Metaso Search 提供高质量中文搜索,Metaso Reader 可将网页转换为结构化 Markdown。 + 未配置 API Key 时,这些工具仍可选择但无法使用。 + + + + {/* 模型和工具设置 */}
+ 💡 秘塔工具说明:Metaso Search 提供高质量中文搜索,Metaso Reader 可将网页转换为结构化 Markdown。 + 未配置 API Key 时,这些工具仍可选择但无法使用。 +