mirror of
https://github.com/open-webui/open-webui
synced 2024-11-06 16:59:42 +00:00
refac
This commit is contained in:
parent
dff3732fcd
commit
5ffd216fca
@ -15,6 +15,9 @@ from fastapi import Depends, FastAPI, File, Form, HTTPException, UploadFile, sta
|
|||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
|
||||||
|
from open_webui.apps.webui.models.knowledge import Knowledges
|
||||||
|
|
||||||
from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
from open_webui.apps.retrieval.vector.connector import VECTOR_DB_CLIENT
|
||||||
|
|
||||||
# Document loaders
|
# Document loaders
|
||||||
@ -1277,6 +1280,7 @@ def delete_entries_from_collection(form_data: DeleteForm, user=Depends(get_admin
|
|||||||
@app.post("/reset/db")
|
@app.post("/reset/db")
|
||||||
def reset_vector_db(user=Depends(get_admin_user)):
|
def reset_vector_db(user=Depends(get_admin_user)):
|
||||||
VECTOR_DB_CLIENT.reset()
|
VECTOR_DB_CLIENT.reset()
|
||||||
|
Knowledges.delete_all_knowledge()
|
||||||
|
|
||||||
|
|
||||||
@app.post("/reset/uploads")
|
@app.post("/reset/uploads")
|
||||||
@ -1299,28 +1303,6 @@ def reset_upload_dir(user=Depends(get_admin_user)) -> bool:
|
|||||||
print(f"The directory {folder} does not exist")
|
print(f"The directory {folder} does not exist")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Failed to process the directory {folder}. Reason: {e}")
|
print(f"Failed to process the directory {folder}. Reason: {e}")
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@app.post("/reset")
|
|
||||||
def reset(user=Depends(get_admin_user)) -> bool:
|
|
||||||
folder = f"{UPLOAD_DIR}"
|
|
||||||
for filename in os.listdir(folder):
|
|
||||||
file_path = os.path.join(folder, filename)
|
|
||||||
try:
|
|
||||||
if os.path.isfile(file_path) or os.path.islink(file_path):
|
|
||||||
os.unlink(file_path)
|
|
||||||
elif os.path.isdir(file_path):
|
|
||||||
shutil.rmtree(file_path)
|
|
||||||
except Exception as e:
|
|
||||||
log.error("Failed to delete %s. Reason: %s" % (file_path, e))
|
|
||||||
|
|
||||||
try:
|
|
||||||
VECTOR_DB_CLIENT.reset()
|
|
||||||
except Exception as e:
|
|
||||||
log.exception(e)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -154,5 +154,15 @@ class KnowledgeTable:
|
|||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def delete_all_knowledge(self) -> bool:
|
||||||
|
with get_db() as db:
|
||||||
|
try:
|
||||||
|
db.query(Knowledge).delete()
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
return True
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
Knowledges = KnowledgeTable()
|
Knowledges = KnowledgeTable()
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
|
||||||
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
|
||||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
import Switch from '$lib/components/common/Switch.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -535,13 +536,13 @@
|
|||||||
<hr class=" dark:border-gray-850" />
|
<hr class=" dark:border-gray-850" />
|
||||||
|
|
||||||
<div class="">
|
<div class="">
|
||||||
<div class="text-sm font-medium">{$i18n.t('Content Extraction')}</div>
|
<div class="text-sm font-medium mb-1">{$i18n.t('Content Extraction')}</div>
|
||||||
|
|
||||||
<div class="flex w-full justify-between mt-2">
|
<div class="flex w-full justify-between">
|
||||||
<div class="self-center text-xs font-medium">{$i18n.t('Engine')}</div>
|
<div class="self-center text-xs font-medium">{$i18n.t('Engine')}</div>
|
||||||
<div class="flex items-center relative">
|
<div class="flex items-center relative">
|
||||||
<select
|
<select
|
||||||
class="dark:bg-gray-900 w-fit pr-8 rounded px-2 p-1 text-xs bg-transparent outline-none text-right"
|
class="dark:bg-gray-900 w-fit pr-8 rounded px-2 text-xs bg-transparent outline-none text-right"
|
||||||
bind:value={contentExtractionEngine}
|
bind:value={contentExtractionEngine}
|
||||||
on:change={(e) => {
|
on:change={(e) => {
|
||||||
showTikaServerUrl = e.target.value === 'tika';
|
showTikaServerUrl = e.target.value === 'tika';
|
||||||
@ -554,7 +555,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if showTikaServerUrl}
|
{#if showTikaServerUrl}
|
||||||
<div class="flex w-full mt-2">
|
<div class="flex w-full mt-1">
|
||||||
<div class="flex-1 mr-2">
|
<div class="flex-1 mr-2">
|
||||||
<input
|
<input
|
||||||
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
class="w-full rounded-lg py-2 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
@ -568,10 +569,126 @@
|
|||||||
|
|
||||||
<hr class=" dark:border-gray-850" />
|
<hr class=" dark:border-gray-850" />
|
||||||
|
|
||||||
<div class="">
|
<div class=" ">
|
||||||
<div class="text-sm font-medium">{$i18n.t('Files')}</div>
|
<div class=" text-sm font-medium mb-1">{$i18n.t('Query Params')}</div>
|
||||||
|
|
||||||
<div class=" my-2 flex gap-1.5">
|
<div class=" flex gap-1.5">
|
||||||
|
<div class="flex flex-col w-full gap-1">
|
||||||
|
<div class=" text-xs font-medium w-full">{$i18n.t('Top K')}</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<input
|
||||||
|
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
|
type="number"
|
||||||
|
placeholder={$i18n.t('Enter Top K')}
|
||||||
|
bind:value={querySettings.k}
|
||||||
|
autocomplete="off"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if querySettings.hybrid === true}
|
||||||
|
<div class=" flex flex-col w-full gap-1">
|
||||||
|
<div class="text-xs font-medium w-full">
|
||||||
|
{$i18n.t('Minimum Score')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<input
|
||||||
|
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
|
type="number"
|
||||||
|
step="0.01"
|
||||||
|
placeholder={$i18n.t('Enter Score')}
|
||||||
|
bind:value={querySettings.r}
|
||||||
|
autocomplete="off"
|
||||||
|
min="0.0"
|
||||||
|
title={$i18n.t('The score should be a value between 0.0 (0%) and 1.0 (100%).')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if querySettings.hybrid === true}
|
||||||
|
<div class="mt-2 text-xs text-gray-400 dark:text-gray-500">
|
||||||
|
{$i18n.t(
|
||||||
|
'Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.'
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class=" mb-1 text-xs font-medium">{$i18n.t('RAG Template')}</div>
|
||||||
|
<Tooltip
|
||||||
|
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||||
|
placement="top-start"
|
||||||
|
>
|
||||||
|
<textarea
|
||||||
|
bind:value={querySettings.template}
|
||||||
|
placeholder={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
||||||
|
class="w-full rounded-lg px-4 py-3 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
|
||||||
|
rows="4"
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class=" dark:border-gray-850" />
|
||||||
|
|
||||||
|
<div class=" ">
|
||||||
|
<div class="mb-1 text-sm font-medium">{$i18n.t('Chunk Params')}</div>
|
||||||
|
|
||||||
|
<div class=" flex gap-1.5">
|
||||||
|
<div class=" w-full justify-between">
|
||||||
|
<div class="self-center text-xs font-medium min-w-fit mb-1">{$i18n.t('Chunk Size')}</div>
|
||||||
|
<div class="self-center">
|
||||||
|
<input
|
||||||
|
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
|
type="number"
|
||||||
|
placeholder={$i18n.t('Enter Chunk Size')}
|
||||||
|
bind:value={chunkSize}
|
||||||
|
autocomplete="off"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<div class=" self-center text-xs font-medium min-w-fit mb-1">
|
||||||
|
{$i18n.t('Chunk Overlap')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="self-center">
|
||||||
|
<input
|
||||||
|
class="w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
||||||
|
type="number"
|
||||||
|
placeholder={$i18n.t('Enter Chunk Overlap')}
|
||||||
|
bind:value={chunkOverlap}
|
||||||
|
autocomplete="off"
|
||||||
|
min="0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="my-2">
|
||||||
|
<div class="flex justify-between items-center text-xs">
|
||||||
|
<div class=" text-xs font-medium">{$i18n.t('PDF Extract Images (OCR)')}</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Switch bind:state={pdfExtractImages} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr class=" dark:border-gray-850" />
|
||||||
|
|
||||||
|
<div class="">
|
||||||
|
<div class="text-sm font-medium mb-1">{$i18n.t('Files')}</div>
|
||||||
|
|
||||||
|
<div class=" flex gap-1.5">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<div class=" self-center text-xs font-medium min-w-fit mb-1">
|
<div class=" self-center text-xs font-medium min-w-fit mb-1">
|
||||||
{$i18n.t('Max Upload Size')}
|
{$i18n.t('Max Upload Size')}
|
||||||
@ -623,128 +740,6 @@
|
|||||||
|
|
||||||
<hr class=" dark:border-gray-850" />
|
<hr class=" dark:border-gray-850" />
|
||||||
|
|
||||||
<div class=" ">
|
|
||||||
<div class=" text-sm font-medium">{$i18n.t('Query Params')}</div>
|
|
||||||
|
|
||||||
<div class=" flex gap-1">
|
|
||||||
<div class=" flex w-full justify-between">
|
|
||||||
<div class="self-center text-xs font-medium min-w-fit">{$i18n.t('Top K')}</div>
|
|
||||||
|
|
||||||
<div class="self-center p-3">
|
|
||||||
<input
|
|
||||||
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
|
||||||
type="number"
|
|
||||||
placeholder={$i18n.t('Enter Top K')}
|
|
||||||
bind:value={querySettings.k}
|
|
||||||
autocomplete="off"
|
|
||||||
min="0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if querySettings.hybrid === true}
|
|
||||||
<div class=" flex w-full justify-between">
|
|
||||||
<div class=" self-center text-xs font-medium min-w-fit">
|
|
||||||
{$i18n.t('Minimum Score')}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="self-center p-3">
|
|
||||||
<input
|
|
||||||
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
|
||||||
type="number"
|
|
||||||
step="0.01"
|
|
||||||
placeholder={$i18n.t('Enter Score')}
|
|
||||||
bind:value={querySettings.r}
|
|
||||||
autocomplete="off"
|
|
||||||
min="0.0"
|
|
||||||
title={$i18n.t('The score should be a value between 0.0 (0%) and 1.0 (100%).')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if querySettings.hybrid === true}
|
|
||||||
<div class="mt-2 mb-1 text-xs text-gray-400 dark:text-gray-500">
|
|
||||||
{$i18n.t(
|
|
||||||
'Note: If you set a minimum score, the search will only return documents with a score greater than or equal to the minimum score.'
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class=" dark:border-gray-850 my-3" />
|
|
||||||
{/if}
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class=" mb-2.5 text-sm font-medium">{$i18n.t('RAG Template')}</div>
|
|
||||||
<Tooltip
|
|
||||||
content={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
|
||||||
placement="top-start"
|
|
||||||
>
|
|
||||||
<textarea
|
|
||||||
bind:value={querySettings.template}
|
|
||||||
placeholder={$i18n.t('Leave empty to use the default prompt, or enter a custom prompt')}
|
|
||||||
class="w-full rounded-lg px-4 py-3 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none resize-none"
|
|
||||||
rows="4"
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class=" dark:border-gray-850" />
|
|
||||||
|
|
||||||
<div class=" ">
|
|
||||||
<div class=" text-sm font-medium">{$i18n.t('Chunk Params')}</div>
|
|
||||||
|
|
||||||
<div class=" my-2 flex gap-1.5">
|
|
||||||
<div class=" w-full justify-between">
|
|
||||||
<div class="self-center text-xs font-medium min-w-fit mb-1">{$i18n.t('Chunk Size')}</div>
|
|
||||||
<div class="self-center">
|
|
||||||
<input
|
|
||||||
class=" w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
|
||||||
type="number"
|
|
||||||
placeholder={$i18n.t('Enter Chunk Size')}
|
|
||||||
bind:value={chunkSize}
|
|
||||||
autocomplete="off"
|
|
||||||
min="0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="w-full">
|
|
||||||
<div class=" self-center text-xs font-medium min-w-fit mb-1">
|
|
||||||
{$i18n.t('Chunk Overlap')}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="self-center">
|
|
||||||
<input
|
|
||||||
class="w-full rounded-lg py-1.5 px-4 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none"
|
|
||||||
type="number"
|
|
||||||
placeholder={$i18n.t('Enter Chunk Overlap')}
|
|
||||||
bind:value={chunkOverlap}
|
|
||||||
autocomplete="off"
|
|
||||||
min="0"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="my-3">
|
|
||||||
<div class="flex justify-between items-center text-xs">
|
|
||||||
<div class=" text-xs font-medium">{$i18n.t('PDF Extract Images (OCR)')}</div>
|
|
||||||
|
|
||||||
<button
|
|
||||||
class=" text-xs font-medium text-gray-500"
|
|
||||||
type="button"
|
|
||||||
on:click={() => {
|
|
||||||
pdfExtractImages = !pdfExtractImages;
|
|
||||||
}}>{pdfExtractImages ? $i18n.t('On') : $i18n.t('Off')}</button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr class=" dark:border-gray-850" />
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class=" flex rounded-xl py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
|
class=" flex rounded-xl py-2 px-3.5 w-full hover:bg-gray-200 dark:hover:bg-gray-800 transition"
|
||||||
@ -794,7 +789,9 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class=" self-center text-sm font-medium">{$i18n.t('Reset Vector Storage')}</div>
|
<div class=" self-center text-sm font-medium">
|
||||||
|
{$i18n.t('Reset Vector Storage/Knowledge')}
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user