diff --git a/backend/open_webui/apps/webui/models/knowledge.py b/backend/open_webui/apps/webui/models/knowledge.py index 2ed7e1fe7..2d0e33f1b 100644 --- a/backend/open_webui/apps/webui/models/knowledge.py +++ b/backend/open_webui/apps/webui/models/knowledge.py @@ -85,6 +85,8 @@ class KnowledgeResponse(BaseModel): description: str data: Optional[dict] = None meta: Optional[dict] = None + + access_control: Optional[dict] = None created_at: int # timestamp in epoch updated_at: int # timestamp in epoch @@ -95,12 +97,7 @@ class KnowledgeForm(BaseModel): name: str description: str data: Optional[dict] = None - - -class KnowledgeUpdateForm(BaseModel): - name: Optional[str] = None - description: Optional[str] = None - data: Optional[dict] = None + access_control: Optional[dict] = None class KnowledgeTable: @@ -159,14 +156,32 @@ class KnowledgeTable: return None def update_knowledge_by_id( - self, id: str, form_data: KnowledgeUpdateForm, overwrite: bool = False + self, id: str, form_data: KnowledgeForm, overwrite: bool = False ) -> Optional[KnowledgeModel]: try: with get_db() as db: knowledge = self.get_knowledge_by_id(id=id) db.query(Knowledge).filter_by(id=id).update( { - **form_data.model_dump(exclude_none=True), + **form_data.model_dump(), + "updated_at": int(time.time()), + } + ) + db.commit() + return self.get_knowledge_by_id(id=id) + except Exception as e: + log.exception(e) + return None + + def update_knowledge_data_by_id( + self, id: str, data: dict + ) -> Optional[KnowledgeModel]: + try: + with get_db() as db: + knowledge = self.get_knowledge_by_id(id=id) + db.query(Knowledge).filter_by(id=id).update( + { + "data": data, "updated_at": int(time.time()), } ) diff --git a/backend/open_webui/apps/webui/models/tools.py b/backend/open_webui/apps/webui/models/tools.py index 1b7256df4..63570bee6 100644 --- a/backend/open_webui/apps/webui/models/tools.py +++ b/backend/open_webui/apps/webui/models/tools.py @@ -81,6 +81,7 @@ class ToolResponse(BaseModel): user_id: str name: str meta: ToolMeta + access_control: Optional[dict] = None updated_at: int # timestamp in epoch created_at: int # timestamp in epoch @@ -90,6 +91,7 @@ class ToolForm(BaseModel): name: str content: str meta: ToolMeta + access_control: Optional[dict] = None class ToolValves(BaseModel): diff --git a/backend/open_webui/apps/webui/routers/knowledge.py b/backend/open_webui/apps/webui/routers/knowledge.py index dfe233372..1ffadeac2 100644 --- a/backend/open_webui/apps/webui/routers/knowledge.py +++ b/backend/open_webui/apps/webui/routers/knowledge.py @@ -6,7 +6,6 @@ import logging from open_webui.apps.webui.models.knowledge import ( Knowledges, - KnowledgeUpdateForm, KnowledgeForm, KnowledgeResponse, ) @@ -64,8 +63,8 @@ async def get_knowledge(user=Depends(get_verified_user)): file_ids.remove(missing_file) data["file_ids"] = file_ids - Knowledges.update_knowledge_by_id( - id=knowledge_base.id, form_data=KnowledgeUpdateForm(data=data) + Knowledges.update_knowledge_data_by_id( + id=knowledge_base.id, data=data ) files = Files.get_file_metadatas_by_ids(file_ids) @@ -109,8 +108,8 @@ async def get_knowledge_list(user=Depends(get_verified_user)): file_ids.remove(missing_file) data["file_ids"] = file_ids - Knowledges.update_knowledge_by_id( - id=knowledge_base.id, form_data=KnowledgeUpdateForm(data=data) + Knowledges.update_knowledge_data_by_id( + id=knowledge_base.id, data=data ) files = Files.get_file_metadatas_by_ids(file_ids) @@ -186,7 +185,7 @@ async def get_knowledge_by_id(id: str, user=Depends(get_verified_user)): @router.post("/{id}/update", response_model=Optional[KnowledgeFilesResponse]) async def update_knowledge_by_id( id: str, - form_data: KnowledgeUpdateForm, + form_data: KnowledgeForm, user=Depends(get_verified_user), ): knowledge = Knowledges.get_knowledge_by_id(id=id) @@ -277,9 +276,7 @@ def add_file_to_knowledge_by_id( file_ids.append(form_data.file_id) data["file_ids"] = file_ids - knowledge = Knowledges.update_knowledge_by_id( - id=id, form_data=KnowledgeUpdateForm(data=data) - ) + knowledge = Knowledges.update_knowledge_data_by_id(id=id.id, data=data) if knowledge: files = Files.get_files_by_ids(file_ids) @@ -413,9 +410,7 @@ def remove_file_from_knowledge_by_id( file_ids.remove(form_data.file_id) data["file_ids"] = file_ids - knowledge = Knowledges.update_knowledge_by_id( - id=id, form_data=KnowledgeUpdateForm(data=data) - ) + knowledge = Knowledges.update_knowledge_data_by_id(id=id.id, data=data) if knowledge: files = Files.get_files_by_ids(file_ids) @@ -496,7 +491,6 @@ async def reset_knowledge_by_id(id: str, user=Depends(get_verified_user)): log.debug(e) pass - knowledge = Knowledges.update_knowledge_by_id( - id=id, form_data=KnowledgeUpdateForm(data={"file_ids": []}) - ) + knowledge = Knowledges.update_knowledge_data_by_id(id=id.id, data={"file_ids": []}) + return knowledge diff --git a/src/lib/apis/knowledge/index.ts b/src/lib/apis/knowledge/index.ts index c889e0594..da2b9d530 100644 --- a/src/lib/apis/knowledge/index.ts +++ b/src/lib/apis/knowledge/index.ts @@ -1,6 +1,6 @@ import { WEBUI_API_BASE_URL } from '$lib/constants'; -export const createNewKnowledge = async (token: string, name: string, description: string) => { +export const createNewKnowledge = async (token: string, name: string, description: string, accessControl: null|object) => { let error = null; const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/create`, { @@ -12,7 +12,8 @@ export const createNewKnowledge = async (token: string, name: string, descriptio }, body: JSON.stringify({ name: name, - description: description + description: description, + access_control: accessControl }) }) .then(async (res) => { @@ -130,6 +131,7 @@ type KnowledgeUpdateForm = { name?: string; description?: string; data?: object; + access_control?: null|object; }; export const updateKnowledgeById = async (token: string, id: string, form: KnowledgeUpdateForm) => { @@ -145,7 +147,8 @@ export const updateKnowledgeById = async (token: string, id: string, form: Knowl body: JSON.stringify({ name: form?.name ? form.name : undefined, description: form?.description ? form.description : undefined, - data: form?.data ? form.data : undefined + data: form?.data ? form.data : undefined, + access_control: form.access_control }) }) .then(async (res) => { diff --git a/src/lib/components/icons/LockClosed.svelte b/src/lib/components/icons/LockClosed.svelte new file mode 100644 index 000000000..c41171f4e --- /dev/null +++ b/src/lib/components/icons/LockClosed.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte b/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte index 29945cfb3..5d1e79808 100644 --- a/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte +++ b/src/lib/components/workspace/Knowledge/CreateKnowledgeBase.svelte @@ -12,6 +12,7 @@ let name = ''; let description = ''; + let accessControl = null; const submitHandler = async () => { loading = true; @@ -24,7 +25,12 @@ return; } - const res = await createNewKnowledge(localStorage.token, name, description).catch((e) => { + const res = await createNewKnowledge( + localStorage.token, + name, + description, + accessControl + ).catch((e) => { toast.error(e); }); @@ -105,7 +111,9 @@