From 092351d76d7d1bdc80478c88bcb3848b2b7ac145 Mon Sep 17 00:00:00 2001 From: silentoplayz Date: Sat, 20 Jun 2026 00:41:24 -0400 Subject: [PATCH] fix(knowledge): recover unlinked pending files and cap the pending poll --- backend/open_webui/routers/knowledge.py | 57 +++++++++++-------- .../workspace/Knowledge/KnowledgeBase.svelte | 10 +++- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/backend/open_webui/routers/knowledge.py b/backend/open_webui/routers/knowledge.py index 8a60f79495..d7b6767530 100644 --- a/backend/open_webui/routers/knowledge.py +++ b/backend/open_webui/routers/knowledge.py @@ -1495,24 +1495,39 @@ async def update_file_from_knowledge_by_id( detail=ERROR_MESSAGES.NOT_FOUND, ) - # Validate the file actually belongs to this knowledge base - if not await Knowledges.has_file(knowledge_id=id, file_id=form_data.file_id, db=db): - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=ERROR_MESSAGES.NOT_FOUND, - ) + is_linked = await Knowledges.has_file(knowledge_id=id, file_id=form_data.file_id, db=db) - # Remove content from the vector database - await ASYNC_VECTOR_DB_CLIENT.delete(collection_name=knowledge.id, filter={'file_id': form_data.file_id}) - - # Add content to the vector database try: - await process_file( - request, - ProcessFileForm(file_id=form_data.file_id, collection_name=id), - user=user, - db=db, - ) + if is_linked: + await ASYNC_VECTOR_DB_CLIENT.delete( + collection_name=knowledge.id, filter={'file_id': form_data.file_id} + ) + await process_file( + request, + ProcessFileForm(file_id=form_data.file_id, collection_name=id), + user=user, + db=db, + ) + else: + await process_file( + request, + ProcessFileForm(file_id=form_data.file_id), + user=user, + db=db, + ) + await process_file( + request, + ProcessFileForm(file_id=form_data.file_id, collection_name=id), + user=user, + db=db, + ) + await Knowledges.add_file_to_knowledge_by_id( + knowledge_id=id, + file_id=form_data.file_id, + user_id=user.id, + directory_id=form_data.directory_id, + db=db, + ) except Exception as e: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, @@ -1585,14 +1600,8 @@ async def remove_file_from_knowledge_by_id( detail=ERROR_MESSAGES.NOT_FOUND, ) - # Validate the file actually belongs to this knowledge base - if not await Knowledges.has_file(knowledge_id=id, file_id=form_data.file_id, db=db): - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=ERROR_MESSAGES.NOT_FOUND, - ) - - await Knowledges.remove_file_from_knowledge_by_id(knowledge_id=id, file_id=form_data.file_id, db=db) + if await Knowledges.has_file(knowledge_id=id, file_id=form_data.file_id, db=db): + await Knowledges.remove_file_from_knowledge_by_id(knowledge_id=id, file_id=form_data.file_id, db=db) # Remove content from the vector database try: diff --git a/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte b/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte index fb8a865fca..436ec8a5b9 100644 --- a/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte +++ b/src/lib/components/workspace/Knowledge/KnowledgeBase.svelte @@ -139,6 +139,7 @@ let deleteDirectoryContents = true; let pendingPollTimer: ReturnType | null = null; + let pendingPollCount = 0; let externalTestQuery = ''; let externalTestResult: { documents?: string[]; @@ -228,15 +229,20 @@ // Start polling for completion (if not already polling) if (!pendingPollTimer) { + pendingPollCount = 0; pendingPollTimer = setInterval(async () => { + pendingPollCount++; try { const still = await getPendingKnowledgeFiles(localStorage.token, knowledgeId); - if (!still || still.length === 0) { + if (!still || still.length === 0 || pendingPollCount >= 60) { clearInterval(pendingPollTimer); pendingPollTimer = null; init(); } - } catch {} + } catch { + clearInterval(pendingPollTimer); + pendingPollTimer = null; + } }, 5000); } }