From 2cf014c7e9be601116d8e93da0d7367f77d6f14e Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Sun, 25 Oct 2026 00:46:22 +0200 Subject: [PATCH] fix: built-in tool toggles show while their feature is off (#32964) * fix: built-in tool toggles show while their feature is off The model editor listed the Memory, Notes, Channels, Notifications, Web Search, Image Generation, Code Interpreter, Automations, Calendar and Sub-agents built-in tools even when the admin had turned that feature off for the whole instance, where those toggles do nothing. Each of them is now hidden while its feature is off, and the choices saved on a model are kept for when it is turned back on. The server now also reports whether sub-agents are on, and saving the Sub-agents settings updates the editor without a reload. Refs #32830 * refac: name the feature switch map like the rest of the codebase Uses the same name the model capabilities change uses for its matching map. * refac: keep each tool's feature switch next to its label Each built-in tool now carries its feature switch alongside its label and description, so the list is defined in one place. --- backend/open_webui/main.py | 2 + .../admin/Settings/Subagents.svelte | 3 ++ .../workspace/Models/BuiltinTools.svelte | 41 ++++++++++++------- src/lib/stores/index.ts | 6 +++ 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 846f5aab35..b18224fb7f 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -2361,6 +2361,7 @@ async def get_app_config(request: Request): 'google_drive.enable', 'onedrive.enable', 'memories.enable', + 'subagents.enable', 'ui.default_models', 'ui.default_pinned_models', 'ui.default_interface_settings', @@ -2469,6 +2470,7 @@ async def get_app_config(request: Request): 'enable_google_drive_integration': config.get('google_drive.enable'), 'enable_onedrive_integration': config.get('onedrive.enable'), 'enable_memories': config.get('memories.enable'), + 'enable_subagents': config.get('subagents.enable'), **( { 'enable_onedrive_personal': ENABLE_ONEDRIVE_PERSONAL, diff --git a/src/lib/components/admin/Settings/Subagents.svelte b/src/lib/components/admin/Settings/Subagents.svelte index 0784df2581..a1a490c4f2 100644 --- a/src/lib/components/admin/Settings/Subagents.svelte +++ b/src/lib/components/admin/Settings/Subagents.svelte @@ -3,6 +3,8 @@ import { getContext, onMount } from 'svelte'; import { toast } from 'svelte-sonner'; + import { config as appConfig } from '$lib/stores'; + import { getBackendConfig } from '$lib/apis'; import { getSubagentsConfig, setSubagentsConfig } from '$lib/apis/configs'; import Spinner from '$lib/components/common/Spinner.svelte'; import Switch from '$lib/components/common/Switch.svelte'; @@ -48,6 +50,7 @@ SUBAGENTS_MAX_OUTPUT: maxOutput, SUBAGENTS_SYSTEM_PROMPT: systemPrompt }); + await appConfig.set(await getBackendConfig()); toast.success($i18n.t('Settings saved successfully!')); } catch (error) { toast.error(`${error}`); diff --git a/src/lib/components/workspace/Models/BuiltinTools.svelte b/src/lib/components/workspace/Models/BuiltinTools.svelte index a0209a0f16..c33e05aafd 100644 --- a/src/lib/components/workspace/Models/BuiltinTools.svelte +++ b/src/lib/components/workspace/Models/BuiltinTools.svelte @@ -2,6 +2,7 @@ import { getContext } from 'svelte'; import type { Writable } from 'svelte/store'; import type { i18n as i18nType } from 'i18next'; + import { config } from '$lib/stores'; import ModelSettingToggle from './ModelSettingToggle.svelte'; import ModelSettingsSection from './ModelSettingsSection.svelte'; @@ -19,7 +20,8 @@ }, memory: { label: $i18n.t('settings.admin.models.builtinTools.memory.label'), - description: $i18n.t('settings.admin.models.builtinTools.memory.description') + description: $i18n.t('settings.admin.models.builtinTools.memory.description'), + enabled: $config?.features?.enable_memories }, chats: { label: $i18n.t('settings.admin.models.builtinTools.chats.label'), @@ -27,7 +29,8 @@ }, notes: { label: $i18n.t('settings.admin.models.builtinTools.notes.label'), - description: $i18n.t('settings.admin.models.builtinTools.notes.description') + description: $i18n.t('settings.admin.models.builtinTools.notes.description'), + enabled: $config?.features?.enable_notes }, knowledge: { label: $i18n.t('settings.admin.models.builtinTools.knowledge.label'), @@ -39,23 +42,28 @@ }, channels: { label: $i18n.t('settings.admin.models.builtinTools.channels.label'), - description: $i18n.t('settings.admin.models.builtinTools.channels.description') + description: $i18n.t('settings.admin.models.builtinTools.channels.description'), + enabled: $config?.features?.enable_channels }, notifications: { label: $i18n.t('settings.admin.models.builtinTools.notifications.label'), - description: $i18n.t('settings.admin.models.builtinTools.notifications.description') + description: $i18n.t('settings.admin.models.builtinTools.notifications.description'), + enabled: $config?.features?.enable_user_webhooks }, web_search: { label: $i18n.t('settings.admin.models.builtinTools.webSearch.label'), - description: $i18n.t('settings.admin.models.builtinTools.webSearch.description') + description: $i18n.t('settings.admin.models.builtinTools.webSearch.description'), + enabled: $config?.features?.enable_web_search }, image_generation: { label: $i18n.t('settings.admin.models.builtinTools.imageGeneration.label'), - description: $i18n.t('settings.admin.models.builtinTools.imageGeneration.description') + description: $i18n.t('settings.admin.models.builtinTools.imageGeneration.description'), + enabled: $config?.features?.enable_image_generation }, code_interpreter: { label: $i18n.t('settings.admin.models.builtinTools.codeInterpreter.label'), - description: $i18n.t('settings.admin.models.builtinTools.codeInterpreter.description') + description: $i18n.t('settings.admin.models.builtinTools.codeInterpreter.description'), + enabled: $config?.features?.enable_code_interpreter }, tasks: { label: $i18n.t('settings.admin.models.builtinTools.tasks.label'), @@ -63,15 +71,18 @@ }, automations: { label: $i18n.t('settings.admin.models.builtinTools.automations.label'), - description: $i18n.t('settings.admin.models.builtinTools.automations.description') + description: $i18n.t('settings.admin.models.builtinTools.automations.description'), + enabled: $config?.features?.enable_automations }, calendar: { label: $i18n.t('settings.admin.models.builtinTools.calendar.label'), - description: $i18n.t('settings.admin.models.builtinTools.calendar.description') + description: $i18n.t('settings.admin.models.builtinTools.calendar.description'), + enabled: $config?.features?.enable_calendar }, subagents: { label: $i18n.t('settings.admin.models.builtinTools.subagents.label'), - description: $i18n.t('settings.admin.models.builtinTools.subagents.description') + description: $i18n.t('settings.admin.models.builtinTools.subagents.description'), + enabled: $config?.features?.enable_subagents }, skills: { label: $i18n.t('settings.admin.models.builtinTools.skills.label'), @@ -80,10 +91,12 @@ }; // with File Context on, attached files go into the prompt instead - $: allTools = (Object.keys(toolLabels ?? {}) as Array).filter((key) => - key === 'files' - ? (capabilities.file_upload ?? true) && !(capabilities.file_context ?? true) - : (capabilities[key] ?? true) + $: allTools = (Object.keys(toolLabels ?? {}) as Array).filter( + (key) => + (toolLabels[key].enabled ?? true) && + (key === 'files' + ? (capabilities.file_upload ?? true) && !(capabilities.file_context ?? true) + : (capabilities[key] ?? true)) ); export let builtinTools: Record = {}; diff --git a/src/lib/stores/index.ts b/src/lib/stores/index.ts index 33358f551d..69d93b740b 100644 --- a/src/lib/stores/index.ts +++ b/src/lib/stores/index.ts @@ -389,6 +389,12 @@ type Config = { enable_tool_permissions?: boolean; enable_community_sharing: boolean; enable_memories: boolean; + enable_notes?: boolean; + enable_channels?: boolean; + enable_user_webhooks?: boolean; + enable_automations?: boolean; + enable_calendar?: boolean; + enable_subagents?: boolean; enable_plugins?: boolean; enable_tools?: boolean; enable_functions?: boolean;