2024-02-18 13:06:08 +08:00
< script lang = "ts" >
2024-10-02 08:35:35 +08:00
import { toast } from 'svelte-sonner';
2024-08-27 23:05:24 +08:00
import { onMount , getContext , createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher();
2024-02-18 14:47:58 +08:00
import {
2024-03-03 10:56:57 +08:00
getQuerySettings,
2024-03-24 11:50:57 +08:00
updateQuerySettings,
2024-04-05 01:01:23 +08:00
resetVectorDB,
2024-04-15 06:31:40 +08:00
getEmbeddingConfig,
2024-04-23 04:49:58 +08:00
updateEmbeddingConfig,
getRerankingConfig,
2024-06-04 12:45:36 +08:00
updateRerankingConfig,
2024-06-09 17:28:52 +08:00
getRAGConfig,
updateRAGConfig
2024-09-28 07:36:35 +08:00
} from '$lib/apis/retrieval';
2024-10-02 08:35:35 +08:00
2025-04-13 07:33:36 +08:00
import { reindexKnowledgeFiles } from '$lib/apis/knowledge';
import { deleteAllFiles } from '$lib/apis/files';
2024-10-02 08:35:35 +08:00
2024-06-15 18:02:20 +08:00
import ResetUploadDirConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
import ResetVectorDBConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
2025-04-07 23:53:11 +08:00
import ReindexKnowledgeFilesConfirmDialog from '$lib/components/common/ConfirmDialog.svelte';
2024-06-25 20:15:29 +08:00
import SensitiveInput from '$lib/components/common/SensitiveInput.svelte';
2024-08-27 23:05:24 +08:00
import Tooltip from '$lib/components/common/Tooltip.svelte';
2024-10-13 18:02:02 +08:00
import Switch from '$lib/components/common/Switch.svelte';
2024-10-20 14:17:47 +08:00
import Textarea from '$lib/components/common/Textarea.svelte';
2025-04-13 07:33:36 +08:00
import Spinner from '$lib/components/common/Spinner.svelte';
2024-02-18 13:06:08 +08:00
2024-03-03 04:38:51 +08:00
const i18n = getContext('i18n');
2024-04-10 15:33:45 +08:00
let updateEmbeddingModelLoading = false;
2024-04-23 04:49:58 +08:00
let updateRerankingModelLoading = false;
2024-02-18 13:14:42 +08:00
2024-03-24 11:50:57 +08:00
let showResetConfirm = false;
2024-06-04 12:45:36 +08:00
let showResetUploadDirConfirm = false;
2025-04-07 23:44:10 +08:00
let showReindexConfirm = false;
2024-03-24 11:50:57 +08:00
2024-04-15 05:55:00 +08:00
let embeddingEngine = '';
2024-04-15 06:31:40 +08:00
let embeddingModel = '';
2024-09-27 06:28:47 +08:00
let embeddingBatchSize = 1;
2024-04-23 04:49:58 +08:00
let rerankingModel = '';
2024-04-15 06:31:40 +08:00
2025-05-30 04:34:18 +08:00
let OpenAIUrl = '';
let OpenAIKey = '';
2025-05-20 10:58:04 +08:00
2025-05-30 04:34:18 +08:00
let AzureOpenAIUrl = '';
let AzureOpenAIKey = '';
let AzureOpenAIVersion = '';
2024-11-19 06:19:56 +08:00
let OllamaUrl = '';
let OllamaKey = '';
2024-04-15 07:48:15 +08:00
2024-03-03 10:56:57 +08:00
let querySettings = {
template: '',
2024-04-23 07:36:46 +08:00
r: 0.0,
2024-04-26 06:31:21 +08:00
k: 4,
2025-03-06 17:47:57 +08:00
k_reranker: 4,
2024-04-26 06:31:21 +08:00
hybrid: false
2024-03-03 10:56:57 +08:00
};
2024-02-18 14:47:58 +08:00
2025-04-13 07:33:36 +08:00
let RAGConfig = null;
2024-04-05 01:01:23 +08:00
const embeddingModelUpdateHandler = async () => {
2024-04-15 07:48:15 +08: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-15 06:31:40 +08:00
toast.error(
$i18n.t(
'Model filesystem path detected. Model shortname is required for update, cannot continue.'
)
);
return;
}
2024-04-15 07:48:15 +08:00
if (embeddingEngine === 'openai' && embeddingModel === '') {
2024-04-06 18:38:34 +08:00
toast.error(
$i18n.t(
'Model filesystem path detected. Model shortname is required for update, cannot continue.'
)
);
2024-04-06 18:22:48 +08:00
return;
}
2025-05-30 04:34:18 +08:00
if (
embeddingEngine === 'azure_openai' & &
(AzureOpenAIKey === '' || AzureOpenAIUrl === '' || AzureOpenAIVersion === '')
) {
toast.error($i18n.t('OpenAI URL/Key required.'));
return;
}
2024-04-15 07:48:15 +08:00
2025-05-16 03:53:07 +08:00
console.debug('Update embedding model attempt:', embeddingModel);
2024-04-06 18:22:48 +08:00
2024-04-10 15:33:45 +08:00
updateEmbeddingModelLoading = true;
2025-05-30 04:34:18 +08:00
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 14:41:32 +08:00
toast.error(`${ error } `);
2024-04-15 07:48:15 +08:00
await setEmbeddingConfig();
2024-04-10 15:46:09 +08:00
return null;
});
2024-04-10 15:33:45 +08:00
updateEmbeddingModelLoading = false;
2024-04-05 01:01:23 +08:00
if (res) {
2025-05-16 03:53:07 +08:00
console.debug('embeddingModelUpdateHandler:', res);
2024-04-06 18:22:48 +08:00
if (res.status === true) {
2024-04-15 07:48:15 +08:00
toast.success($i18n.t('Embedding model set to "{{ embedding_model }} "', res), {
2024-04-06 18:38:34 +08:00
duration: 1000 * 10
});
2024-04-05 01:01:23 +08:00
}
}
};
2024-02-18 14:29:52 +08:00
const submitHandler = async () => {
2025-05-15 02:28:40 +08:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'external' & &
RAGConfig.EXTERNAL_DOCUMENT_LOADER_URL === ''
) {
toast.error($i18n.t('External Document Loader URL required.'));
return;
}
2025-04-13 07:33:36 +08:00
if (RAGConfig.CONTENT_EXTRACTION_ENGINE === 'tika' && RAGConfig.TIKA_SERVER_URL === '') {
2024-07-02 02:10:59 +08:00
toast.error($i18n.t('Tika Server URL required.'));
return;
}
2025-04-13 07:33:36 +08:00
if (RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling' && RAGConfig.DOCLING_SERVER_URL === '') {
2025-02-14 20:08:03 +08:00
toast.error($i18n.t('Docling Server URL required.'));
return;
}
2025-05-04 03:48:12 +08:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'docling' & &
2025-05-03 13:12:58 +08:00
((RAGConfig.DOCLING_OCR_ENGINE === '' & & RAGConfig.DOCLING_OCR_LANG !== '') ||
2025-05-04 03:48:12 +08: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.')
);
2025-05-03 05:31:00 +08:00
return;
}
2025-04-13 07:33:36 +08:00
2025-05-29 06:33:40 +08:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'datalab_marker' & &
!RAGConfig.DATALAB_MARKER_API_KEY
) {
toast.error($i18n.t('Datalab Marker API Key required.'));
return;
}
2025-07-23 08:49:28 +08: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;
}
}
2025-02-07 20:44:47 +08:00
if (
2025-04-13 07:33:36 +08:00
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'document_intelligence' & &
(RAGConfig.DOCUMENT_INTELLIGENCE_ENDPOINT === '' ||
RAGConfig.DOCUMENT_INTELLIGENCE_KEY === '')
2025-02-07 20:44:47 +08:00
) {
toast.error($i18n.t('Document Intelligence endpoint and key required.'));
return;
}
2025-04-13 07:33:36 +08:00
if (
RAGConfig.CONTENT_EXTRACTION_ENGINE === 'mistral_ocr' & &
RAGConfig.MISTRAL_OCR_API_KEY === ''
) {
2025-03-22 20:44:50 +08:00
toast.error($i18n.t('Mistral OCR API Key required.'));
return;
}
2025-02-27 07:42:19 +08:00
2025-04-13 07:33:36 +08:00
if (!RAGConfig.BYPASS_EMBEDDING_AND_RETRIEVAL) {
2025-02-27 07:42:19 +08:00
await embeddingModelUpdateHandler();
}
2025-06-09 00:02:14 +08:00
const res = await updateRAGConfig(localStorage.token, {
...RAGConfig,
ALLOWED_FILE_EXTENSIONS: RAGConfig.ALLOWED_FILE_EXTENSIONS.split(',')
.map((ext) => ext.trim())
.filter((ext) => ext !== ''),
DATALAB_MARKER_LANGS: RAGConfig.DATALAB_MARKER_LANGS.split(',')
.map((code) => code.trim())
.filter((code) => code !== '')
.join(', '),
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 23:05:24 +08:00
dispatch('save');
2024-02-18 14:29:52 +08:00
};
2024-04-15 07:48:15 +08:00
const setEmbeddingConfig = async () => {
const embeddingConfig = await getEmbeddingConfig(localStorage.token);
if (embeddingConfig) {
embeddingEngine = embeddingConfig.embedding_engine;
embeddingModel = embeddingConfig.embedding_model;
2024-09-27 06:28:47 +08:00
embeddingBatchSize = embeddingConfig.embedding_batch_size ?? 1;
2024-04-15 07:48:15 +08:00
2025-05-30 04:34:18 +08:00
OpenAIKey = embeddingConfig.openai_config.key;
OpenAIUrl = embeddingConfig.openai_config.url;
2024-11-19 06:19:56 +08:00
2025-05-30 04:34:18 +08:00
OllamaKey = embeddingConfig.ollama_config.key;
OllamaUrl = embeddingConfig.ollama_config.url;
2025-05-20 10:58:04 +08:00
2025-05-30 04:34:18 +08:00
AzureOpenAIKey = embeddingConfig.azure_openai_config.key;
AzureOpenAIUrl = embeddingConfig.azure_openai_config.url;
AzureOpenAIVersion = embeddingConfig.azure_openai_config.version;
}
};
2024-02-18 14:29:52 +08:00
onMount(async () => {
2024-04-15 07:48:15 +08:00
await setEmbeddingConfig();
2024-04-05 01:01:23 +08:00
2025-05-17 01:05:52 +08:00
const config = await getRAGConfig(localStorage.token);
2025-05-19 04:13:03 +08:00
config.ALLOWED_FILE_EXTENSIONS = (config?.ALLOWED_FILE_EXTENSIONS ?? []).join(', ');
2025-06-09 00:02:14 +08: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-07-23 08:49:28 +08:00
// Set default API Base URL if empty
if (!config.DATALAB_MARKER_API_BASE_URL) {
config.DATALAB_MARKER_API_BASE_URL = 'https://www.datalab.to/api/v1/marker';
}
2025-05-17 01:05:52 +08:00
RAGConfig = config;
2024-02-18 14:29:52 +08:00
});
2024-02-18 13:06:08 +08:00
< / script >
2024-06-15 18:02:20 +08:00
< ResetUploadDirConfirmDialog
bind:show={ showResetUploadDirConfirm }
2024-06-19 06:20:04 +08:00
on:confirm={ async () => {
const res = await deleteAllFiles(localStorage.token).catch((error) => {
2025-01-21 14:41:32 +08:00
toast.error(`${ error } `);
2024-06-15 18:02:20 +08: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 14:41:32 +08:00
toast.error(`${ error } `);
2024-06-15 18:02:20 +08:00
return null;
});
if (res) {
toast.success($i18n.t('Success'));
}
}}
/>
2025-04-07 23:53:11 +08:00
< ReindexKnowledgeFilesConfirmDialog
2025-04-07 23:44:10 +08:00
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 13:06:08 +08:00
< form
class="flex flex-col h-full justify-between space-y-3 text-sm"
on:submit| preventDefault={() => {
2024-02-18 14:29:52 +08:00
submitHandler();
2024-02-18 13:06:08 +08:00
}}
>
2025-04-13 07:33:36 +08:00
{ #if RAGConfig }
< div class = " space-y-2.5 overflow-y-scroll scrollbar-hidden h-full pr-1.5" >
< div class = "" >
2025-02-27 07:42:19 +08:00
< div class = "mb-3" >
2025-04-13 07:33:36 +08:00
< div class = " mb-2.5 text-base font-medium" > { $i18n . t ( 'General' )} </ div >
2025-02-27 05:59:08 +08:00
2025-02-27 07:42:19 +08:00
< hr class = " border-gray-100 dark:border-gray-850 my-2" / >
2025-02-27 05:59:08 +08:00
2025-04-13 07:33:36 +08:00
< div class = "mb-2.5 flex flex-col w-full justify-between" >
2025-05-15 01:26:49 +08:00
< div class = "flex w-full justify-between mb-1" >
2025-04-13 07:33:36 +08:00
< div class = "self-center text-xs font-medium" >
{ $i18n . t ( 'Content Extraction Engine' )}
2025-02-27 07:42:19 +08:00
< / div >
2025-04-13 07:33:36 +08:00
< div class = "" >
2025-02-27 07:42:19 +08:00
< select
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
>
2025-04-13 07:33:36 +08:00
< option value = "" > { $i18n . t ( 'Default' )} </ option >
2025-05-15 02:28:40 +08:00
< option value = "external" > { $i18n . t ( 'External' )} </ option >
2025-04-13 07:33:36 +08:00
< option value = "tika" > { $i18n . t ( 'Tika' )} </ option >
< option value = "docling" > { $i18n . t ( 'Docling' )} </ option >
2025-05-29 06:33:40 +08:00
< option value = "datalab_marker" > { $i18n . t ( 'Datalab Marker API' )} </ option >
2025-04-13 07:33:36 +08:00
< option value = "document_intelligence" > { $i18n . t ( 'Document Intelligence' )} </ option >
< option value = "mistral_ocr" > { $i18n . t ( 'Mistral OCR' )} </ option >
2025-02-27 07:42:19 +08:00
< / select >
< / div >
2025-02-27 05:48:56 +08:00
< / div >
2025-02-27 07:42:19 +08:00
2025-04-13 07:33:36 +08: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 >
2025-05-27 12:44:07 +08:00
{ :else if RAGConfig . CONTENT_EXTRACTION_ENGINE === 'datalab_marker' }
2025-05-29 06:33:40 +08:00
< div class = "my-0.5 flex gap-2 pr-2" >
2025-07-23 08:49:28 +08: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-05-29 06:33:40 +08:00
< SensitiveInput
placeholder={ $i18n . t ( 'Enter Datalab Marker API Key' )}
required={ false }
bind:value={ RAGConfig . DATALAB_MARKER_API_KEY }
/>
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08:00
2025-07-23 08:49:28 +08: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-29 06:33:40 +08:00
< / div >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 08:49:28 +08: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-29 06:33:40 +08:00
)}
placement="top-start"
>
{ $i18n . t ( 'Use LLM' )}
< / Tooltip >
< / div >
< div class = "flex items-center" >
< Switch bind:state = { RAGConfig . DATALAB_MARKER_USE_LLM } / >
< / div >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 09:06:29 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-29 06:33:40 +08: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 >
2025-05-27 12:44:07 +08:00
< / div >
2025-05-15 02:28:40 +08: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-13 07:33:36 +08:00
{ :else if RAGConfig . CONTENT_EXTRACTION_ENGINE === 'tika' }
< div class = "flex w-full mt-1" >
< div class = "flex-1 mr-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'Enter Docling Server URL' )}
bind:value={ RAGConfig . DOCLING_SERVER_URL }
2025-02-27 07:42:19 +08:00
/>
< / div >
2025-05-03 05:31:00 +08:00
< div class = "flex w-full mt-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-05-03 05:31:00 +08:00
placeholder={ $i18n . t ( 'Enter Docling OCR Engine' )}
bind:value={ RAGConfig . DOCLING_OCR_ENGINE }
/>
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-05-03 05:31:00 +08:00
placeholder={ $i18n . t ( 'Enter Docling OCR Language(s)' )}
bind:value={ RAGConfig . DOCLING_OCR_LANG }
/>
< / div >
2025-05-15 01:26:49 +08:00
< 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 >
2025-06-08 22:30:26 +08:00
{ #if RAGConfig . DOCLING_DO_PICTURE_DESCRIPTION }
2025-06-09 00:02:14 +08: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 >
2025-06-08 22:30:26 +08:00
< / div >
< / div >
{ #if RAGConfig . DOCLING_PICTURE_DESCRIPTION_MODE === 'local' }
2025-06-09 00:02:14 +08: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' )}
2025-06-08 22:30:26 +08:00
< / div >
2025-06-09 00:02:14 +08:00
< div class = "flex w-full items-center relative" >
2025-06-08 22:30:26 +08:00
< Tooltip
2025-06-09 00:02:14 +08: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.'
)}
2025-06-08 22:30:26 +08:00
placement="top-start"
2025-06-09 00:02:14 +08:00
className="w-full"
2025-06-08 22:30:26 +08:00
>
2025-06-09 00:02:14 +08:00
< Textarea
bind:value={ RAGConfig . DOCLING_PICTURE_DESCRIPTION_LOCAL }
2025-06-09 00:05:26 +08:00
placeholder={ $i18n . t ( 'Enter Config in JSON format' )}
2025-06-09 00:02:14 +08:00
/>
2025-06-08 22:30:26 +08:00
< / Tooltip >
< / div >
< / div >
< / div >
{ :else if RAGConfig . DOCLING_PICTURE_DESCRIPTION_MODE === 'api' }
2025-06-09 00:02:14 +08: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' )}
2025-06-08 22:30:26 +08:00
< / div >
2025-06-09 00:02:14 +08:00
< div class = "flex w-full items-center relative" >
2025-06-08 22:30:26 +08:00
< Tooltip
2025-06-09 00:02:14 +08: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.'
)}
2025-06-08 22:30:26 +08:00
placement="top-start"
2025-06-09 00:02:14 +08:00
className="w-full"
2025-06-08 22:30:26 +08:00
>
2025-06-09 00:02:14 +08:00
< Textarea
bind:value={ RAGConfig . DOCLING_PICTURE_DESCRIPTION_API }
2025-06-09 00:05:26 +08:00
placeholder={ $i18n . t ( 'Enter Config in JSON format' )}
2025-06-09 00:02:14 +08:00
/>
2025-06-08 22:30:26 +08:00
< / Tooltip >
< / div >
< / div >
< / div >
{ /if }
{ /if }
2025-04-13 07:33:36 +08:00
{ :else if RAGConfig . CONTENT_EXTRACTION_ENGINE === 'document_intelligence' }
2025-02-27 07:42:19 +08:00
< div class = "my-0.5 flex gap-2 pr-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'Enter Document Intelligence Endpoint' )}
bind:value={ RAGConfig . DOCUMENT_INTELLIGENCE_ENDPOINT }
2025-02-27 07:42:19 +08:00
/>
< SensitiveInput
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'Enter Document Intelligence Key' )}
bind:value={ RAGConfig . DOCUMENT_INTELLIGENCE_KEY }
2025-02-27 07:42:19 +08:00
/>
< / div >
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
/>
2025-02-27 05:48:56 +08:00
< / div >
2025-04-13 07:33:36 +08:00
{ /if }
< / div >
2025-02-27 07:42:19 +08:00
< div class = " mb-2.5 flex w-full justify-between" >
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
< div class = "flex items-center relative" >
< Tooltip
2025-04-13 07:33:36 +08:00
content={ RAGConfig . BYPASS_EMBEDDING_AND_RETRIEVAL
2025-03-07 19:59:09 +08: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-27 07:42:19 +08:00
>
2025-04-13 07:33:36 +08:00
< Switch bind:state = { RAGConfig . BYPASS_EMBEDDING_AND_RETRIEVAL } / >
2025-02-27 07:42:19 +08:00
< / Tooltip >
< / div >
< / div >
2024-05-07 05:36:36 +08:00
2025-04-13 07:33:36 +08:00
{ #if ! RAGConfig . BYPASS_EMBEDDING_AND_RETRIEVAL }
2025-03-29 04:16:56 +08:00
< div class = " mb-2.5 flex w-full justify-between" >
2025-04-13 07:33:36 +08:00
< div class = " self-center text-xs font-medium" > { $i18n . t ( 'Text Splitter' )} </ div >
2025-03-29 04:16:56 +08:00
< div class = "flex items-center relative" >
2025-04-13 07:33:36 +08: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 >
2025-05-24 08:19:44 +08:00
< option value = "markdown_header" > { $i18n . t ( 'Markdown (Header)' )} </ option >
2025-04-13 07:33:36 +08:00
< / select >
2025-03-29 04:16:56 +08:00
< / div >
2025-02-27 07:42:19 +08:00
< / div >
2025-04-13 07:33:36 +08: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-03-29 04:16:56 +08:00
2025-04-13 07:33:36 +08: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 }
placeholder="Select an embedding model engine"
on:change={( e ) => {
2025-05-30 04:34:18 +08:00
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-13 07:33:36 +08:00
}}
>
< option value = "" > { $i18n . t ( 'Default (SentenceTransformers)' )} </ option >
< option value = "ollama" > { $i18n . t ( 'Ollama' )} </ option >
2025-05-30 04:34:18 +08:00
< option value = "openai" > { $i18n . t ( 'OpenAI' )} </ option >
< option value = "azure_openai" > Azure OpenAI< / option >
2025-04-13 07:33:36 +08:00
< / select >
< / div >
< / div >
2025-05-30 04:34:18 +08:00
{ #if embeddingEngine === 'openai' }
2025-04-13 07:33:36 +08:00
< div class = "my-0.5 flex gap-2 pr-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'API Base URL' )}
bind:value={ OpenAIUrl }
required
/>
2025-07-02 03:03:50 +08:00
< SensitiveInput
placeholder={ $i18n . t ( 'API Key' )}
bind:value={ OpenAIKey }
required={ false }
/>
2025-04-13 07:33:36 +08:00
< / div >
2025-05-30 04:34:18 +08:00
{ :else if embeddingEngine === 'ollama' }
2025-04-13 07:33:36 +08:00
< div class = "my-0.5 flex gap-2 pr-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'API Base URL' )}
bind:value={ OllamaUrl }
required
/>
< SensitiveInput
placeholder={ $i18n . t ( 'API Key' )}
bind:value={ OllamaKey }
required={ false }
/>
< / div >
2025-05-30 04:34:18 +08:00
{ :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"
placeholder="Version"
bind:value={ AzureOpenAIVersion }
required
/>
< / div >
< / div >
{ /if }
2025-04-13 07:33:36 +08: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
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
bind:value={ embeddingModel }
placeholder={ $i18n . t ( 'Set embedding model' )}
required
/>
< / div >
< / div >
{ : else }
2025-03-29 04:16:56 +08:00
< div class = "flex w-full" >
< div class = "flex-1 mr-2" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( ' Set embedding model ( e . g . {{ model }}) ' , {
model: embeddingModel.slice(-40)
2025-03-29 04:16:56 +08:00
})}
2025-04-13 07:33:36 +08:00
bind:value={ embeddingModel }
2025-03-29 04:16:56 +08:00
/>
< / div >
2025-04-13 07:33:36 +08: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-26 06:44:45 +08:00
< Spinner / >
2025-04-13 07:33:36 +08:00
< / div >
{ : else }
2025-03-29 04:16:56 +08:00
< svg
xmlns="http://www.w3.org/2000/svg"
2025-04-13 07:33:36 +08:00
viewBox="0 0 16 16"
fill="currentColor"
class="w-4 h-4"
2025-03-29 04:16:56 +08:00
>
< path
2025-04-13 07:33:36 +08: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"
2025-03-29 04:16:56 +08:00
/>
< path
2025-04-13 07:33:36 +08: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"
2025-03-29 04:16:56 +08:00
/>
< / svg >
2025-04-13 07:33:36 +08:00
{ /if }
< / button >
{ /if }
2025-03-29 04:16:56 +08:00
< / div >
2025-04-13 07:33:36 +08:00
{ /if }
< / div >
< div class = "mt-1 mb-1 text-xs text-gray-400 dark:text-gray-500" >
{ $i18n . t (
'Warning: If you update or change your embedding model, you will need to re-import all documents.'
)}
< / div >
< / div >
2025-05-30 04:34:18 +08:00
{ #if embeddingEngine === 'ollama' || embeddingEngine === 'openai' || embeddingEngine === 'azure_openai' }
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
< / div >
2025-02-27 05:48:56 +08:00
< / div >
2025-03-29 04:16:56 +08:00
{ /if }
2025-04-13 07:33:36 +08: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-27 05:48:56 +08:00
2025-03-29 04:17:43 +08:00
< div class = " mb-2.5 flex w-full justify-between" >
2025-04-13 07:33:36 +08:00
< div class = " self-center text-xs font-medium" > { $i18n . t ( 'Full Context Mode' )} </ div >
2025-03-06 17:47:57 +08:00
< div class = "flex items-center relative" >
2025-04-13 07:33:36 +08: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 17:47:57 +08:00
< / div >
< / div >
2025-04-13 07:33:36 +08: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-09 00:02:14 +08:00
< Switch bind:state = { RAGConfig . ENABLE_RAG_HYBRID_SEARCH } / >
2025-04-13 07:33:36 +08:00
< / div >
< / div >
{ #if RAGConfig . ENABLE_RAG_HYBRID_SEARCH === true }
2025-05-10 22:33:52 +08: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 }
placeholder="Select a reranking model engine"
2025-05-10 22:38:30 +08: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 22:33:52 +08: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
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-05-10 22:33:52 +08:00
placeholder={ $i18n . t ( 'API Base URL' )}
bind:value={ RAGConfig . RAG_EXTERNAL_RERANKER_URL }
required
/>
< SensitiveInput
placeholder={ $i18n . t ( 'API Key' )}
2025-05-10 22:36:45 +08:00
bind:value={ RAGConfig . RAG_EXTERNAL_RERANKER_API_KEY }
2025-05-10 22:33:52 +08:00
required={ false }
/>
< / div >
{ /if }
< / div >
2025-04-13 07:33:36 +08: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
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( ' Set reranking model ( e . g . {{ model }}) ' , {
model: 'BAAI/bge-reranker-v2-m3'
})}
2025-05-10 22:33:52 +08:00
bind:value={ RAGConfig . RAG_RERANKING_MODEL }
2025-04-13 07:33:36 +08: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-27 07:42:19 +08:00
< div class = "flex items-center relative" >
2025-02-27 05:48:56 +08:00
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-02-27 07:42:19 +08:00
type="number"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'Enter Top K' )}
bind:value={ RAGConfig . TOP_K }
2025-02-27 07:42:19 +08:00
autocomplete="off"
2025-03-29 04:17:43 +08:00
min="0"
2025-02-27 05:48:56 +08:00
/>
< / div >
2025-02-27 07:42:19 +08:00
< / div >
2025-03-29 04:17:43 +08:00
2025-04-13 07:33:36 +08: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-29 04:17:43 +08:00
< div class = "flex items-center relative" >
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-03-29 04:17:43 +08:00
type="number"
2025-04-13 07:33:36 +08:00
placeholder={ $i18n . t ( 'Enter Top K Reranker' )}
bind:value={ RAGConfig . TOP_K_RERANKER }
2025-03-29 04:17:43 +08:00
autocomplete="off"
2025-04-13 07:33:36 +08:00
min="0"
2025-03-29 04:17:43 +08:00
/>
< / div >
< / div >
2025-04-13 07:33:36 +08: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
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08: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-29 04:17:43 +08:00
< / div >
2025-04-13 07:33:36 +08:00
{ /if }
2025-05-20 16:39:31 +08:00
{ #if RAGConfig . ENABLE_RAG_HYBRID_SEARCH === true }
< div class = "mb-2.5 flex w-full justify-between" >
2025-05-24 06:13:46 +08:00
< div class = "self-center text-xs font-medium" >
{ $i18n . t ( 'Weight of BM25 Retrieval' )}
< / div >
2025-05-20 16:39:31 +08:00
< div class = "flex items-center relative" >
< input
class="flex-1 w-full text-sm bg-transparent outline-hidden"
type="number"
step="0.01"
placeholder={ $i18n . t ( 'Enter BM25 Weight' )}
2025-05-24 04:06:44 +08:00
bind:value={ RAGConfig . HYBRID_BM25_WEIGHT }
2025-05-20 16:39:31 +08:00
autocomplete="off"
min="0.0"
max="1.0"
/>
< / div >
< / div >
{ /if }
2025-03-29 04:17:43 +08:00
{ /if }
2024-12-20 12:56:16 +08:00
2025-04-13 07:33:36 +08: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-17 01:05:52 +08: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-13 07:33:36 +08: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-29 04:18:44 +08:00
< Tooltip
2025-04-13 07:33:36 +08: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-29 04:18:44 +08:00
placement="top-start"
>
2025-04-13 07:33:36 +08:00
< input
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
type="number"
placeholder={ $i18n . t ( 'Leave empty for unlimited' )}
bind:value={ RAGConfig . FILE_MAX_SIZE }
autocomplete="off"
min="0"
2025-03-29 04:18:44 +08:00
/>
< / Tooltip >
2024-06-09 17:28:52 +08:00
< / div >
< / div >
2024-12-19 02:32:46 +08:00
2025-04-13 07:33:36 +08: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
2025-05-15 01:26:49 +08:00
class="flex-1 w-full text-sm bg-transparent outline-hidden"
2025-04-13 07:33:36 +08:00
type="number"
placeholder={ $i18n . t ( 'Leave empty for unlimited' )}
bind:value={ RAGConfig . FILE_MAX_COUNT }
autocomplete="off"
min="0"
/>
< / Tooltip >
< / div >
2024-12-19 02:32:46 +08:00
< / div >
2025-06-16 20:52:57 +08: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 12:56:16 +08:00
< / div >
2025-04-13 07:33:36 +08:00
< div class = "mb-3" >
< div class = " mb-2.5 text-base font-medium" > { $i18n . t ( 'Integration' )} </ div >
2025-02-27 05:48:56 +08:00
2025-04-13 07:33:36 +08:00
< hr class = " border-gray-100 dark:border-gray-850 my-2" / >
2025-02-27 05:48:56 +08:00
2025-04-13 07:33:36 +08: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-27 05:48:56 +08:00
< / div >
2025-04-13 07:33:36 +08: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-27 05:48:56 +08:00
< / div >
< / div >
2025-04-13 07:33:36 +08:00
< div class = "mb-3" >
< div class = " mb-2.5 text-base font-medium" > { $i18n . t ( 'Danger Zone' )} </ div >
2025-02-27 05:48:56 +08:00
2025-04-13 07:33:36 +08: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-27 05:48:56 +08:00
< / div >
2025-04-13 07:33:36 +08: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 >
2025-04-07 23:44:10 +08:00
< / div >
2025-04-13 07:33:36 +08: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 >
2025-04-07 23:44:10 +08:00
< / div >
< / div >
2025-02-27 05:48:56 +08:00
< / div >
2024-06-04 12:45:36 +08:00
< / div >
2025-04-13 07:33:36 +08: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 20:15:16 +08:00
< Spinner className = "size-5" / >
2025-04-13 07:33:36 +08:00
< / div >
{ /if }
2024-02-18 13:06:08 +08:00
< / form >