open-webui/src/lib/components/admin/Settings/Documents.svelte

1532 lines
52 KiB
Svelte
Raw Normal View History

2024-02-18 05:06:08 +00:00
<script lang="ts">
2024-10-02 00:35:35 +00:00
import { toast } from 'svelte-sonner';
2024-08-27 15:05:24 +00:00
import { onMount, getContext, createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
2024-02-18 06:47:58 +00:00
import {
2024-03-03 02:56:57 +00:00
getQuerySettings,
2024-03-24 03:50:57 +00:00
updateQuerySettings,
resetVectorDB,
2024-04-14 22:31:40 +00:00
getEmbeddingConfig,
2024-04-22 20:49:58 +00:00
updateEmbeddingConfig,
getRerankingConfig,
2024-06-04 04:45:36 +00:00
updateRerankingConfig,
getRAGConfig,
updateRAGConfig
2024-09-27 23:36:35 +00:00
} from '$lib/apis/retrieval';
2024-10-02 00:35:35 +00:00
2025-04-12 23:33:36 +00:00
import { reindexKnowledgeFiles } from '$lib/apis/knowledge';
import { deleteAllFiles } from '$lib/apis/files';
2024-10-02 00:35:35 +00:00
2024-06-15 10:02:20 +00:00
import ResetUploadDirConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ReindexKnowledgeFilesConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
2024-08-27 15:05:24 +00:00
import Tooltip from '$lib/components/common/Tooltip.svelte';
2024-10-13 10:02:02 +00:00
import Switch from '$lib/components/common/Switch.svelte';
2024-10-20 06:17:47 +00:00
import Textarea from '$lib/components/common/Textarea.svelte';
2025-04-12 23:33:36 +00:00
import Spinner from '$lib/components/common/Spinner.svelte';
2024-02-18 05:06:08 +00:00
const i18n = getContext('i18n');
2024-04-10 07:33:45 +00:00
let updateEmbeddingModelLoading = false;
2024-04-22 20:49:58 +00:00
let updateRerankingModelLoading = false;
2024-02-18 05:14:42 +00:00
2024-03-24 03:50:57 +00:00
let showResetConfirm = false;
2024-06-04 04:45:36 +00:00
let showResetUploadDirConfirm = false;
let showReindexConfirm = false;
2024-03-24 03:50:57 +00:00
2024-04-14 21:55:00 +00:00
let embeddingEngine = '';
2024-04-14 22:31:40 +00:00
let embeddingModel = '';
let embeddingBatchSize = 1;
2024-04-22 20:49:58 +00:00
let rerankingModel = '';
2024-04-14 22:31:40 +00:00
let OpenAIUrl = '';
let OpenAIKey = '';
2025-05-20 02:58:04 +00:00
let AzureOpenAIUrl = '';
let AzureOpenAIKey = '';
let AzureOpenAIVersion = '';
2024-11-18 22:19:56 +00:00
let OllamaUrl = '';
let OllamaKey = '';
2024-04-14 23:48:15 +00:00
2024-03-03 02:56:57 +00:00
let querySettings = {
template: '',
r: 0.0,
2024-04-25 22:31:21 +00:00
k: 4,
2025-03-06 09:47:57 +00:00
k_reranker: 4,
2024-04-25 22:31:21 +00:00
hybrid: false
2024-03-03 02:56:57 +00:00
};
2024-02-18 06:47:58 +00:00
2025-04-12 23:33:36 +00:00
let RAGConfig = null;
const embeddingModelUpdateHandler = async () => {
2024-04-14 23:48:15 +00:00
if (embeddingEngine === '' && embeddingModel.split('/').length - 1 > 1) {
toast.error(
$i18n.t(
'Model filesystem path detected. Model shortname is required for update, cannot continue.'
)
);
return;
}
if (embeddingEngine === 'ollama' && embeddingModel === '') {
2024-04-14 22:31:40 +00:00
toast.error(
$i18n.t(
'Model filesystem path detected. Model shortname is required for update, cannot continue.'
)
);
return;
}
2024-04-14 23:48:15 +00:00
if (embeddingEngine === 'openai' && embeddingModel === '') {
2024-04-06 10:38:34 +00:00
toast.error(
$i18n.t(
'Model filesystem path detected. Model shortname is required for update, cannot continue.'
)
);
return;
}
if (
embeddingEngine === 'azure_openai' &&
(AzureOpenAIKey === '' || AzureOpenAIUrl === '' || AzureOpenAIVersion === '')
) {
toast.error($i18n.t('OpenAI URL/Key required.'));
return;
}
2024-04-14 23:48:15 +00:00
console.debug('Update embedding model attempt:', embeddingModel);
2024-04-10 07:33:45 +00:00
updateEmbeddingModelLoading = true;
const res = await updateEmbeddingConfig(localStorage.token, {
embedding_engine: embeddingEngine,
embedding_model: embeddingModel,
embedding_batch_size: embeddingBatchSize,
ollama_config: {
key: OllamaKey,
url: OllamaUrl
},
openai_config: {
key: OpenAIKey,
url: OpenAIUrl
},
azure_openai_config: {
key: AzureOpenAIKey,
url: AzureOpenAIUrl,
version: AzureOpenAIVersion
}
}).catch(async (error) => {
2025-01-21 06:41:32 +00:00
toast.error(`${error}`);
2024-04-14 23:48:15 +00:00
await setEmbeddingConfig();
2024-04-10 07:46:09 +00:00
return null;
});
2024-04-10 07:33:45 +00:00
updateEmbeddingModelLoading = false;
if (res) {
console.debug('embeddingModelUpdateHandler:', res);
if (res.status === true) {
2024-04-14 23:48:15 +00:00
toast.success($i18n.t('Embedding model set to "{{embedding_model}}"', res), {
2024-04-06 10:38:34 +00:00
duration: 1000 * 10
});
}
}
};
2024-02-18 06:29:52 +00:00
const submitHandler = async () => {
2025-05-14 18:28:40 +00:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'external' &&
RAGConfig.EXTERNAL_DOCUMENT_LOADER_URL === ''
) {
toast.error($i18n.t('External Document Loader URL required.'));
return;
}
2025-04-12 23:33:36 +00:00
if (RAGConfig.CONTENT_EXTRACTION_ENGINE === 'tika' && RAGConfig.TIKA_SERVER_URL === '') {
toast.error($i18n.t('Tika Server URL required.'));
return;
}
2025-04-12 23:33:36 +00:00
if (RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling' && RAGConfig.DOCLING_SERVER_URL === '') {
toast.error($i18n.t('Docling Server URL required.'));
return;
}
2025-05-03 19:48:12 +00:00
if (
2025-09-09 14:31:06 +00:00
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling' &&
RAGConfig.DOCLING_DO_OCR &&
((RAGConfig.DOCLING_OCR_ENGINE === '' && RAGConfig.DOCLING_OCR_LANG !== '') ||
2025-05-03 19:48:12 +00:00
(RAGConfig.DOCLING_OCR_ENGINE !== '' && RAGConfig.DOCLING_OCR_LANG === ''))
) {
toast.error(
$i18n.t('Both Docling OCR Engine and Language(s) must be provided or both left empty.')
);
return;
}
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling' &&
2025-09-09 14:31:06 +00:00
RAGConfig.DOCLING_DO_OCR === false &&
RAGConfig.DOCLING_FORCE_OCR === true
) {
2025-09-09 14:31:06 +00:00
toast.error($i18n.t('In order to force OCR, performing OCR must be enabled.'));
return;
}
2025-04-12 23:33:36 +00:00
2025-07-23 00:49:28 +00:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'datalab_marker' &&
RAGConfig.DATALAB_MARKER_ADDITIONAL_CONFIG &&
RAGConfig.DATALAB_MARKER_ADDITIONAL_CONFIG.trim() !== ''
) {
try {
JSON.parse(RAGConfig.DATALAB_MARKER_ADDITIONAL_CONFIG);
} catch (e) {
toast.error($i18n.t('Invalid JSON format in Additional Config'));
return;
}
}
if (
2025-04-12 23:33:36 +00:00
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'document_intelligence' &&
RAGConfig.DOCUMENT_INTELLIGENCE_ENDPOINT === ''
) {
toast.error($i18n.t('Document Intelligence endpoint required.'));
return;
}
2025-04-12 23:33:36 +00:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'mistral_ocr' &&
RAGConfig.MISTRAL_OCR_API_KEY === ''
) {
toast.error($i18n.t('Mistral OCR API Key required.'));
return;
}
2025-02-26 23:42:19 +00:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'mineru' &&
RAGConfig.MINERU_API_MODE === 'cloud' &&
RAGConfig.MINERU_API_KEY === ''
) {
toast.error($i18n.t('MinerU API Key required for Cloud API mode.'));
return;
}
2025-04-12 23:33:36 +00:00
if (!RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL) {
2025-02-26 23:42:19 +00:00
await embeddingModelUpdateHandler();
}
2025-06-08 16:02:14 +00:00
const res = await updateRAGConfig(localStorage.token, {
...RAGConfig,
ALLOWED_FILE_EXTENSIONS: RAGConfig.ALLOWED_FILE_EXTENSIONS.split(',')
.map((ext) => ext.trim())
.filter((ext) => ext !== ''),
DOCLING_PICTURE_DESCRIPTION_LOCAL: JSON.parse(
RAGConfig.DOCLING_PICTURE_DESCRIPTION_LOCAL || '{}'
),
DOCLING_PICTURE_DESCRIPTION_API: JSON.parse(RAGConfig.DOCLING_PICTURE_DESCRIPTION_API || '{}')
});
2024-08-27 15:05:24 +00:00
dispatch('save');
2024-02-18 06:29:52 +00:00
};
2024-04-14 23:48:15 +00:00
const setEmbeddingConfig = async () => {
const embeddingConfig = await getEmbeddingConfig(localStorage.token);
if (embeddingConfig) {
embeddingEngine = embeddingConfig.embedding_engine;
embeddingModel = embeddingConfig.embedding_model;
embeddingBatchSize = embeddingConfig.embedding_batch_size ?? 1;
2024-04-14 23:48:15 +00:00
OpenAIKey = embeddingConfig.openai_config.key;
OpenAIUrl = embeddingConfig.openai_config.url;
2024-11-18 22:19:56 +00:00
OllamaKey = embeddingConfig.ollama_config.key;
OllamaUrl = embeddingConfig.ollama_config.url;
2025-05-20 02:58:04 +00:00
AzureOpenAIKey = embeddingConfig.azure_openai_config.key;
AzureOpenAIUrl = embeddingConfig.azure_openai_config.url;
AzureOpenAIVersion = embeddingConfig.azure_openai_config.version;
}
};
2024-02-18 06:29:52 +00:00
onMount(async () => {
2024-04-14 23:48:15 +00:00
await setEmbeddingConfig();
2025-05-16 17:05:52 +00:00
const config = await getRAGConfig(localStorage.token);
2025-05-18 20:13:03 +00:00
config.ALLOWED_FILE_EXTENSIONS = (config?.ALLOWED_FILE_EXTENSIONS ?? []).join(', ');
2025-06-08 16:02:14 +00:00
config.DOCLING_PICTURE_DESCRIPTION_LOCAL = JSON.stringify(
config.DOCLING_PICTURE_DESCRIPTION_LOCAL ?? {},
null,
2
);
config.DOCLING_PICTURE_DESCRIPTION_API = JSON.stringify(
config.DOCLING_PICTURE_DESCRIPTION_API ?? {},
null,
2
);
2025-05-16 17:05:52 +00:00
RAGConfig = config;
2024-02-18 06:29:52 +00:00
});
2024-02-18 05:06:08 +00:00
</script>
2024-06-15 10:02:20 +00:00
<ResetUploadDirConfirmDialog
bind:show={showResetUploadDirConfirm}
2024-06-18 22:20:04 +00:00
on:confirm={async () => {
const res = await deleteAllFiles(localStorage.token).catch((error) => {
2025-01-21 06:41:32 +00:00
toast.error(`${error}`);
2024-06-15 10:02:20 +00:00
return null;
});
if (res) {
toast.success($i18n.t('Success'));
}
}}
/>
<ResetVectorDBConfirmDialog
bind:show={showResetConfirm}
on:confirm={() => {
const res = resetVectorDB(localStorage.token).catch((error) => {
2025-01-21 06:41:32 +00:00
toast.error(`${error}`);
2024-06-15 10:02:20 +00:00
return null;
});
if (res) {
toast.success($i18n.t('Success'));
}
}}
/>
<ReindexKnowledgeFilesConfirmDialog
bind:show={showReindexConfirm}
on:confirm={async () => {
const res = await reindexKnowledgeFiles(localStorage.token).catch((error) => {
toast.error(`${error}`);
return null;
});
if (res) {
toast.success($i18n.t('Success'));
}
}}
/>
2024-02-18 05:06:08 +00:00
<form
class="flex flex-col h-full justify-between space-y-3 text-sm"
on:submit|preventDefault={() => {
2024-02-18 06:29:52 +00:00
submitHandler();
2024-02-18 05:06:08 +00:00
}}
>
2025-04-12 23:33:36 +00:00
{#if RAGConfig}
<div class=" space-y-2.5 overflow-y-scroll scrollbar-hidden h-full pr-1.5">
<div class="">
2025-02-26 23:42:19 +00:00
<div class="mb-3">
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 text-base font-medium">{$i18n.t('General')}</div>
2025-02-26 21:59:08 +00:00
2025-02-26 23:42:19 +00:00
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
2025-02-26 21:59:08 +00:00
2025-04-12 23:33:36 +00:00
<div class="mb-2.5 flex flex-col w-full justify-between">
<div class="flex w-full justify-between mb-1">
2025-04-12 23:33:36 +00:00
<div class="self-center text-xs font-medium">
{$i18n.t('Content Extraction Engine')}
2025-02-26 23:42:19 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class="">
2025-02-26 23:42:19 +00:00
<select
2025-04-12 23:33:36 +00:00
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.CONTENT_EXTRACTION_ENGINE}
2025-02-26 23:42:19 +00:00
>
2025-04-12 23:33:36 +00:00
<option value="">{$i18n.t('Default')}</option>
2025-05-14 18:28:40 +00:00
<option value="external">{$i18n.t('External')}</option>
2025-04-12 23:33:36 +00:00
<option value="tika">{$i18n.t('Tika')}</option>
<option value="docling">{$i18n.t('Docling')}</option>
2025-05-28 22:33:40 +00:00
<option value="datalab_marker">{$i18n.t('Datalab Marker API')}</option>
2025-04-12 23:33:36 +00:00
<option value="document_intelligence">{$i18n.t('Document Intelligence')}</option>
<option value="mistral_ocr">{$i18n.t('Mistral OCR')}</option>
<option value="mineru">{$i18n.t('MinerU')}</option>
2025-02-26 23:42:19 +00:00
</select>
</div>
2025-02-26 21:48:56 +00:00
</div>
2025-02-26 23:42:19 +00:00
2025-04-12 23:33:36 +00:00
{#if RAGConfig.CONTENT_EXTRACTION_ENGINE === ''}
<div class="flex w-full mt-1">
<div class="flex-1 flex justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('PDF Extract Images (OCR)')}
</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.PDF_EXTRACT_IMAGES} />
</div>
</div>
</div>
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'datalab_marker'}
2025-05-28 22:33:40 +00:00
<div class="my-0.5 flex gap-2 pr-2">
2025-07-23 00:49:28 +00:00
<Tooltip
content={$i18n.t(
'API Base URL for Datalab Marker service. Defaults to: https://www.datalab.to/api/v1/marker'
)}
placement="top-start"
className="w-full"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('Enter Datalab Marker API Base URL')}
bind:value={RAGConfig.DATALAB_MARKER_API_BASE_URL}
/>
</Tooltip>
2025-07-23 03:52:05 +00:00
</div>
<div class="my-0.5 flex gap-2 pr-2">
2025-05-28 22:33:40 +00:00
<SensitiveInput
placeholder={$i18n.t('Enter Datalab Marker API Key')}
required={false}
bind:value={RAGConfig.DATALAB_MARKER_API_KEY}
/>
</div>
2025-05-28 22:33:40 +00:00
2025-07-23 00:49:28 +00:00
<div class="flex flex-col gap-2 mt-2">
<div class=" flex flex-col w-full justify-between">
<div class=" mb-1 text-xs font-medium">
{$i18n.t('Additional Config')}
</div>
<div class="flex w-full items-center relative">
<Tooltip
content={$i18n.t(
'Additional configuration options for marker. This should be a JSON string with key-value pairs. For example, \'{"key": "value"}\'. Supported keys include: disable_links, keep_pageheader_in_output, keep_pagefooter_in_output, filter_blank_pages, drop_repeated_text, layout_coverage_threshold, merge_threshold, height_tolerance, gap_threshold, image_threshold, min_line_length, level_count, default_level'
)}
placement="top-start"
className="w-full"
>
<Textarea
bind:value={RAGConfig.DATALAB_MARKER_ADDITIONAL_CONFIG}
placeholder={$i18n.t('Enter JSON config (e.g., {"disable_links": true})')}
/>
</Tooltip>
</div>
2025-05-28 22:33:40 +00:00
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
2025-07-23 00:49:28 +00:00
'Significantly improves accuracy by using an LLM to enhance tables, forms, inline math, and layout detection. Will increase latency. Defaults to False.'
2025-05-28 22:33:40 +00:00
)}
placement="top-start"
>
{$i18n.t('Use LLM')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_USE_LLM} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t('Skip the cache and re-run the inference. Defaults to False.')}
placement="top-start"
>
{$i18n.t('Skip Cache')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_SKIP_CACHE} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Force OCR on all pages of the PDF. This can lead to worse results if you have good text in your PDFs. Defaults to False.'
)}
placement="top-start"
>
{$i18n.t('Force OCR')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_FORCE_OCR} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Whether to paginate the output. Each page will be separated by a horizontal rule and page number. Defaults to False.'
)}
placement="top-start"
>
{$i18n.t('Paginate')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_PAGINATE} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Strip existing OCR text from the PDF and re-run OCR. Ignored if Force OCR is enabled. Defaults to False.'
)}
placement="top-start"
>
{$i18n.t('Strip Existing OCR')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_STRIP_EXISTING_OCR} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Disable image extraction from the PDF. If Use LLM is enabled, images will be automatically captioned. Defaults to False.'
)}
placement="top-start"
>
{$i18n.t('Disable Image Extraction')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_DISABLE_IMAGE_EXTRACTION} />
</div>
2025-07-23 01:06:29 +00:00
</div>
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Format the lines in the output. Defaults to False. If set to True, the lines will be formatted to detect inline math and styles.'
)}
placement="top-start"
>
{$i18n.t('Format Lines')}
</Tooltip>
</div>
<div class="flex items-center">
<Switch bind:state={RAGConfig.DATALAB_MARKER_FORMAT_LINES} />
</div>
</div>
2025-05-28 22:33:40 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
"The output format for the text. Can be 'json', 'markdown', or 'html'. Defaults to 'markdown'."
)}
placement="top-start"
>
{$i18n.t('Output Format')}
</Tooltip>
</div>
<div class="">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.DATALAB_MARKER_OUTPUT_FORMAT}
>
<option value="markdown">{$i18n.t('Markdown')}</option>
<option value="json">{$i18n.t('JSON')}</option>
<option value="html">{$i18n.t('HTML')}</option>
</select>
</div>
</div>
2025-05-14 18:28:40 +00:00
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'external'}
<div class="my-0.5 flex gap-2 pr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('Enter External Document Loader URL')}
bind:value={RAGConfig.EXTERNAL_DOCUMENT_LOADER_URL}
/>
<SensitiveInput
placeholder={$i18n.t('Enter External Document Loader API Key')}
required={false}
bind:value={RAGConfig.EXTERNAL_DOCUMENT_LOADER_API_KEY}
/>
</div>
2025-04-12 23:33:36 +00:00
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'tika'}
<div class="flex w-full mt-1">
<div class="flex-1 mr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Tika Server URL')}
bind:value={RAGConfig.TIKA_SERVER_URL}
/>
</div>
</div>
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling'}
<div class="flex w-full mt-1">
2025-02-26 23:42:19 +00:00
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Docling Server URL')}
bind:value={RAGConfig.DOCLING_SERVER_URL}
2025-02-26 23:42:19 +00:00
/>
2025-09-09 14:31:06 +00:00
</div>
<div class="flex w-full mt-2">
<div class="flex-1 flex justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Perform OCR')}
</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.DOCLING_DO_OCR} />
</div>
</div>
</div>
{#if RAGConfig.DOCLING_DO_OCR}
2025-09-09 14:31:06 +00:00
<div class="flex w-full mt-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('Enter Docling OCR Engine')}
bind:value={RAGConfig.DOCLING_OCR_ENGINE}
/>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('Enter Docling OCR Language(s)')}
bind:value={RAGConfig.DOCLING_OCR_LANG}
/>
</div>
{/if}
<div class="flex w-full mt-2">
<div class="flex-1 flex justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Force OCR')}
</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.DOCLING_FORCE_OCR} />
</div>
</div>
</div>
2025-09-09 14:31:06 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip content={''} placement="top-start">
{$i18n.t('PDF Backend')}
</Tooltip>
</div>
<div class="">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.DOCLING_PDF_BACKEND}
>
<option value="pypdfium2">{$i18n.t('pypdfium2')}</option>
<option value="dlparse_v1">{$i18n.t('dlparse_v1')}</option>
<option value="dlparse_v2">{$i18n.t('dlparse_v2')}</option>
<option value="dlparse_v4">{$i18n.t('dlparse_v4')}</option>
</select>
</div>
</div>
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip content={''} placement="top-start">
{$i18n.t('Table Mode')}
</Tooltip>
</div>
<div class="">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.DOCLING_TABLE_MODE}
>
<option value="fast">{$i18n.t('fast')}</option>
<option value="accurate">{$i18n.t('accurate')}</option>
</select>
</div>
</div>
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip content={''} placement="top-start">
{$i18n.t('Pipeline')}
</Tooltip>
</div>
<div class="">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.DOCLING_PIPELINE}
>
<option value="standard">{$i18n.t('standard')}</option>
<option value="vlm">{$i18n.t('vlm')}</option>
</select>
</div>
</div>
<div class="flex w-full mt-2">
<div class="flex-1 flex justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Describe Pictures in Documents')}
</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.DOCLING_DO_PICTURE_DESCRIPTION} />
</div>
</div>
</div>
{#if RAGConfig.DOCLING_DO_PICTURE_DESCRIPTION}
2025-06-08 16:02:14 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip content={''} placement="top-start">
{$i18n.t('Picture Description Mode')}
</Tooltip>
</div>
<div class="">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.DOCLING_PICTURE_DESCRIPTION_MODE}
>
<option value="">{$i18n.t('Default')}</option>
<option value="local">{$i18n.t('Local')}</option>
<option value="api">{$i18n.t('API')}</option>
</select>
</div>
</div>
{#if RAGConfig.DOCLING_PICTURE_DESCRIPTION_MODE === 'local'}
2025-06-08 16:02:14 +00:00
<div class="flex flex-col gap-2 mt-2">
<div class=" flex flex-col w-full justify-between">
<div class=" mb-1 text-xs font-medium">
{$i18n.t('Picture Description Local Config')}
</div>
2025-06-08 16:02:14 +00:00
<div class="flex w-full items-center relative">
<Tooltip
2025-06-08 16:02:14 +00:00
content={$i18n.t(
'Options for running a local vision-language model in the picture description. The parameters refer to a model hosted on Hugging Face. This parameter is mutually exclusive with picture_description_api.'
)}
placement="top-start"
2025-06-08 16:02:14 +00:00
className="w-full"
>
2025-06-08 16:02:14 +00:00
<Textarea
bind:value={RAGConfig.DOCLING_PICTURE_DESCRIPTION_LOCAL}
2025-06-08 16:05:26 +00:00
placeholder={$i18n.t('Enter Config in JSON format')}
2025-06-08 16:02:14 +00:00
/>
</Tooltip>
</div>
</div>
</div>
{:else if RAGConfig.DOCLING_PICTURE_DESCRIPTION_MODE === 'api'}
2025-06-08 16:02:14 +00:00
<div class="flex flex-col gap-2 mt-2">
<div class=" flex flex-col w-full justify-between">
<div class=" mb-1 text-xs font-medium">
{$i18n.t('Picture Description API Config')}
</div>
2025-06-08 16:02:14 +00:00
<div class="flex w-full items-center relative">
<Tooltip
2025-06-08 16:02:14 +00:00
content={$i18n.t(
'API details for using a vision-language model in the picture description. This parameter is mutually exclusive with picture_description_local.'
)}
placement="top-start"
2025-06-08 16:02:14 +00:00
className="w-full"
>
2025-06-08 16:02:14 +00:00
<Textarea
bind:value={RAGConfig.DOCLING_PICTURE_DESCRIPTION_API}
2025-06-08 16:05:26 +00:00
placeholder={$i18n.t('Enter Config in JSON format')}
2025-06-08 16:02:14 +00:00
/>
</Tooltip>
</div>
</div>
</div>
{/if}
{/if}
0.6.33 (#18118) * feat: improve ollama model management experience This commit introduces several improvements to the Ollama model management modal: - Adds a cancel button to the model pulling operation, using the existing 'x' button pattern. - Adds a cancel button to the "Update All" models operation, allowing the user to cancel the update for the currently processing model. - Cleans up toast notifications when updating all models. A single toast is now shown at the beginning and a summary toast at the end, preventing notification spam. - Refactors the `ManageOllama.svelte` component to support these new cancellation features. - Adds tooltips to all buttons in the modal to improve clarity. - Disables buttons when their corresponding input fields are empty to prevent accidental clicks. * fix * i18n: improve Chinese translation * fix: handle non‑UTF8 chars in third‑party responses without error * German translation of new strings in i18n * log web search queries only with level 'debug' instead of 'info' * Tool calls now only include text and dont inlcude other content like image b64 * fix onedrive * fix: discovery url * fix: default permissions not being loaded * fix: ai hallucination * fix: non rich text input copy * refac: rm print statements * refac: disable direct models from model editors * refac/fix: do not process xlsx files with azure doc intelligence * Update pull_request_template.md * Update generated image translation in DE-de * added missing danish translations * feat(onedrive): Enable search and "My Organization" pivot * style(onedrive): Formatting fix * feat: Implement toggling for vertical and horizontal flow layouts This commit introduces the necessary logic and UI controls to allow users to switch the Flow component layout between vertical and horizontal orientations. * **`Flow.svelte` Refactoring:** * Updates logic for calculating level offsets and node positions to consistently respect the current flow orientation. * Adds a control panel using `<Controls>` and `<SwitchButton>` components. * Provides user interface elements to easily switch the flow layout between horizontal and vertical orientations. * build(deps): bump pydantic from 2.11.7 to 2.11.9 in /backend Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.7 to 2.11.9. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/v2.11.9/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.11.7...v2.11.9) --- updated-dependencies: - dependency-name: pydantic dependency-version: 2.11.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump black from 25.1.0 to 25.9.0 in /backend Bumps [black](https://github.com/psf/black) from 25.1.0 to 25.9.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/25.1.0...25.9.0) --- updated-dependencies: - dependency-name: black dependency-version: 25.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump markdown from 3.8.2 to 3.9 in /backend Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.8.2 to 3.9. - [Release notes](https://github.com/Python-Markdown/markdown/releases) - [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md) - [Commits](https://github.com/Python-Markdown/markdown/compare/3.8.2...3.9.0) --- updated-dependencies: - dependency-name: markdown dependency-version: '3.9' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump chromadb from 1.0.20 to 1.1.0 in /backend Bumps [chromadb](https://github.com/chroma-core/chroma) from 1.0.20 to 1.1.0. - [Release notes](https://github.com/chroma-core/chroma/releases) - [Changelog](https://github.com/chroma-core/chroma/blob/main/RELEASE_PROCESS.md) - [Commits](https://github.com/chroma-core/chroma/compare/1.0.20...1.1.0) --- updated-dependencies: - dependency-name: chromadb dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump opentelemetry-api from 1.36.0 to 1.37.0 Bumps [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python) from 1.36.0 to 1.37.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-python/compare/v1.36.0...v1.37.0) --- updated-dependencies: - dependency-name: opentelemetry-api dependency-version: 1.37.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * refac: ollama embed form data * fix: non rich text handling * fix: oauth client registration * refac * chore: dep bump * chore: fastapi bump * chore/refac: bump bcrypt and remove passlib * Improving Korean Translation * refac * Improving Korean Translation * feat: PWA share_target implementation Co-Authored-By: gjveld <19951982+gjveld@users.noreply.github.com> * refac: message input mobile detection behaviour * feat: model_ids per folder * Update translation.json (pt-BR) inclusion of new translations of items that have been added * refac * refac * refac * refac * refac/fix: temp chat * refac * refac: stop task * refac/fix: azure audio escape * refac: external tool validation * refac/enh: start.sh additional args support * refac * refac: styling * refac/fix: direct connection floating action buttons * refac/fix: system prompt duplication * refac/enh: openai tts additional params support * refac * feat: load data in parallel to accelerate page loading speed * i18n: improve Chinese translation * refac * refac: model selector * UPD: i18n es-ES Translation v0.6.33 UPD: i18n es-ES Translation v0.6.33 Updated new strings. * refac * improved query pref by querying only relevant columns * refac/enh: docling params * refac * refac: openai additional headers support * refac * FEAT: Add Vega Char Visualizer Renderer ### FEAT: Add Vega Char Visualizer Renderer Feature required in https://github.com/open-webui/open-webui/discussions/18022 Added npm vega lib to package.json Added function for visualization renderer to src/libs/utils/index.ts Added logic to src/lib/components/chat/Messages/CodeBlock.svelte The treatment is similar as for mermaid diagrams. Reference: https://vega.github.io/vega/ * refac * chore * refac * FEAT: Add Vega-Lite Char Visualizer Renderer ### FEAT: Add Vega Char Visualizer Renderer Add suport for Vega-Lite Specifications. Vega-Lite is a "compiled" version of Vega Char Visualizer. For be rendered with Vega it have to be compiled. This PR add the check and compile if necessary, is a complement of recent Vega Renderer Feature added. * refac * refac/fix: switch * enh/refac: url input handling * refac * refac: styling * UPD: Add Validators & Error Toast for Mermaid & Vega diagrams ### UPD: Feat: Add Validators & Error Toast for Mermaid & Vega diagrams Description: As many time the diagrams generated or entered have syntax errors the diagrams are not rendered due to that errors, but as there isn't any notification is difficult to know what happend. This PR add validator and toast notification when error on Mermaid and Vega/Vega-Lite diagrams, helping the user to fix its. * removed redundant knowledge API call * Fix Code Format * refac: model workspace view * refac * refac: knowledge * refac: prompts * refac: tools * refac * feat: attach folder * refac: make tencentcloud-sdk-python optional * refac/fix: oauth * enh: ENABLE_OAUTH_EMAIL_FALLBACK * refac/fix: folders * Update requirements.txt * Update pyproject.toml * UPD: Add Validators & Error Toast for Mermaid & Vega diagrams ### UPD: Feat: Add Validators & Error Toast for Mermaid & Vega diagrams Description: As many time the diagrams generated or entered have syntax errors the diagrams are not rendered due to that errors, but as there isn't any notification is difficult to know what happend. This PR add validator and toast notification when error on Mermaid and Vega/Vega-Lite diagrams, helping the user to fix its. Note: Another possibility of integrating this Graph Visualizer is through its svelte component: https://github.com/vega/svelte-vega/tree/main/packages/svelte-vega * Removed unused toast import & Code Format * refac * refac: external tool server view * refac * refac: overview * refac: styling * refac * Update bug_report.yaml * refac * refac * refac * refac * refac: oauth client fallback * Fixed: Cannot handle batch sizes > 1 if no padding token is defined Fixes Cannot handle batch sizes > 1 if no padding token is defined For reranker models that do not have this defined in their config by using the eos_token_id if present as pad_token_id. * refac: fallback to reasoning content * fix(i18n): corrected typo in Spanish translation for "Reasoning Tags" Typo fixed in Spanish translation file at line 1240 of `open-webui/src/lib/i18n/locales/es-ES/translation.json`: - Incorrect: "Eriquetas de Razonamiento" - Correct: "Etiquetas de Razonamiento" This improves clarity and consistency in the UI. * refac/fix: ENABLE_STAR_SESSIONS_MIDDLEWARE * refac/fix: redirect * refac * refac * refac * refac: web search error handling * refac: source parsing * refac: functions * refac * refac/enh: note pdf export * refac/fix: mcp oauth2.1 * chore: format * chore: Changelog (#17995) * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * refac * chore: dep bump --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: silentoplayz <jacwoo21@outlook.com> Co-authored-by: Shirasawa <764798966@qq.com> Co-authored-by: Jan Kessler <jakessle@uni-mainz.de> Co-authored-by: Jacob Leksan <jacob.leksan@expedient.com> Co-authored-by: Classic298 <27028174+Classic298@users.noreply.github.com> Co-authored-by: sinejespersen <sinejespersen@protonmail.com> Co-authored-by: Selene Blok <selene.blok@rws.nl> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cyp <cypher9715@naver.com> Co-authored-by: gjveld <19951982+gjveld@users.noreply.github.com> Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> Co-authored-by: _00_ <131402327+rgaricano@users.noreply.github.com> Co-authored-by: expruc <eygabi01@gmail.com> Co-authored-by: YetheSamartaka <55753928+YetheSamartaka@users.noreply.github.com> Co-authored-by: Akutangulo <akutangulo@gmail.com>
2025-10-07 21:20:27 +00:00
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip content={''} placement="top-start">
{$i18n.t('Parameters')}
</Tooltip>
</div>
<div class="">
<Textarea
2025-10-20 04:27:50 +00:00
bind:value={RAGConfig.DOCLING_PARAMS}
0.6.33 (#18118) * feat: improve ollama model management experience This commit introduces several improvements to the Ollama model management modal: - Adds a cancel button to the model pulling operation, using the existing 'x' button pattern. - Adds a cancel button to the "Update All" models operation, allowing the user to cancel the update for the currently processing model. - Cleans up toast notifications when updating all models. A single toast is now shown at the beginning and a summary toast at the end, preventing notification spam. - Refactors the `ManageOllama.svelte` component to support these new cancellation features. - Adds tooltips to all buttons in the modal to improve clarity. - Disables buttons when their corresponding input fields are empty to prevent accidental clicks. * fix * i18n: improve Chinese translation * fix: handle non‑UTF8 chars in third‑party responses without error * German translation of new strings in i18n * log web search queries only with level 'debug' instead of 'info' * Tool calls now only include text and dont inlcude other content like image b64 * fix onedrive * fix: discovery url * fix: default permissions not being loaded * fix: ai hallucination * fix: non rich text input copy * refac: rm print statements * refac: disable direct models from model editors * refac/fix: do not process xlsx files with azure doc intelligence * Update pull_request_template.md * Update generated image translation in DE-de * added missing danish translations * feat(onedrive): Enable search and "My Organization" pivot * style(onedrive): Formatting fix * feat: Implement toggling for vertical and horizontal flow layouts This commit introduces the necessary logic and UI controls to allow users to switch the Flow component layout between vertical and horizontal orientations. * **`Flow.svelte` Refactoring:** * Updates logic for calculating level offsets and node positions to consistently respect the current flow orientation. * Adds a control panel using `<Controls>` and `<SwitchButton>` components. * Provides user interface elements to easily switch the flow layout between horizontal and vertical orientations. * build(deps): bump pydantic from 2.11.7 to 2.11.9 in /backend Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.11.7 to 2.11.9. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/v2.11.9/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v2.11.7...v2.11.9) --- updated-dependencies: - dependency-name: pydantic dependency-version: 2.11.9 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump black from 25.1.0 to 25.9.0 in /backend Bumps [black](https://github.com/psf/black) from 25.1.0 to 25.9.0. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/25.1.0...25.9.0) --- updated-dependencies: - dependency-name: black dependency-version: 25.9.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump markdown from 3.8.2 to 3.9 in /backend Bumps [markdown](https://github.com/Python-Markdown/markdown) from 3.8.2 to 3.9. - [Release notes](https://github.com/Python-Markdown/markdown/releases) - [Changelog](https://github.com/Python-Markdown/markdown/blob/master/docs/changelog.md) - [Commits](https://github.com/Python-Markdown/markdown/compare/3.8.2...3.9.0) --- updated-dependencies: - dependency-name: markdown dependency-version: '3.9' dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump chromadb from 1.0.20 to 1.1.0 in /backend Bumps [chromadb](https://github.com/chroma-core/chroma) from 1.0.20 to 1.1.0. - [Release notes](https://github.com/chroma-core/chroma/releases) - [Changelog](https://github.com/chroma-core/chroma/blob/main/RELEASE_PROCESS.md) - [Commits](https://github.com/chroma-core/chroma/compare/1.0.20...1.1.0) --- updated-dependencies: - dependency-name: chromadb dependency-version: 1.1.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * build(deps): bump opentelemetry-api from 1.36.0 to 1.37.0 Bumps [opentelemetry-api](https://github.com/open-telemetry/opentelemetry-python) from 1.36.0 to 1.37.0. - [Release notes](https://github.com/open-telemetry/opentelemetry-python/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/open-telemetry/opentelemetry-python/compare/v1.36.0...v1.37.0) --- updated-dependencies: - dependency-name: opentelemetry-api dependency-version: 1.37.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * refac: ollama embed form data * fix: non rich text handling * fix: oauth client registration * refac * chore: dep bump * chore: fastapi bump * chore/refac: bump bcrypt and remove passlib * Improving Korean Translation * refac * Improving Korean Translation * feat: PWA share_target implementation Co-Authored-By: gjveld <19951982+gjveld@users.noreply.github.com> * refac: message input mobile detection behaviour * feat: model_ids per folder * Update translation.json (pt-BR) inclusion of new translations of items that have been added * refac * refac * refac * refac * refac/fix: temp chat * refac * refac: stop task * refac/fix: azure audio escape * refac: external tool validation * refac/enh: start.sh additional args support * refac * refac: styling * refac/fix: direct connection floating action buttons * refac/fix: system prompt duplication * refac/enh: openai tts additional params support * refac * feat: load data in parallel to accelerate page loading speed * i18n: improve Chinese translation * refac * refac: model selector * UPD: i18n es-ES Translation v0.6.33 UPD: i18n es-ES Translation v0.6.33 Updated new strings. * refac * improved query pref by querying only relevant columns * refac/enh: docling params * refac * refac: openai additional headers support * refac * FEAT: Add Vega Char Visualizer Renderer ### FEAT: Add Vega Char Visualizer Renderer Feature required in https://github.com/open-webui/open-webui/discussions/18022 Added npm vega lib to package.json Added function for visualization renderer to src/libs/utils/index.ts Added logic to src/lib/components/chat/Messages/CodeBlock.svelte The treatment is similar as for mermaid diagrams. Reference: https://vega.github.io/vega/ * refac * chore * refac * FEAT: Add Vega-Lite Char Visualizer Renderer ### FEAT: Add Vega Char Visualizer Renderer Add suport for Vega-Lite Specifications. Vega-Lite is a "compiled" version of Vega Char Visualizer. For be rendered with Vega it have to be compiled. This PR add the check and compile if necessary, is a complement of recent Vega Renderer Feature added. * refac * refac/fix: switch * enh/refac: url input handling * refac * refac: styling * UPD: Add Validators & Error Toast for Mermaid & Vega diagrams ### UPD: Feat: Add Validators & Error Toast for Mermaid & Vega diagrams Description: As many time the diagrams generated or entered have syntax errors the diagrams are not rendered due to that errors, but as there isn't any notification is difficult to know what happend. This PR add validator and toast notification when error on Mermaid and Vega/Vega-Lite diagrams, helping the user to fix its. * removed redundant knowledge API call * Fix Code Format * refac: model workspace view * refac * refac: knowledge * refac: prompts * refac: tools * refac * feat: attach folder * refac: make tencentcloud-sdk-python optional * refac/fix: oauth * enh: ENABLE_OAUTH_EMAIL_FALLBACK * refac/fix: folders * Update requirements.txt * Update pyproject.toml * UPD: Add Validators & Error Toast for Mermaid & Vega diagrams ### UPD: Feat: Add Validators & Error Toast for Mermaid & Vega diagrams Description: As many time the diagrams generated or entered have syntax errors the diagrams are not rendered due to that errors, but as there isn't any notification is difficult to know what happend. This PR add validator and toast notification when error on Mermaid and Vega/Vega-Lite diagrams, helping the user to fix its. Note: Another possibility of integrating this Graph Visualizer is through its svelte component: https://github.com/vega/svelte-vega/tree/main/packages/svelte-vega * Removed unused toast import & Code Format * refac * refac: external tool server view * refac * refac: overview * refac: styling * refac * Update bug_report.yaml * refac * refac * refac * refac * refac: oauth client fallback * Fixed: Cannot handle batch sizes > 1 if no padding token is defined Fixes Cannot handle batch sizes > 1 if no padding token is defined For reranker models that do not have this defined in their config by using the eos_token_id if present as pad_token_id. * refac: fallback to reasoning content * fix(i18n): corrected typo in Spanish translation for "Reasoning Tags" Typo fixed in Spanish translation file at line 1240 of `open-webui/src/lib/i18n/locales/es-ES/translation.json`: - Incorrect: "Eriquetas de Razonamiento" - Correct: "Etiquetas de Razonamiento" This improves clarity and consistency in the UI. * refac/fix: ENABLE_STAR_SESSIONS_MIDDLEWARE * refac/fix: redirect * refac * refac * refac * refac: web search error handling * refac: source parsing * refac: functions * refac * refac/enh: note pdf export * refac/fix: mcp oauth2.1 * chore: format * chore: Changelog (#17995) * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * Update CHANGELOG.md * refac * chore: dep bump --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: silentoplayz <jacwoo21@outlook.com> Co-authored-by: Shirasawa <764798966@qq.com> Co-authored-by: Jan Kessler <jakessle@uni-mainz.de> Co-authored-by: Jacob Leksan <jacob.leksan@expedient.com> Co-authored-by: Classic298 <27028174+Classic298@users.noreply.github.com> Co-authored-by: sinejespersen <sinejespersen@protonmail.com> Co-authored-by: Selene Blok <selene.blok@rws.nl> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Cyp <cypher9715@naver.com> Co-authored-by: gjveld <19951982+gjveld@users.noreply.github.com> Co-authored-by: joaoback <156559121+joaoback@users.noreply.github.com> Co-authored-by: _00_ <131402327+rgaricano@users.noreply.github.com> Co-authored-by: expruc <eygabi01@gmail.com> Co-authored-by: YetheSamartaka <55753928+YetheSamartaka@users.noreply.github.com> Co-authored-by: Akutangulo <akutangulo@gmail.com>
2025-10-07 21:20:27 +00:00
placeholder={$i18n.t('Enter additional parameters in JSON format')}
minSize={100}
/>
</div>
</div>
2025-04-12 23:33:36 +00:00
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'document_intelligence'}
2025-02-26 23:42:19 +00:00
<div class="my-0.5 flex gap-2 pr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Document Intelligence Endpoint')}
bind:value={RAGConfig.DOCUMENT_INTELLIGENCE_ENDPOINT}
2025-02-26 23:42:19 +00:00
/>
<SensitiveInput
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Document Intelligence Key')}
bind:value={RAGConfig.DOCUMENT_INTELLIGENCE_KEY}
required={false}
2025-02-26 23:42:19 +00:00
/>
</div>
2025-04-12 23:33:36 +00:00
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'mistral_ocr'}
<div class="my-0.5 flex gap-2 pr-2">
<SensitiveInput
placeholder={$i18n.t('Enter Mistral API Key')}
bind:value={RAGConfig.MISTRAL_OCR_API_KEY}
2025-02-26 23:42:19 +00:00
/>
2025-02-26 21:48:56 +00:00
</div>
2025-10-16 16:36:26 +00:00
{:else if RAGConfig.CONTENT_EXTRACTION_ENGINE === 'mineru'}
<!-- API Mode Selection -->
<div class="flex w-full mt-2">
<div class="flex-1 flex justify-between">
<div class="self-center text-xs font-medium">
{$i18n.t('API Mode')}
</div>
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden"
bind:value={RAGConfig.MINERU_API_MODE}
on:change={() => {
// Auto-update URL when switching modes if it's empty or matches the opposite mode's default
const cloudUrl = 'https://mineru.net/api/v4';
const localUrl = 'http://localhost:8000';
if (RAGConfig.MINERU_API_MODE === 'cloud') {
if (!RAGConfig.MINERU_API_URL || RAGConfig.MINERU_API_URL === localUrl) {
RAGConfig.MINERU_API_URL = cloudUrl;
}
} else {
if (!RAGConfig.MINERU_API_URL || RAGConfig.MINERU_API_URL === cloudUrl) {
RAGConfig.MINERU_API_URL = localUrl;
}
}
2025-10-16 16:36:26 +00:00
}}
>
2025-10-20 03:41:25 +00:00
<option value="local">{$i18n.t('local')}</option>
<option value="cloud">{$i18n.t('cloud')}</option>
2025-10-16 16:36:26 +00:00
</select>
</div>
</div>
2025-10-16 16:36:26 +00:00
<!-- API URL -->
<div class="flex w-full mt-2">
2025-10-16 16:36:26 +00:00
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={RAGConfig.MINERU_API_MODE === 'cloud'
? $i18n.t('https://mineru.net/api/v4')
: $i18n.t('http://localhost:8000')}
bind:value={RAGConfig.MINERU_API_URL}
/>
</div>
2025-10-20 03:41:25 +00:00
<div class="flex w-full mt-2">
<SensitiveInput
placeholder={$i18n.t('Enter MinerU API Key')}
bind:value={RAGConfig.MINERU_API_KEY}
/>
</div>
2025-10-16 16:36:26 +00:00
<!-- Parameters -->
<div class="flex justify-between w-full mt-2">
<div class="self-center text-xs font-medium">
<Tooltip
content={$i18n.t(
'Advanced parameters for MinerU parsing (enable_ocr, enable_formula, enable_table, language, model_version, page_ranges)'
)}
placement="top-start"
>
{$i18n.t('Parameters')}
</Tooltip>
</div>
<div class="">
<Textarea
value={typeof RAGConfig.MINERU_PARAMS === 'object' &&
RAGConfig.MINERU_PARAMS !== null &&
Object.keys(RAGConfig.MINERU_PARAMS).length > 0
? JSON.stringify(RAGConfig.MINERU_PARAMS, null, 2)
: ''}
on:input={(e) => {
try {
const value = e.target.value.trim();
RAGConfig.MINERU_PARAMS = value ? JSON.parse(value) : {};
} catch (err) {
// Keep the string value if JSON is invalid (user is still typing)
RAGConfig.MINERU_PARAMS = e.target.value;
}
}}
placeholder={`{\n "enable_ocr": false,\n "enable_formula": true,\n "enable_table": true,\n "language": "en",\n "model_version": "pipeline",\n "page_ranges": ""\n}`}
minSize={100}
/>
</div>
</div>
2025-10-16 16:36:26 +00:00
{/if}
2025-04-12 23:33:36 +00:00
</div>
2025-02-26 23:42:19 +00:00
<div class=" mb-2.5 flex w-full justify-between">
2025-04-12 23:33:36 +00:00
<div class=" self-center text-xs font-medium">
<Tooltip content={$i18n.t('Full Context Mode')} placement="top-start">
{$i18n.t('Bypass Embedding and Retrieval')}
</Tooltip>
</div>
2025-02-26 23:42:19 +00:00
<div class="flex items-center relative">
<Tooltip
2025-04-12 23:33:36 +00:00
content={RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL
2025-03-07 11:59:09 +00:00
? $i18n.t(
'Inject the entire content as context for comprehensive processing, this is recommended for complex queries.'
)
: $i18n.t(
'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'
)}
2025-02-26 23:42:19 +00:00
>
2025-04-12 23:33:36 +00:00
<Switch bind:state={RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL} />
2025-02-26 23:42:19 +00:00
</Tooltip>
</div>
</div>
2024-05-06 21:36:36 +00:00
2025-04-12 23:33:36 +00:00
{#if !RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL}
<div class=" mb-2.5 flex w-full justify-between">
2025-04-12 23:33:36 +00:00
<div class=" self-center text-xs font-medium">{$i18n.t('Text Splitter')}</div>
<div class="flex items-center relative">
2025-04-12 23:33:36 +00:00
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.TEXT_SPLITTER}
>
<option value="">{$i18n.t('Default')} ({$i18n.t('Character')})</option>
<option value="token">{$i18n.t('Token')} ({$i18n.t('Tiktoken')})</option>
<option value="markdown_header">{$i18n.t('Markdown (Header)')}</option>
2025-04-12 23:33:36 +00:00
</select>
</div>
2025-02-26 23:42:19 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" flex gap-1.5 w-full">
<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-hidden"
type="number"
placeholder={$i18n.t('Enter Chunk Size')}
bind:value={RAGConfig.CHUNK_SIZE}
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>
2025-04-12 23:33:36 +00:00
<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-hidden"
type="number"
placeholder={$i18n.t('Enter Chunk Overlap')}
bind:value={RAGConfig.CHUNK_OVERLAP}
autocomplete="off"
min="0"
/>
</div>
</div>
</div>
</div>
{/if}
</div>
{#if !RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL}
<div class="mb-3">
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Embedding')}</div>
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
<div class=" mb-2.5 flex flex-col w-full justify-between">
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Embedding Model Engine')}
</div>
<div class="flex items-center relative">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
bind:value={embeddingEngine}
2025-08-14 00:15:16 +00:00
placeholder={$i18n.t('Select an embedding model engine')}
2025-04-12 23:33:36 +00:00
on:change={(e) => {
if (e.target.value === 'ollama') {
embeddingModel = '';
} else if (e.target.value === 'openai') {
embeddingModel = 'text-embedding-3-small';
} else if (e.target.value === 'azure_openai') {
embeddingModel = 'text-embedding-3-small';
} else if (e.target.value === '') {
embeddingModel = 'sentence-transformers/all-MiniLM-L6-v2';
}
2025-04-12 23:33:36 +00:00
}}
>
<option value="">{$i18n.t('Default (SentenceTransformers)')}</option>
<option value="ollama">{$i18n.t('Ollama')}</option>
<option value="openai">{$i18n.t('OpenAI')}</option>
2025-08-19 18:39:17 +00:00
<option value="azure_openai">{$i18n.t('Azure OpenAI')}</option>
2025-04-12 23:33:36 +00:00
</select>
</div>
</div>
{#if embeddingEngine === 'openai'}
2025-04-12 23:33:36 +00:00
<div class="my-0.5 flex gap-2 pr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('API Base URL')}
bind:value={OpenAIUrl}
required
/>
<SensitiveInput
placeholder={$i18n.t('API Key')}
bind:value={OpenAIKey}
required={false}
/>
2025-04-12 23:33:36 +00:00
</div>
{:else if embeddingEngine === 'ollama'}
2025-04-12 23:33:36 +00:00
<div class="my-0.5 flex gap-2 pr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('API Base URL')}
bind:value={OllamaUrl}
required
/>
<SensitiveInput
placeholder={$i18n.t('API Key')}
bind:value={OllamaKey}
required={false}
/>
</div>
{:else if embeddingEngine === 'azure_openai'}
<div class="my-0.5 flex flex-col gap-2 pr-2 w-full">
<div class="flex gap-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
placeholder={$i18n.t('API Base URL')}
bind:value={AzureOpenAIUrl}
required
/>
<SensitiveInput placeholder={$i18n.t('API Key')} bind:value={AzureOpenAIKey} />
</div>
<div class="flex gap-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-08-14 00:15:16 +00:00
placeholder={$i18n.t('Version')}
bind:value={AzureOpenAIVersion}
required
/>
</div>
</div>
{/if}
2025-04-12 23:33:36 +00:00
</div>
<div class=" mb-2.5 flex flex-col w-full">
<div class=" mb-1 text-xs font-medium">{$i18n.t('Embedding Model')}</div>
<div class="">
{#if embeddingEngine === 'ollama'}
<div class="flex w-full">
<div class="flex-1 mr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
bind:value={embeddingModel}
placeholder={$i18n.t('Set embedding model')}
required
/>
</div>
</div>
{:else}
<div class="flex w-full">
<div class="flex-1 mr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Set embedding model (e.g. {{model}})', {
model: embeddingModel.slice(-40)
})}
2025-04-12 23:33:36 +00:00
bind:value={embeddingModel}
/>
</div>
2025-04-12 23:33:36 +00:00
{#if embeddingEngine === ''}
<button
class="px-2.5 bg-transparent text-gray-800 dark:bg-transparent dark:text-gray-100 rounded-lg transition"
on:click={() => {
embeddingModelUpdateHandler();
}}
disabled={updateEmbeddingModelLoading}
>
{#if updateEmbeddingModelLoading}
<div class="self-center">
2025-06-25 22:44:45 +00:00
<Spinner />
2025-04-12 23:33:36 +00:00
</div>
{:else}
<svg
xmlns="http://www.w3.org/2000/svg"
2025-04-12 23:33:36 +00:00
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
>
<path
2025-04-12 23:33:36 +00:00
d="M8.75 2.75a.75.75 0 0 0-1.5 0v5.69L5.03 6.22a.75.75 0 0 0-1.06 1.06l3.5 3.5a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0-1.06-1.06L8.75 8.44V2.75Z"
/>
<path
2025-04-12 23:33:36 +00:00
d="M3.5 9.75a.75.75 0 0 0-1.5 0v1.5A2.75 2.75 0 0 0 4.75 14h6.5A2.75 2.75 0 0 0 14 11.25v-1.5a.75.75 0 0 0-1.5 0v1.5c0 .69-.56 1.25-1.25 1.25h-6.5c-.69 0-1.25-.56-1.25-1.25v-1.5Z"
/>
</svg>
2025-04-12 23:33:36 +00:00
{/if}
</button>
{/if}
</div>
2025-04-12 23:33:36 +00:00
{/if}
</div>
<div class="mt-1 mb-1 text-xs text-gray-400 dark:text-gray-500">
{$i18n.t(
2025-10-14 23:36:43 +00:00
'After updating or changing the embedding model, you must reindex the knowledge base for the changes to take effect. You can do this using the "Reindex" button below.'
2025-04-12 23:33:36 +00:00
)}
</div>
</div>
{#if embeddingEngine === 'ollama' || embeddingEngine === 'openai' || embeddingEngine === 'azure_openai'}
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Embedding Batch Size')}
</div>
<div class="">
<input
bind:value={embeddingBatchSize}
type="number"
class=" bg-transparent text-center w-14 outline-none"
min="-2"
max="16000"
step="1"
/>
2025-02-26 23:42:19 +00:00
</div>
2025-02-26 21:48:56 +00:00
</div>
{/if}
2025-04-12 23:33:36 +00:00
</div>
<div class="mb-3">
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Retrieval')}</div>
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
2025-02-26 21:48:56 +00:00
2025-03-28 20:17:43 +00:00
<div class=" mb-2.5 flex w-full justify-between">
2025-04-12 23:33:36 +00:00
<div class=" self-center text-xs font-medium">{$i18n.t('Full Context Mode')}</div>
2025-03-06 09:47:57 +00:00
<div class="flex items-center relative">
2025-04-12 23:33:36 +00:00
<Tooltip
content={RAGConfig.RAG_FULL_CONTEXT
? $i18n.t(
'Inject the entire content as context for comprehensive processing, this is recommended for complex queries.'
)
: $i18n.t(
'Default to segmented retrieval for focused and relevant content extraction, this is recommended for most cases.'
)}
>
<Switch bind:state={RAGConfig.RAG_FULL_CONTEXT} />
</Tooltip>
2025-03-06 09:47:57 +00:00
</div>
</div>
2025-04-12 23:33:36 +00:00
{#if !RAGConfig.RAG_FULL_CONTEXT}
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Hybrid Search')}</div>
<div class="flex items-center relative">
2025-06-08 16:02:14 +00:00
<Switch bind:state={RAGConfig.ENABLE_RAG_HYBRID_SEARCH} />
2025-04-12 23:33:36 +00:00
</div>
</div>
{#if RAGConfig.ENABLE_RAG_HYBRID_SEARCH === true}
2025-05-10 14:33:52 +00:00
<div class=" mb-2.5 flex flex-col w-full justify-between">
<div class="flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Reranking Engine')}
</div>
<div class="flex items-center relative">
<select
class="dark:bg-gray-900 w-fit pr-8 rounded-sm px-2 p-1 text-xs bg-transparent outline-hidden text-right"
bind:value={RAGConfig.RAG_RERANKING_ENGINE}
2025-08-14 00:15:16 +00:00
placeholder={$i18n.t('Select a reranking model engine')}
2025-05-10 14:38:30 +00:00
on:change={(e) => {
if (e.target.value === 'external') {
RAGConfig.RAG_RERANKING_MODEL = '';
} else if (e.target.value === '') {
RAGConfig.RAG_RERANKING_MODEL = 'BAAI/bge-reranker-v2-m3';
}
}}
2025-05-10 14:33:52 +00:00
>
<option value="">{$i18n.t('Default (SentenceTransformers)')}</option>
<option value="external">{$i18n.t('External')}</option>
</select>
</div>
</div>
{#if RAGConfig.RAG_RERANKING_ENGINE === 'external'}
<div class="my-0.5 flex gap-2 pr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-05-10 14:33:52 +00:00
placeholder={$i18n.t('API Base URL')}
bind:value={RAGConfig.RAG_EXTERNAL_RERANKER_URL}
required
/>
<SensitiveInput
placeholder={$i18n.t('API Key')}
2025-05-10 14:36:45 +00:00
bind:value={RAGConfig.RAG_EXTERNAL_RERANKER_API_KEY}
2025-05-10 14:33:52 +00:00
required={false}
/>
</div>
{/if}
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex flex-col w-full">
<div class=" mb-1 text-xs font-medium">{$i18n.t('Reranking Model')}</div>
<div class="">
<div class="flex w-full">
<div class="flex-1 mr-2">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Set reranking model (e.g. {{model}})', {
model: 'BAAI/bge-reranker-v2-m3'
})}
2025-05-10 14:33:52 +00:00
bind:value={RAGConfig.RAG_RERANKING_MODEL}
2025-04-12 23:33:36 +00:00
/>
</div>
</div>
</div>
</div>
{/if}
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Top K')}</div>
2025-02-26 23:42:19 +00:00
<div class="flex items-center relative">
2025-02-26 21:48:56 +00:00
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-02-26 23:42:19 +00:00
type="number"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Top K')}
bind:value={RAGConfig.TOP_K}
2025-02-26 23:42:19 +00:00
autocomplete="off"
2025-03-28 20:17:43 +00:00
min="0"
2025-02-26 21:48:56 +00:00
/>
</div>
2025-02-26 23:42:19 +00:00
</div>
2025-03-28 20:17:43 +00:00
2025-04-12 23:33:36 +00:00
{#if RAGConfig.ENABLE_RAG_HYBRID_SEARCH === true}
<div class="mb-2.5 flex w-full justify-between">
<div class="self-center text-xs font-medium">{$i18n.t('Top K Reranker')}</div>
2025-03-28 20:17:43 +00:00
<div class="flex items-center relative">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-03-28 20:17:43 +00:00
type="number"
2025-04-12 23:33:36 +00:00
placeholder={$i18n.t('Enter Top K Reranker')}
bind:value={RAGConfig.TOP_K_RERANKER}
2025-03-28 20:17:43 +00:00
autocomplete="off"
2025-04-12 23:33:36 +00:00
min="0"
2025-03-28 20:17:43 +00:00
/>
</div>
</div>
2025-04-12 23:33:36 +00:00
{/if}
{#if RAGConfig.ENABLE_RAG_HYBRID_SEARCH === true}
<div class=" mb-2.5 flex flex-col w-full justify-between">
<div class=" flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Relevance Threshold')}
</div>
<div class="flex items-center relative">
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
type="number"
step="0.01"
placeholder={$i18n.t('Enter Score')}
bind:value={RAGConfig.RELEVANCE_THRESHOLD}
autocomplete="off"
min="0.0"
title={$i18n.t(
'The score should be a value between 0.0 (0%) and 1.0 (100%).'
)}
/>
</div>
</div>
<div class="mt-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>
2025-03-28 20:17:43 +00:00
</div>
2025-04-12 23:33:36 +00:00
{/if}
{#if RAGConfig.ENABLE_RAG_HYBRID_SEARCH === true}
2025-08-04 13:51:22 +00:00
<div class=" mb-2.5 py-0.5 w-full justify-between">
<Tooltip
content={$i18n.t(
'The Weight of BM25 Hybrid Search. 0 more semantic, 1 more lexical. Default 0.5'
2025-08-04 13:51:22 +00:00
)}
placement="top-start"
className="inline-tooltip"
>
<div class="flex w-full justify-between">
2025-08-04 13:51:22 +00:00
<div class=" self-center text-xs font-medium">
{$i18n.t('BM25 Weight')}
</div>
2025-08-04 13:51:22 +00:00
<button
class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden"
type="button"
on:click={() => {
RAGConfig.HYBRID_BM25_WEIGHT =
(RAGConfig?.HYBRID_BM25_WEIGHT ?? null) === null ? 0.5 : null;
}}
>
{#if (RAGConfig?.HYBRID_BM25_WEIGHT ?? null) === null}
<span class="ml-2 self-center"> {$i18n.t('Default')} </span>
{:else}
<span class="ml-2 self-center"> {$i18n.t('Custom')} </span>
{/if}
</button>
</div>
2025-08-04 13:51:22 +00:00
</Tooltip>
{#if (RAGConfig?.HYBRID_BM25_WEIGHT ?? null) !== null}
<div class="flex mt-0.5 space-x-2">
<div class=" flex-1">
2025-08-04 13:51:22 +00:00
<input
id="steps-range"
type="range"
min="0"
max="1"
step="0.05"
bind:value={RAGConfig.HYBRID_BM25_WEIGHT}
class="w-full h-2 rounded-lg appearance-none cursor-pointer dark:bg-gray-700"
/>
<div class="py-0.5">
<div class="flex w-full justify-between">
<div class=" text-left text-xs font-small">
{$i18n.t('semantic')}
2025-08-04 13:51:22 +00:00
</div>
<div class=" text-right text-xs font-small">
{$i18n.t('lexical')}
2025-08-04 13:51:22 +00:00
</div>
</div>
</div>
</div>
<div>
<input
bind:value={RAGConfig.HYBRID_BM25_WEIGHT}
type="number"
class=" bg-transparent text-center w-14"
min="0"
max="1"
step="any"
/>
</div>
2025-08-04 13:51:22 +00:00
</div>
{/if}
</div>
{/if}
{/if}
2024-12-20 04:56:16 +00:00
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex flex-col w-full justify-between">
<div class=" mb-1 text-xs font-medium">{$i18n.t('RAG Template')}</div>
<div class="flex w-full items-center relative">
<Tooltip
content={$i18n.t(
'Leave empty to use the default prompt, or enter a custom prompt'
)}
placement="top-start"
className="w-full"
>
<Textarea
bind:value={RAGConfig.RAG_TEMPLATE}
placeholder={$i18n.t(
'Leave empty to use the default prompt, or enter a custom prompt'
)}
/>
</Tooltip>
</div>
</div>
</div>
{/if}
<div class="mb-3">
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Files')}</div>
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
2025-05-16 17:05:52 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Allowed File Extensions')}</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'Allowed file extensions for upload. Separate multiple extensions with commas. Leave empty for all file types.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="text"
placeholder={$i18n.t('e.g. pdf, docx, txt')}
bind:value={RAGConfig.ALLOWED_FILE_EXTENSIONS}
autocomplete="off"
/>
</Tooltip>
</div>
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Max Upload Size')}</div>
<div class="flex items-center relative">
2025-03-28 20:18:44 +00:00
<Tooltip
2025-04-12 23:33:36 +00:00
content={$i18n.t(
'The maximum file size in MB. If the file size exceeds this limit, the file will not be uploaded.'
)}
2025-03-28 20:18:44 +00:00
placement="top-start"
>
2025-04-12 23:33:36 +00:00
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
bind:value={RAGConfig.FILE_MAX_SIZE}
autocomplete="off"
min="0"
2025-03-28 20:18:44 +00:00
/>
</Tooltip>
</div>
</div>
2024-12-18 18:32:46 +00:00
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Max Upload Count')}</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'The maximum number of files that can be used at once in chat. If the number of files exceeds this limit, the files will not be uploaded.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-12 23:33:36 +00:00
type="number"
placeholder={$i18n.t('Leave empty for unlimited')}
bind:value={RAGConfig.FILE_MAX_COUNT}
autocomplete="off"
min="0"
/>
</Tooltip>
</div>
2024-12-18 18:32:46 +00:00
</div>
2025-06-16 12:52:57 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Image Compression Width')}</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'The width in pixels to compress images to. Leave empty for no compression.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="number"
placeholder={$i18n.t('Leave empty for no compression')}
bind:value={RAGConfig.FILE_IMAGE_COMPRESSION_WIDTH}
autocomplete="off"
min="0"
/>
</Tooltip>
</div>
</div>
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Image Compression Height')}
</div>
<div class="flex items-center relative">
<Tooltip
content={$i18n.t(
'The height in pixels to compress images to. Leave empty for no compression.'
)}
placement="top-start"
>
<input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="number"
placeholder={$i18n.t('Leave empty for no compression')}
bind:value={RAGConfig.FILE_IMAGE_COMPRESSION_HEIGHT}
autocomplete="off"
min="0"
/>
</Tooltip>
</div>
</div>
2024-12-20 04:56:16 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class="mb-3">
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Integration')}</div>
2025-02-26 21:48:56 +00:00
2025-04-12 23:33:36 +00:00
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
2025-02-26 21:48:56 +00:00
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Google Drive')}</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.ENABLE_GOOGLE_DRIVE_INTEGRATION} />
</div>
2025-02-26 21:48:56 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('OneDrive')}</div>
<div class="flex items-center relative">
<Switch bind:state={RAGConfig.ENABLE_ONEDRIVE_INTEGRATION} />
</div>
2025-02-26 21:48:56 +00:00
</div>
</div>
2025-04-12 23:33:36 +00:00
<div class="mb-3">
<div class=" mb-2.5 text-base font-medium">{$i18n.t('Danger Zone')}</div>
2025-02-26 21:48:56 +00:00
2025-04-12 23:33:36 +00:00
<hr class=" border-gray-100 dark:border-gray-850 my-2" />
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">{$i18n.t('Reset Upload Directory')}</div>
<div class="flex items-center relative">
<button
class="text-xs"
on:click={() => {
showResetUploadDirConfirm = true;
}}
>
{$i18n.t('Reset')}
</button>
</div>
2025-02-26 21:48:56 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Reset Vector Storage/Knowledge')}
</div>
<div class="flex items-center relative">
<button
class="text-xs"
on:click={() => {
showResetConfirm = true;
}}
>
{$i18n.t('Reset')}
</button>
</div>
</div>
2025-04-12 23:33:36 +00:00
<div class=" mb-2.5 flex w-full justify-between">
<div class=" self-center text-xs font-medium">
{$i18n.t('Reindex Knowledge Base Vectors')}
</div>
<div class="flex items-center relative">
<button
class="text-xs"
on:click={() => {
showReindexConfirm = true;
}}
>
{$i18n.t('Reindex')}
</button>
</div>
</div>
</div>
2025-02-26 21:48:56 +00:00
</div>
2024-06-04 04:45:36 +00:00
</div>
2025-04-12 23:33:36 +00:00
<div class="flex justify-end pt-3 text-sm font-medium">
<button
class="px-3.5 py-1.5 text-sm font-medium bg-black hover:bg-gray-900 text-white dark:bg-white dark:text-black dark:hover:bg-gray-100 transition rounded-full"
type="submit"
>
{$i18n.t('Save')}
</button>
</div>
{:else}
<div class="flex items-center justify-center h-full">
2025-06-27 12:15:16 +00:00
<Spinner className="size-5" />
2025-04-12 23:33:36 +00:00
</div>
{/if}
2024-02-18 05:06:08 +00:00
</form>