diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 983db4e04b..879f3344f1 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -1548,6 +1548,13 @@ ENABLE_CHANNELS = PersistentConfig( os.environ.get("ENABLE_CHANNELS", "False").lower() == "true", ) +ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS = PersistentConfig( + "ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS", + "knowledge.individual_file_attachments.enable", + os.environ.get("ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS", "True").lower() + == "true", +) + ENABLE_NOTES = PersistentConfig( "ENABLE_NOTES", "notes.enable", diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 5609289166..273ed078b8 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -356,6 +356,7 @@ from open_webui.config import ( API_KEYS_ALLOWED_ENDPOINTS, ENABLE_FOLDERS, ENABLE_CHANNELS, + ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS, ENABLE_NOTES, ENABLE_COMMUNITY_SHARING, ENABLE_MESSAGE_RATING, @@ -772,6 +773,10 @@ app.state.config.BANNERS = WEBUI_BANNERS app.state.config.ENABLE_FOLDERS = ENABLE_FOLDERS app.state.config.ENABLE_CHANNELS = ENABLE_CHANNELS +app.state.config.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS = ( + ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS +) + app.state.config.ENABLE_NOTES = ENABLE_NOTES app.state.config.ENABLE_COMMUNITY_SHARING = ENABLE_COMMUNITY_SHARING app.state.config.ENABLE_MESSAGE_RATING = ENABLE_MESSAGE_RATING @@ -1852,6 +1857,7 @@ async def get_app_config(request: Request): "enable_folders": app.state.config.ENABLE_FOLDERS, "enable_channels": app.state.config.ENABLE_CHANNELS, "enable_notes": app.state.config.ENABLE_NOTES, + "enable_individual_knowledge_file_attachments": app.state.config.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS, "enable_web_search": app.state.config.ENABLE_WEB_SEARCH, "enable_code_execution": app.state.config.ENABLE_CODE_EXECUTION, "enable_code_interpreter": app.state.config.ENABLE_CODE_INTERPRETER, diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py index 3d83dcaea6..1190dcfe50 100644 --- a/backend/open_webui/routers/auths.py +++ b/backend/open_webui/routers/auths.py @@ -940,6 +940,7 @@ async def get_admin_config(request: Request, user=Depends(get_admin_user)): "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, "ENABLE_NOTES": request.app.state.config.ENABLE_NOTES, "ENABLE_USER_WEBHOOKS": request.app.state.config.ENABLE_USER_WEBHOOKS, + "ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS": request.app.state.config.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS, "PENDING_USER_OVERLAY_TITLE": request.app.state.config.PENDING_USER_OVERLAY_TITLE, "PENDING_USER_OVERLAY_CONTENT": request.app.state.config.PENDING_USER_OVERLAY_CONTENT, "RESPONSE_WATERMARK": request.app.state.config.RESPONSE_WATERMARK, @@ -962,6 +963,7 @@ class AdminConfig(BaseModel): ENABLE_CHANNELS: bool ENABLE_NOTES: bool ENABLE_USER_WEBHOOKS: bool + ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS: bool PENDING_USER_OVERLAY_TITLE: Optional[str] = None PENDING_USER_OVERLAY_CONTENT: Optional[str] = None RESPONSE_WATERMARK: Optional[str] = None @@ -986,6 +988,9 @@ async def update_admin_config( request.app.state.config.ENABLE_FOLDERS = form_data.ENABLE_FOLDERS request.app.state.config.ENABLE_CHANNELS = form_data.ENABLE_CHANNELS request.app.state.config.ENABLE_NOTES = form_data.ENABLE_NOTES + request.app.state.config.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS = ( + form_data.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS + ) if form_data.DEFAULT_USER_ROLE in ["pending", "user", "admin"]: request.app.state.config.DEFAULT_USER_ROLE = form_data.DEFAULT_USER_ROLE @@ -1030,6 +1035,7 @@ async def update_admin_config( "ENABLE_CHANNELS": request.app.state.config.ENABLE_CHANNELS, "ENABLE_NOTES": request.app.state.config.ENABLE_NOTES, "ENABLE_USER_WEBHOOKS": request.app.state.config.ENABLE_USER_WEBHOOKS, + "ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS": request.app.state.config.ENABLE_INDIVIDUAL_KNOWLEDGE_FILE_ATTACHMENTS, "PENDING_USER_OVERLAY_TITLE": request.app.state.config.PENDING_USER_OVERLAY_TITLE, "PENDING_USER_OVERLAY_CONTENT": request.app.state.config.PENDING_USER_OVERLAY_CONTENT, "RESPONSE_WATERMARK": request.app.state.config.RESPONSE_WATERMARK, diff --git a/src/lib/components/admin/Settings/General.svelte b/src/lib/components/admin/Settings/General.svelte index 390334b215..f0a16a6933 100644 --- a/src/lib/components/admin/Settings/General.svelte +++ b/src/lib/components/admin/Settings/General.svelte @@ -707,6 +707,13 @@ +
+
+ {$i18n.t('Allow Individual Knowledge File Attachments')} +
+ + +
diff --git a/src/lib/components/chat/MessageInput/Commands/Knowledge.svelte b/src/lib/components/chat/MessageInput/Commands/Knowledge.svelte index 77e5c16804..27552f5b17 100644 --- a/src/lib/components/chat/MessageInput/Commands/Knowledge.svelte +++ b/src/lib/components/chat/MessageInput/Commands/Knowledge.svelte @@ -13,7 +13,7 @@ import Database from '$lib/components/icons/Database.svelte'; import GlobeAlt from '$lib/components/icons/GlobeAlt.svelte'; import Youtube from '$lib/components/icons/Youtube.svelte'; - import { folders } from '$lib/stores'; + import { folders, config } from '$lib/stores'; import Folder from '$lib/components/icons/Folder.svelte'; const i18n = getContext('i18n'); @@ -167,6 +167,10 @@ }; }); + if (!($config?.features?.enable_individual_knowledge_file_attachments ?? true)) { + items = items.filter((it) => it.type !== 'file'); + } + fuse = new Fuse(items, { keys: ['name', 'description'] }); diff --git a/src/lib/components/chat/MessageInput/InputMenu/Knowledge.svelte b/src/lib/components/chat/MessageInput/InputMenu/Knowledge.svelte index df8d8aabab..a49de7906f 100644 --- a/src/lib/components/chat/MessageInput/InputMenu/Knowledge.svelte +++ b/src/lib/components/chat/MessageInput/InputMenu/Knowledge.svelte @@ -2,7 +2,7 @@ import { onMount, tick, getContext } from 'svelte'; import { decodeString } from '$lib/utils'; - import { knowledge } from '$lib/stores'; + import { knowledge, config } from '$lib/stores'; import { getKnowledgeBases } from '$lib/apis/knowledge'; @@ -99,7 +99,9 @@ }; } ); - + if (!($config?.features?.enable_individual_knowledge_file_attachments ?? true)) { + items = items.filter((it) => it.type !== 'file'); + } await tick(); loaded = true; diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 57257d59d3..fe7e6688b5 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -274,6 +274,7 @@ type Config = { enable_autocomplete_generation: boolean; enable_direct_connections: boolean; enable_version_update_check: boolean; + enable_individual_knowledge_file_attachments: boolean; }; oauth: { providers: {