diff --git a/web/src/components/DatabaseHeader.vue b/web/src/components/DatabaseHeader.vue index d6cd3285..99ba673d 100644 --- a/web/src/components/DatabaseHeader.vue +++ b/web/src/components/DatabaseHeader.vue @@ -75,7 +75,7 @@ import { ref, reactive, computed } from 'vue' import { useRouter } from 'vue-router' import { useDatabaseStore } from '@/stores/database' -import { getKbTypeLabel, getKbTypeIcon, getKbTypeColor } from '@/utils/kb_utils' +import { getKbTypeLabel, getKbTypeIcon, getKbTypeColor, parseModelSpec, buildDisplaySpec, buildLlmInfoPayload } from '@/utils/kb_utils' import { LeftOutlined, EditOutlined, DeleteOutlined } from '@ant-design/icons-vue' import HeaderComponent from '@/components/HeaderComponent.vue' import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue' @@ -94,6 +94,7 @@ const editForm = reactive({ name: '', description: '', llm_info: { + model_spec: '', provider: '', model_name: '' } @@ -113,6 +114,7 @@ const showEditModal = () => { // 如果是 LightRAG 类型,加载当前的 LLM 配置 if (database.value.kb_type === 'lightrag') { const llmInfo = database.value.llm_info || {} + editForm.llm_info.model_spec = llmInfo.model_spec || '' editForm.llm_info.provider = llmInfo.provider || '' editForm.llm_info.model_name = llmInfo.model_name || '' } @@ -130,10 +132,7 @@ const handleEditSubmit = () => { // 如果是 LightRAG 类型,包含 llm_info if (database.value.kb_type === 'lightrag') { - updateData.llm_info = { - provider: editForm.llm_info.provider, - model_name: editForm.llm_info.model_name - } + updateData.llm_info = buildLlmInfoPayload(editForm.llm_info) } await store.updateDatabaseInfo(updateData) @@ -145,25 +144,12 @@ const handleEditSubmit = () => { } // LLM 模型选择处理 -const llmModelSpec = computed(() => { - const provider = editForm.llm_info?.provider || '' - const modelName = editForm.llm_info?.model_name || '' - if (provider && modelName) { - return `${provider}/${modelName}` - } - return '' -}) +const llmModelSpec = computed(() => buildDisplaySpec(editForm.llm_info)) const handleLLMSelect = (spec) => { - console.log('LLM选择:', spec) - if (typeof spec !== 'string' || !spec) return - - const index = spec.indexOf('/') - const provider = index !== -1 ? spec.slice(0, index) : '' - const modelName = index !== -1 ? spec.slice(index + 1) : '' - - editForm.llm_info.provider = provider - editForm.llm_info.model_name = modelName + const parsed = parseModelSpec(spec) + if (!parsed) return + Object.assign(editForm.llm_info, parsed) } const deleteDatabase = () => { diff --git a/web/src/components/KnowledgeBaseCard.vue b/web/src/components/KnowledgeBaseCard.vue index 6ddb02bc..04ca9072 100644 --- a/web/src/components/KnowledgeBaseCard.vue +++ b/web/src/components/KnowledgeBaseCard.vue @@ -158,7 +158,7 @@ import { ref, reactive, computed, h, onMounted } from 'vue' import { useRouter } from 'vue-router' import { useDatabaseStore } from '@/stores/database' import { useUserStore } from '@/stores/user' -import { getKbTypeLabel, getKbTypeColor } from '@/utils/kb_utils' +import { getKbTypeLabel, getKbTypeColor, parseModelSpec, buildDisplaySpec, buildLlmInfoPayload } from '@/utils/kb_utils' import { CHUNK_PRESET_OPTIONS, CHUNK_PRESET_LABEL_MAP, @@ -264,6 +264,7 @@ const editForm = reactive({ auto_generate_questions: false, chunk_preset_id: 'general', llm_info: { + model_spec: '', provider: '', model_name: '' }, @@ -296,6 +297,7 @@ const showEditModal = () => { // 如果是 LightRAG 类型,加载当前的 LLM 配置 if (database.value.kb_type === 'lightrag') { const llmInfo = database.value.llm_info || {} + editForm.llm_info.model_spec = llmInfo.model_spec || '' editForm.llm_info.provider = llmInfo.provider || '' editForm.llm_info.model_name = llmInfo.model_name || '' } @@ -375,10 +377,7 @@ const handleEditSubmit = () => { // 如果是 LightRAG 类型,包含 llm_info if (database.value.kb_type === 'lightrag') { - updateData.llm_info = { - provider: editForm.llm_info.provider, - model_name: editForm.llm_info.model_name - } + updateData.llm_info = buildLlmInfoPayload(editForm.llm_info) } await store.updateDatabaseInfo(updateData) @@ -390,25 +389,12 @@ const handleEditSubmit = () => { } // LLM 模型选择处理 -const llmModelSpec = computed(() => { - const provider = editForm.llm_info?.provider || '' - const modelName = editForm.llm_info?.model_name || '' - if (provider && modelName) { - return `${provider}/${modelName}` - } - return '' -}) +const llmModelSpec = computed(() => buildDisplaySpec(editForm.llm_info)) const handleLLMSelect = (spec) => { - console.log('LLM选择:', spec) - if (typeof spec !== 'string' || !spec) return - - const index = spec.indexOf('/') - const provider = index !== -1 ? spec.slice(0, index) : '' - const modelName = index !== -1 ? spec.slice(index + 1) : '' - - editForm.llm_info.provider = provider - editForm.llm_info.model_name = modelName + const parsed = parseModelSpec(spec) + if (!parsed) return + Object.assign(editForm.llm_info, parsed) } const deleteDatabase = () => { diff --git a/web/src/utils/kb_utils.js b/web/src/utils/kb_utils.js index cefa3bd4..e210c524 100644 --- a/web/src/utils/kb_utils.js +++ b/web/src/utils/kb_utils.js @@ -26,3 +26,36 @@ export const getKbTypeColor = (type) => { } return colors[type] || 'blue' } + +// 解析模型 spec 为 { model_spec, provider, model_name } +// V2 格式: provider_id:model_id(冒号分隔) +// V1 格式: provider/model_name(斜杠分隔,model_name 可包含冒号) +export const parseModelSpec = (spec) => { + if (typeof spec !== 'string' || !spec) return null + const slashIndex = spec.indexOf('/') + const colonIndex = spec.indexOf(':') + const index = slashIndex !== -1 ? slashIndex : colonIndex + return { + model_spec: spec, + provider: index !== -1 ? spec.slice(0, index) : '', + model_name: index !== -1 ? spec.slice(index + 1) : '' + } +} + +// 从 llm_info 构造显示用的 spec 字符串 +export const buildDisplaySpec = (llmInfo) => { + if (llmInfo?.model_spec) return llmInfo.model_spec + const provider = llmInfo?.provider || '' + const modelName = llmInfo?.model_name || '' + return provider && modelName ? `${provider}/${modelName}` : '' +} + +// 构造提交给后端的 llm_info,避免旧数据写入空 model_spec +export const buildLlmInfoPayload = (llmInfo) => { + const payload = { + provider: llmInfo?.provider || '', + model_name: llmInfo?.model_name || '' + } + if (llmInfo?.model_spec) payload.model_spec = llmInfo.model_spec + return payload +} diff --git a/web/src/views/DataBaseView.vue b/web/src/views/DataBaseView.vue index ad1cf5cd..25660647 100644 --- a/web/src/views/DataBaseView.vue +++ b/web/src/views/DataBaseView.vue @@ -250,7 +250,7 @@ import ExtensionCardGrid from '@/components/extensions/ExtensionCardGrid.vue' import InfoCard from '@/components/shared/InfoCard.vue' import dayjs, { parseToShanghai } from '@/utils/time' import AiTextarea from '@/components/AiTextarea.vue' -import { getKbTypeLabel, getKbTypeIcon, getKbTypeColor } from '@/utils/kb_utils' +import { getKbTypeLabel, getKbTypeIcon, getKbTypeColor, parseModelSpec, buildDisplaySpec, buildLlmInfoPayload } from '@/utils/kb_utils' import { CHUNK_PRESET_OPTIONS, getChunkPresetDescription } from '@/utils/chunk_presets' const route = useRoute() @@ -324,6 +324,7 @@ const createEmptyDatabaseForm = () => ({ chunk_preset_id: 'general', language: 'Chinese', llm_info: { + model_spec: '', provider: '', model_name: '' }, @@ -338,14 +339,7 @@ const selectedPresetDescription = computed(() => getChunkPresetDescription(newDatabase.chunk_preset_id) ) -const llmModelSpec = computed(() => { - const provider = newDatabase.llm_info?.provider || '' - const modelName = newDatabase.llm_info?.model_name || '' - if (provider && modelName) { - return `${provider}/${modelName}` - } - return '' -}) +const llmModelSpec = computed(() => buildDisplaySpec(newDatabase.llm_info)) // 支持的知识库类型 const supportedKbTypes = ref({}) @@ -427,15 +421,9 @@ const handleKbTypeChange = (type) => { // 处理LLM选择 const handleLLMSelect = (spec) => { - console.log('LLM选择:', spec) - if (typeof spec !== 'string' || !spec) return - - const index = spec.indexOf('/') - const provider = index !== -1 ? spec.slice(0, index) : '' - const modelName = index !== -1 ? spec.slice(index + 1) : '' - - newDatabase.llm_info.provider = provider - newDatabase.llm_info.model_name = modelName + const parsed = parseModelSpec(spec) + if (!parsed) return + Object.assign(newDatabase.llm_info, parsed) } // 构建请求数据(只负责表单数据转换) @@ -470,11 +458,8 @@ const buildRequestData = () => { if (newDatabase.kb_type === 'lightrag') { requestData.additional_params.language = newDatabase.language || 'English' - if (newDatabase.llm_info.provider && newDatabase.llm_info.model_name) { - requestData.llm_info = { - provider: newDatabase.llm_info.provider, - model_name: newDatabase.llm_info.model_name - } + if (newDatabase.llm_info.model_spec || (newDatabase.llm_info.provider && newDatabase.llm_info.model_name)) { + requestData.llm_info = buildLlmInfoPayload(newDatabase.llm_info) } }