feat: 更新数据库信息接口,支持可选的 LLM 配置信息,并在前端表单中添加相应字段

This commit is contained in:
Wenjie Zhang 2025-11-04 00:35:49 +08:00
parent 022eea8fde
commit 194ef51299
6 changed files with 80 additions and 14 deletions

View File

@ -7,7 +7,6 @@
## Bugs
- [ ] LightRAG 知识库查看不了解析后的文本,偶然出现,未复现
## Next
@ -41,4 +40,5 @@
- [x] 优化 MCP 逻辑,支持 common + special 创建方式 <Badge type="info" text="0.3.5" />
- [x] 修复本地知识库的 metadata 和 向量数据库中不一致的情况。
- [x] v1 版本的 LangGraph 的工具渲染有问题
- [x] upload 接口会阻塞主进程
- [x] upload 接口会阻塞主进程
- [x] LightRAG 知识库查看不了解析后的文本,偶然出现,未复现

View File

@ -78,12 +78,16 @@ async def get_database_info(db_id: str, current_user: User = Depends(get_admin_u
@knowledge.put("/databases/{db_id}")
async def update_database_info(
db_id: str, name: str = Body(...), description: str = Body(...), current_user: User = Depends(get_admin_user)
db_id: str,
name: str = Body(...),
description: str = Body(...),
llm_info: dict = Body(None),
current_user: User = Depends(get_admin_user),
):
"""更新知识库信息"""
logger.debug(f"Update database {db_id} info: {name}, {description}")
logger.debug(f"Update database {db_id} info: {name}, {description}, llm_info: {llm_info}")
try:
database = await knowledge_base.update_database(db_id, name, description)
database = await knowledge_base.update_database(db_id, name, description, llm_info)
return {"message": "更新成功", "database": database}
except Exception as e:
logger.error(f"更新数据库失败 {e}, {traceback.format_exc()}")

View File

@ -482,7 +482,7 @@ class KnowledgeBase(ABC):
os.makedirs(general_uploads, exist_ok=True)
return general_uploads
def update_database(self, db_id: str, name: str, description: str) -> dict:
def update_database(self, db_id: str, name: str, description: str, llm_info: dict = None) -> dict:
"""
更新数据库
@ -490,6 +490,7 @@ class KnowledgeBase(ABC):
db_id: 数据库ID
name: 新名称
description: 新描述
llm_info: LLM配置信息可选仅用于 LightRAG 类型知识库
Returns:
更新后的数据库信息
@ -499,6 +500,11 @@ class KnowledgeBase(ABC):
self.databases_meta[db_id]["name"] = name
self.databases_meta[db_id]["description"] = description
# 如果提供了 llm_info则更新仅针对 LightRAG 类型)
if llm_info is not None:
self.databases_meta[db_id]["llm_info"] = llm_info
self._save_metadata()
return self.get_database_info(db_id)

View File

@ -332,8 +332,12 @@ class LightRagKB(KnowledgeBase):
if rag:
try:
# 获取文档的所有 chunks
assert hasattr(rag.text_chunks, "get_all"), "text_chunks does not have get_all method"
all_chunks = await rag.text_chunks.get_all() # type: ignore
# LightRAG v1.4+ 使用 JsonKVStorage通过 _data 属性访问所有数据
if hasattr(rag.text_chunks, "_data"):
all_chunks = dict(rag.text_chunks._data)
else:
logger.warning("text_chunks does not have _data attribute, cannot get file content")
return content_info
# 筛选属于该文档的 chunks
doc_chunks = []

View File

@ -366,10 +366,10 @@ class KnowledgeBaseManager:
return False
async def update_database(self, db_id: str, name: str, description: str) -> dict:
async def update_database(self, db_id: str, name: str, description: str, llm_info: dict = None) -> dict:
"""更新数据库"""
kb_instance = self._get_kb_for_database(db_id)
result = kb_instance.update_database(db_id, name, description)
result = kb_instance.update_database(db_id, name, description, llm_info)
async with self._metadata_lock:
if db_id in self.global_databases_meta:

View File

@ -38,7 +38,7 @@
<DeleteOutlined /> 删除数据库
</a-button>
<a-button key="back" @click="editModalVisible = false">取消</a-button>
<a-button key="submit" type="primary" :loading="loading" @click="handleEditSubmit">确定</a-button>
<a-button key="submit" type="primary" @click="handleEditSubmit">确定</a-button>
</template>
<a-form :model="editForm" :rules="rules" ref="editFormRef" layout="vertical">
<a-form-item label="知识库名称" name="name" required>
@ -47,6 +47,15 @@
<a-form-item label="知识库描述" name="description">
<a-textarea v-model:value="editForm.description" placeholder="请输入知识库描述" :rows="4" />
</a-form-item>
<!-- 仅对 LightRAG 类型显示 LLM 配置 -->
<a-form-item v-if="database.kb_type === 'lightrag'" label="语言模型 (LLM)" name="llm_info">
<ModelSelectorComponent
:model_spec="llmModelSpec"
placeholder="请选择模型"
@select-model="handleLLMSelect"
style="width: 100%;"
/>
</a-form-item>
</a-form>
</a-modal>
</template>
@ -62,6 +71,7 @@ import {
DeleteOutlined,
} from '@ant-design/icons-vue';
import HeaderComponent from '@/components/HeaderComponent.vue';
import ModelSelectorComponent from '@/components/ModelSelectorComponent.vue';
import { h } from 'vue';
const router = useRouter();
@ -74,7 +84,11 @@ const editModalVisible = ref(false);
const editFormRef = ref(null);
const editForm = reactive({
name: '',
description: ''
description: '',
llm_info: {
provider: '',
model_name: ''
}
});
const rules = {
@ -88,21 +102,59 @@ const backToDatabase = () => {
const showEditModal = () => {
editForm.name = database.value.name || '';
editForm.description = database.value.description || '';
// LightRAG LLM
if (database.value.kb_type === 'lightrag') {
const llmInfo = database.value.llm_info || {};
editForm.llm_info.provider = llmInfo.provider || '';
editForm.llm_info.model_name = llmInfo.model_name || '';
}
editModalVisible.value = true;
};
const handleEditSubmit = () => {
editFormRef.value.validate().then(async () => {
await store.updateDatabaseInfo({
const updateData = {
name: editForm.name,
description: editForm.description
});
};
// LightRAG llm_info
if (database.value.kb_type === 'lightrag') {
updateData.llm_info = {
provider: editForm.llm_info.provider,
model_name: editForm.llm_info.model_name
};
}
await store.updateDatabaseInfo(updateData);
editModalVisible.value = false;
}).catch(err => {
console.error('表单验证失败:', err);
});
};
// 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 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 deleteDatabase = () => {
store.deleteDatabase();
};