mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: edit file content support
This commit is contained in:
parent
630a78cead
commit
8013c152d0
@ -709,7 +709,7 @@ def save_docs_to_vector_db(
|
|||||||
}
|
}
|
||||||
for idx, text in enumerate(texts)
|
for idx, text in enumerate(texts)
|
||||||
]
|
]
|
||||||
|
|
||||||
VECTOR_DB_CLIENT.insert(
|
VECTOR_DB_CLIENT.insert(
|
||||||
collection_name=collection_name,
|
collection_name=collection_name,
|
||||||
items=items,
|
items=items,
|
||||||
|
@ -196,15 +196,56 @@ def add_file_to_knowledge_by_id(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/{id}/file/update", response_model=Optional[KnowledgeFilesResponse])
|
||||||
|
def update_file_from_knowledge_by_id(
|
||||||
|
id: str,
|
||||||
|
form_data: KnowledgeFileIdForm,
|
||||||
|
user=Depends(get_admin_user),
|
||||||
|
):
|
||||||
|
knowledge = Knowledges.get_knowledge_by_id(id=id)
|
||||||
|
file = Files.get_file_by_id(form_data.file_id)
|
||||||
|
if not file:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Remove content from the vector database
|
||||||
|
VECTOR_DB_CLIENT.delete(
|
||||||
|
collection_name=knowledge.id, filter={"file_id": form_data.file_id}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add content to the vector database
|
||||||
|
try:
|
||||||
|
process_file(ProcessFileForm(file_id=form_data.file_id, collection_name=id))
|
||||||
|
except Exception as e:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=str(e),
|
||||||
|
)
|
||||||
|
|
||||||
|
if knowledge:
|
||||||
|
data = knowledge.data or {}
|
||||||
|
file_ids = data.get("file_ids", [])
|
||||||
|
|
||||||
|
files = Files.get_files_by_ids(file_ids)
|
||||||
|
|
||||||
|
return KnowledgeFilesResponse(
|
||||||
|
**knowledge.model_dump(),
|
||||||
|
files=files,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail=ERROR_MESSAGES.NOT_FOUND,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# RemoveFileFromKnowledge
|
# RemoveFileFromKnowledge
|
||||||
############################
|
############################
|
||||||
|
|
||||||
|
|
||||||
class KnowledgeFileIdForm(BaseModel):
|
|
||||||
file_id: str
|
|
||||||
|
|
||||||
|
|
||||||
@router.post("/{id}/file/remove", response_model=Optional[KnowledgeFilesResponse])
|
@router.post("/{id}/file/remove", response_model=Optional[KnowledgeFilesResponse])
|
||||||
def remove_file_from_knowledge_by_id(
|
def remove_file_from_knowledge_by_id(
|
||||||
id: str,
|
id: str,
|
||||||
@ -224,6 +265,11 @@ def remove_file_from_knowledge_by_id(
|
|||||||
collection_name=knowledge.id, filter={"file_id": form_data.file_id}
|
collection_name=knowledge.id, filter={"file_id": form_data.file_id}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
result = VECTOR_DB_CLIENT.query(
|
||||||
|
collection_name=knowledge.id,
|
||||||
|
filter={"file_id": form_data.file_id},
|
||||||
|
)
|
||||||
|
|
||||||
Files.delete_file_by_id(form_data.file_id)
|
Files.delete_file_by_id(form_data.file_id)
|
||||||
|
|
||||||
if knowledge:
|
if knowledge:
|
||||||
|
@ -92,6 +92,40 @@ export const getFileById = async (token: string, id: string) => {
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateFileDataContentById = async (token: string, id: string, content: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/files/${id}/data/content/update`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
content: content
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const getFileContentById = async (id: string) => {
|
export const getFileContentById = async (id: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
@ -173,6 +173,41 @@ export const addFileToKnowledgeById = async (token: string, id: string, fileId:
|
|||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateFileFromKnowledgeById = async (token: string, id: string, fileId: string) => {
|
||||||
|
let error = null;
|
||||||
|
|
||||||
|
const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/${id}/file/update`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
authorization: `Bearer ${token}`
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
file_id: fileId
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then(async (res) => {
|
||||||
|
if (!res.ok) throw await res.json();
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((json) => {
|
||||||
|
return json;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
error = err.detail;
|
||||||
|
|
||||||
|
console.log(err);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
export const removeFileFromKnowledgeById = async (token: string, id: string, fileId: string) => {
|
export const removeFileFromKnowledgeById = async (token: string, id: string, fileId: string) => {
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
|
@ -8,11 +8,12 @@
|
|||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import { mobile, showSidebar } from '$lib/stores';
|
import { mobile, showSidebar } from '$lib/stores';
|
||||||
|
|
||||||
import { uploadFile } from '$lib/apis/files';
|
import { updateFileDataContentById, uploadFile } from '$lib/apis/files';
|
||||||
import {
|
import {
|
||||||
addFileToKnowledgeById,
|
addFileToKnowledgeById,
|
||||||
getKnowledgeById,
|
getKnowledgeById,
|
||||||
removeFileFromKnowledgeById,
|
removeFileFromKnowledgeById,
|
||||||
|
updateFileFromKnowledgeById,
|
||||||
updateKnowledgeById
|
updateKnowledgeById
|
||||||
} from '$lib/apis/knowledge';
|
} from '$lib/apis/knowledge';
|
||||||
|
|
||||||
@ -135,6 +136,28 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateFileContentHandler = async () => {
|
||||||
|
const fileId = selectedFile.id;
|
||||||
|
const content = selectedFile.data.content;
|
||||||
|
|
||||||
|
const res = updateFileDataContentById(localStorage.token, fileId, content).catch((e) => {
|
||||||
|
toast.error(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedKnowledge = await updateFileFromKnowledgeById(
|
||||||
|
localStorage.token,
|
||||||
|
id,
|
||||||
|
fileId
|
||||||
|
).catch((e) => {
|
||||||
|
toast.error(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (res && updatedKnowledge) {
|
||||||
|
knowledge = updatedKnowledge;
|
||||||
|
toast.success($i18n.t('File content updated successfully.'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const changeDebounceHandler = () => {
|
const changeDebounceHandler = () => {
|
||||||
console.log('debounce');
|
console.log('debounce');
|
||||||
if (debounceTimeout) {
|
if (debounceTimeout) {
|
||||||
@ -420,6 +443,9 @@
|
|||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="self-center w-fit text-sm py-1 px-2.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-lg"
|
class="self-center w-fit text-sm py-1 px-2.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-lg"
|
||||||
|
on:click={() => {
|
||||||
|
updateFileContentHandler();
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{$i18n.t('Save')}
|
{$i18n.t('Save')}
|
||||||
</button>
|
</button>
|
||||||
|
Loading…
Reference in New Issue
Block a user