diff --git a/dashboard/src/i18n/locales/en-US/features/session-management.json b/dashboard/src/i18n/locales/en-US/features/session-management.json index 84ddc0cdb..ee4880d1e 100644 --- a/dashboard/src/i18n/locales/en-US/features/session-management.json +++ b/dashboard/src/i18n/locales/en-US/features/session-management.json @@ -30,6 +30,7 @@ "ttsProvider": "TTS Provider", "llmStatus": "LLM Status", "ttsStatus": "TTS Status", + "knowledgeBase": "Knowledge Base", "pluginManagement": "Plugin Management", "actions": "Actions" } @@ -67,6 +68,31 @@ "fullSessionId": "Full Session ID", "hint": "Custom names help you easily identify sessions. The small information icon (!) will show the actual UMO when hovering." }, + "knowledgeBase": { + "title": "Knowledge Base Configuration", + "configure": "Configure", + "selectKB": "Select Knowledge Bases", + "selectMultiple": "You can select multiple knowledge bases", + "noKBAvailable": "No knowledge bases available", + "noKBDesc": "No knowledge bases have been created yet", + "createKB": "Create Knowledge Base", + "advancedSettings": "Advanced Settings", + "topK": "Result Count", + "topKHint": "Number of results to retrieve from knowledge base", + "enableRerank": "Enable Reranking", + "enableRerankHint": "Use reranking model to improve retrieval quality", + "clearConfig": "Clear Configuration", + "save": "Save", + "cancel": "Cancel", + "loading": "Loading knowledge base configuration...", + "description": "Configure knowledge bases for this session. The session will use configured knowledge bases to enhance conversation context.", + "saveSuccess": "Knowledge base configuration saved successfully", + "saveFailed": "Failed to save knowledge base configuration", + "loadFailed": "Failed to load knowledge base configuration", + "clearSuccess": "Knowledge base configuration cleared", + "clearFailed": "Failed to clear knowledge base configuration", + "clearConfirm": "Are you sure you want to clear the knowledge base configuration for this session?" + }, "deleteConfirm": { "message": "Are you sure you want to delete session {sessionName}?", "warning": "This action will permanently delete all chat history and preference settings for this session (except for data linked via plugins), and this cannot be undone. Continue?" diff --git a/dashboard/src/i18n/locales/zh-CN/features/session-management.json b/dashboard/src/i18n/locales/zh-CN/features/session-management.json index 6e93ef76f..e59c7a5f2 100644 --- a/dashboard/src/i18n/locales/zh-CN/features/session-management.json +++ b/dashboard/src/i18n/locales/zh-CN/features/session-management.json @@ -30,6 +30,7 @@ "ttsProvider": "语音合成模型", "llmStatus": "启用 LLM", "ttsStatus": "启用 TTS", + "knowledgeBase": "知识库配置", "pluginManagement": "插件管理", "actions": "操作" } @@ -67,6 +68,31 @@ "fullSessionId": "完整会话ID", "hint": "自定义名称帮助您轻松识别会话。当设置了自定义名称时,会显示一个小感叹号标识(!),鼠标悬停时会显示实际的UMO。" }, + "knowledgeBase": { + "title": "知识库配置", + "configure": "配置", + "selectKB": "选择知识库", + "selectMultiple": "可以选择多个知识库", + "noKBAvailable": "暂无可用的知识库", + "noKBDesc": "目前没有创建任何知识库", + "createKB": "创建知识库", + "advancedSettings": "高级配置", + "topK": "返回结果数量", + "topKHint": "从知识库检索的结果数量", + "enableRerank": "启用重排序", + "enableRerankHint": "使用重排序模型提高检索质量", + "clearConfig": "清除配置", + "save": "保存", + "cancel": "取消", + "loading": "加载知识库配置中...", + "description": "为此会话配置使用的知识库。会话将使用配置的知识库来增强对话上下文。", + "saveSuccess": "知识库配置保存成功", + "saveFailed": "保存知识库配置失败", + "loadFailed": "加载知识库配置失败", + "clearSuccess": "知识库配置已清除", + "clearFailed": "清除知识库配置失败", + "clearConfirm": "确定要清除此会话的知识库配置吗?" + }, "deleteConfirm": { "message": "确定要删除会话 {sessionName} 吗?", "warning": "此操作将永久删除本次会话的「全部对话记录」与「偏好设置」(插件对会话的关联数据除外),且无法恢复。确认继续?" diff --git a/dashboard/src/views/SessionManagementPage.vue b/dashboard/src/views/SessionManagementPage.vue index a77cfd872..543b0f6f7 100644 --- a/dashboard/src/views/SessionManagementPage.vue +++ b/dashboard/src/views/SessionManagementPage.vue @@ -142,6 +142,14 @@ + + + @@ -291,6 +329,10 @@ const deleting = ref(false) const kbList = ref([]) const embeddingProviders = ref([]) const rerankProviders = ref([]) +const originalEmbeddingProvider = ref(null) +const showEmbeddingWarning = ref(false) +const embeddingChangeDialog = ref(false) +const pendingEmbeddingProvider = ref(null) // 对话框 const showCreateDialog = ref(false) @@ -386,6 +428,7 @@ const navigateToDetail = (kbId: string) => { // 编辑知识库 const editKB = (kb: any) => { editingKB.value = kb + originalEmbeddingProvider.value = kb.embedding_provider_id formData.value = { kb_name: kb.kb_name, description: kb.description || '', @@ -396,6 +439,39 @@ const editKB = (kb: any) => { showCreateDialog.value = true } +// 处理 embedding provider 变更 +const handleEmbeddingProviderChange = (newValue: string | null) => { + // 检测是否修改了embedding provider + if (newValue && originalEmbeddingProvider.value && newValue !== originalEmbeddingProvider.value) { + // 显示二次确认对话框 + showEmbeddingWarning.value = true + pendingEmbeddingProvider.value = newValue + embeddingChangeDialog.value = true + } else { + showEmbeddingWarning.value = false + } +} + +// 确认修改 embedding provider +const confirmEmbeddingChange = () => { + if (pendingEmbeddingProvider.value) { + formData.value.embedding_provider_id = pendingEmbeddingProvider.value + // 更新原始值,这样下次比较时不会重复弹窗 + originalEmbeddingProvider.value = pendingEmbeddingProvider.value + } + embeddingChangeDialog.value = false + showEmbeddingWarning.value = true +} + +// 取消修改 embedding provider +const cancelEmbeddingChange = () => { + // 恢复到原始值 + formData.value.embedding_provider_id = originalEmbeddingProvider.value + embeddingChangeDialog.value = false + showEmbeddingWarning.value = false + pendingEmbeddingProvider.value = null +} + // 确认删除 const confirmDelete = (kb: any) => { deleteTarget.value = kb @@ -481,6 +557,9 @@ const submitForm = async () => { const closeCreateDialog = () => { showCreateDialog.value = false editingKB.value = null + originalEmbeddingProvider.value = null + showEmbeddingWarning.value = false + pendingEmbeddingProvider.value = null formData.value = { kb_name: '', description: '', diff --git a/dashboard/src/views/knowledge-base/components/SettingsTab.vue b/dashboard/src/views/knowledge-base/components/SettingsTab.vue index a3c52d8f0..7eba48d02 100644 --- a/dashboard/src/views/knowledge-base/components/SettingsTab.vue +++ b/dashboard/src/views/knowledge-base/components/SettingsTab.vue @@ -86,9 +86,7 @@ :label="t('settings.embeddingProvider')" variant="outlined" density="comfortable" - disabled - hint="嵌入模型创建后不可修改" - persistent-hint + @update:model-value="handleEmbeddingProviderChange" /> @@ -108,6 +106,10 @@ {{ t('settings.tips') }} + + + 注意: 修改嵌入模型会导致现有的向量数据失效,建议重新上传文档。不同的嵌入模型生成的向量不兼容,可能导致检索结果不准确。 + @@ -131,6 +133,39 @@ {{ snackbar.text }} + + + + + + mdi-alert + 确认修改嵌入模型 + + + + 警告: 修改嵌入模型将导致以下影响: + +
    +
  • 现有的向量数据将失效
  • +
  • 检索功能可能无法正常工作
  • +
  • 建议删除现有文档后重新上传
  • +
  • 不同嵌入模型生成的向量不兼容
  • +
+
+ 您确定要将嵌入模型从 {{ originalEmbeddingProvider }} 修改为 {{ pendingEmbeddingProvider }} 吗? +
+
+ + + + 取消 + + + 确认修改 + + +
+
@@ -152,6 +187,10 @@ const saving = ref(false) const formRef = ref() const embeddingProviders = ref([]) const rerankProviders = ref([]) +const originalEmbeddingProvider = ref('') +const showEmbeddingWarning = ref(false) +const embeddingChangeDialog = ref(false) +const pendingEmbeddingProvider = ref('') const snackbar = ref({ show: false, @@ -190,6 +229,8 @@ watch(() => props.kb, (kb) => { embedding_provider_id: kb.embedding_provider_id || '', rerank_provider_id: kb.rerank_provider_id || '' } + // 保存原始的embedding provider + originalEmbeddingProvider.value = kb.embedding_provider_id || '' } }, { immediate: true }) @@ -212,6 +253,33 @@ const loadProviders = async () => { } } +// 处理embedding provider变更 +const handleEmbeddingProviderChange = (newValue: string) => { + if (newValue && newValue !== originalEmbeddingProvider.value) { + // 显示警告并需要确认 + showEmbeddingWarning.value = true + pendingEmbeddingProvider.value = newValue + embeddingChangeDialog.value = true + } else { + showEmbeddingWarning.value = false + } +} + +// 确认修改embedding provider +const confirmEmbeddingChange = () => { + formData.value.embedding_provider_id = pendingEmbeddingProvider.value + embeddingChangeDialog.value = false + showEmbeddingWarning.value = true +} + +// 取消修改embedding provider +const cancelEmbeddingChange = () => { + formData.value.embedding_provider_id = originalEmbeddingProvider.value + embeddingChangeDialog.value = false + showEmbeddingWarning.value = false + pendingEmbeddingProvider.value = '' +} + // 保存设置 const saveSettings = async () => { const { valid } = await formRef.value.validate()