From f0c7bd3f790e299f4bf9dbeae37c300ed1a85e7e Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 25 Nov 2025 03:12:21 -0500 Subject: [PATCH 01/27] refac --- backend/open_webui/utils/middleware.py | 11 ++++++----- backend/open_webui/utils/misc.py | 6 ++++-- backend/open_webui/utils/tools.py | 10 +++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 323f93f450..efa187a382 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -1409,9 +1409,12 @@ async def process_chat_payload(request, form_data, user, metadata, model): headers=headers if headers else None, ) - function_name_filter_list = mcp_server_connection.get( - "function_name_filter_list", None + function_name_filter_list = ( + mcp_server_connection.get("config", {}) + .get("function_name_filter_list", "") + .split(",") ) + tool_specs = await mcp_clients[server_id].list_tool_specs() for tool_spec in tool_specs: @@ -1424,9 +1427,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): return tool_function - if function_name_filter_list and isinstance( - function_name_filter_list, list - ): + if function_name_filter_list: if not is_string_allowed( tool_spec["name"], function_name_filter_list ): diff --git a/backend/open_webui/utils/misc.py b/backend/open_webui/utils/misc.py index 466e235598..5591fcdb3f 100644 --- a/backend/open_webui/utils/misc.py +++ b/backend/open_webui/utils/misc.py @@ -35,10 +35,10 @@ def get_allow_block_lists(filter_list): for d in filter_list: if d.startswith("!"): # Domains starting with "!" → blocked - block_list.append(d[1:]) + block_list.append(d[1:].strip()) else: # Domains starting without "!" → allowed - allow_list.append(d) + allow_list.append(d.strip()) return allow_list, block_list @@ -54,6 +54,8 @@ def is_string_allowed(string: str, filter_list: Optional[list[str]] = None) -> b return True allow_list, block_list = get_allow_block_lists(filter_list) + print(string, allow_list, block_list) + # If allow list is non-empty, require domain to match one of them if allow_list: if not any(string.endswith(allowed) for allowed in allow_list): diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index ecdf7187e4..268624135d 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -150,15 +150,15 @@ async def get_tools( ) specs = tool_server_data.get("specs", []) - function_name_filter_list = tool_server_connection.get( - "function_name_filter_list", None + function_name_filter_list = ( + tool_server_connection.get("config", {}) + .get("function_name_filter_list", "") + .split(",") ) for spec in specs: function_name = spec["name"] - if function_name_filter_list and isinstance( - function_name_filter_list, list - ): + if function_name_filter_list: if not is_string_allowed( function_name, function_name_filter_list ): From a7ee36266a3060e462575c1de5506c67793d1f58 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 25 Nov 2025 03:15:40 -0500 Subject: [PATCH 02/27] refac: styling --- src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte index 133eb60750..4088b39061 100644 --- a/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte +++ b/src/lib/components/chat/Messages/Markdown/MarkdownTokens.svelte @@ -112,7 +112,7 @@ {save} {preview} edit={editCodeBlock} - stickyButtonsClassName={topPadding ? 'top-7' : 'top-0'} + stickyButtonsClassName={topPadding ? 'top-10' : 'top-0'} onSave={(value) => { onSave({ raw: token.raw, From 3b5710d0cd445cf86423187f5ee7c40472a0df0b Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Tue, 25 Nov 2025 03:46:30 -0500 Subject: [PATCH 03/27] feat/enh: show user count in channels --- backend/open_webui/models/channels.py | 1 + backend/open_webui/routers/channels.py | 3 ++ src/lib/components/channel/Navbar.svelte | 43 +++++++++++++++++++++--- src/lib/components/icons/UserAlt.svelte | 23 +++++++++++++ 4 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 src/lib/components/icons/UserAlt.svelte diff --git a/backend/open_webui/models/channels.py b/backend/open_webui/models/channels.py index 2a14e7a2d5..5f4d1436d9 100644 --- a/backend/open_webui/models/channels.py +++ b/backend/open_webui/models/channels.py @@ -59,6 +59,7 @@ class ChannelModel(BaseModel): class ChannelResponse(ChannelModel): write_access: bool = False + user_count: Optional[int] = None class ChannelForm(BaseModel): diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py index fda0879594..bd688bf5d9 100644 --- a/backend/open_webui/routers/channels.py +++ b/backend/open_webui/routers/channels.py @@ -105,10 +105,13 @@ async def get_channel_by_id(id: str, user=Depends(get_verified_user)): user.id, type="write", access_control=channel.access_control, strict=False ) + user_count = len(get_users_with_access("read", channel.access_control)) + return ChannelResponse( **{ **channel.model_dump(), "write_access": write_access or user.role == "admin", + "user_count": user_count, } ) diff --git a/src/lib/components/channel/Navbar.svelte b/src/lib/components/channel/Navbar.svelte index 92693b4de2..57c452132f 100644 --- a/src/lib/components/channel/Navbar.svelte +++ b/src/lib/components/channel/Navbar.svelte @@ -7,18 +7,22 @@ import { slide } from 'svelte/transition'; import { page } from '$app/stores'; + import { WEBUI_API_BASE_URL } from '$lib/constants'; + import UserMenu from '$lib/components/layout/Sidebar/UserMenu.svelte'; import PencilSquare from '../icons/PencilSquare.svelte'; import Tooltip from '../common/Tooltip.svelte'; import Sidebar from '../icons/Sidebar.svelte'; - import { WEBUI_API_BASE_URL } from '$lib/constants'; + import Hashtag from '../icons/Hashtag.svelte'; + import Lock from '../icons/Lock.svelte'; + import UserAlt from '../icons/UserAlt.svelte'; const i18n = getContext('i18n'); export let channel; -