This commit is contained in:
Timothy Jaeryang Baek
2026-06-17 02:52:35 +02:00
parent e8d55c0a8b
commit 5cdcdbaeec
53 changed files with 7829 additions and 7954 deletions
+24 -13
View File
@@ -42,6 +42,7 @@ from open_webui.env import (
REDIS_KEY_PREFIX,
)
from open_webui.models.access_grants import AccessGrants
from open_webui.models.config import Config
from open_webui.models.groups import Groups
from open_webui.models.tools import Tools
from open_webui.models.users import UserModel
@@ -345,7 +346,7 @@ async def get_tools(request: Request, tool_ids: list[str], user: UserModel, extr
continue
tool_server_idx = tool_server_data.get('idx', 0)
connections = request.app.state.config.TOOL_SERVER_CONNECTIONS
connections = await Config.get('tool_server.connections', [])
if tool_server_idx >= len(connections):
log.warning(
f'Tool server index {tool_server_idx} out of range '
@@ -451,6 +452,16 @@ async def get_builtin_tools(
# Helper to check user-level feature permission (admins always pass)
user = extra_params.get('__user__', {})
config = await Config.get_many(
'rag.web.search.enable',
'image_generation.enable',
'images.edit.enable',
'code_interpreter.enable',
'notes.enable',
'channels.enable',
'automations.enable',
'calendar.enable',
)
async def has_user_permission(feature_key: str) -> bool:
if user.get('role') == 'admin':
@@ -458,7 +469,7 @@ async def get_builtin_tools(
return await has_permission(
user.get('id', ''),
f'features.{feature_key}',
request.app.state.config.USER_PERMISSIONS,
await Config.get('user.permissions'),
)
# Time utilities - available for date calculations
@@ -533,7 +544,7 @@ async def get_builtin_tools(
# Add web search tools if builtin category enabled AND enabled globally AND model has web_search capability
if (
is_builtin_tool_enabled('web_search')
and getattr(request.app.state.config, 'ENABLE_WEB_SEARCH', False)
and config.get('rag.web.search.enable')
and get_model_capability('web_search')
and features.get('web_search')
and await has_user_permission('web_search')
@@ -543,7 +554,7 @@ async def get_builtin_tools(
# Add image generation/edit tools if builtin category enabled AND enabled globally AND model has image_generation capability
if (
is_builtin_tool_enabled('image_generation')
and getattr(request.app.state.config, 'ENABLE_IMAGE_GENERATION', False)
and config.get('image_generation.enable')
and get_model_capability('image_generation')
and features.get('image_generation')
and await has_user_permission('image_generation')
@@ -551,7 +562,7 @@ async def get_builtin_tools(
builtin_functions.append(generate_image)
if (
is_builtin_tool_enabled('image_generation')
and getattr(request.app.state.config, 'ENABLE_IMAGE_EDIT', False)
and config.get('images.edit.enable')
and get_model_capability('image_generation')
and features.get('image_generation')
and await has_user_permission('image_generation')
@@ -561,7 +572,7 @@ async def get_builtin_tools(
# Add code interpreter tool if builtin category enabled AND enabled globally AND model has code_interpreter capability
if (
is_builtin_tool_enabled('code_interpreter')
and getattr(request.app.state.config, 'ENABLE_CODE_INTERPRETER', True)
and config.get('code_interpreter.enable')
and get_model_capability('code_interpreter')
and features.get('code_interpreter')
and await has_user_permission('code_interpreter')
@@ -571,7 +582,7 @@ async def get_builtin_tools(
# Notes tools - search, view, create, and update user's notes
if (
is_builtin_tool_enabled('notes')
and getattr(request.app.state.config, 'ENABLE_NOTES', False)
and config.get('notes.enable')
and await has_user_permission('notes')
):
builtin_functions.extend([search_notes, view_note, write_note, replace_note_content])
@@ -579,7 +590,7 @@ async def get_builtin_tools(
# Channels tools - search channels and messages
if (
is_builtin_tool_enabled('channels')
and getattr(request.app.state.config, 'ENABLE_CHANNELS', False)
and config.get('channels.enable')
and await has_user_permission('channels')
):
builtin_functions.extend(
@@ -602,7 +613,7 @@ async def get_builtin_tools(
# Automation tools - create and manage scheduled automations from chat
if (
is_builtin_tool_enabled('automations')
and getattr(request.app.state.config, 'ENABLE_AUTOMATIONS', False)
and config.get('automations.enable')
and await has_user_permission('automations')
):
builtin_functions.extend(
@@ -612,7 +623,7 @@ async def get_builtin_tools(
# Calendar tools - search/create/update/delete events
if (
is_builtin_tool_enabled('calendar')
and getattr(request.app.state.config, 'ENABLE_CALENDAR', False)
and config.get('calendar.enable')
and await has_user_permission('calendar')
):
builtin_functions.extend(
@@ -958,7 +969,7 @@ def convert_openapi_to_tool_payload(openapi_spec):
async def set_tool_servers(request: Request):
try:
request.app.state.TOOL_SERVERS = await get_tool_servers_data(request.app.state.config.TOOL_SERVER_CONNECTIONS)
request.app.state.TOOL_SERVERS = await get_tool_servers_data(await Config.get('tool_server.connections', []))
except Exception as e:
log.error(f'Error fetching tool server data: {e}')
request.app.state.TOOL_SERVERS = getattr(request.app.state, 'TOOL_SERVERS', None) or []
@@ -1055,7 +1066,7 @@ async def get_terminal_system_prompt(
async def set_terminal_servers(request: Request):
"""Load and cache OpenAPI specs from all TERMINAL_SERVER_CONNECTIONS."""
connections = request.app.state.config.TERMINAL_SERVER_CONNECTIONS or []
connections = await Config.get('terminal_server.connections', []) or []
# Build server configs compatible with get_tool_servers_data
# Terminal connections store id/name at top level; translate to info dict
@@ -1148,7 +1159,7 @@ async def get_terminal_tools(
- Loads specs from cache
- Builds callables that route through the terminal proxy
"""
connections = request.app.state.config.TERMINAL_SERVER_CONNECTIONS or []
connections = await Config.get('terminal_server.connections', []) or []
connection = next((c for c in connections if c.get('id') == terminal_id), None)
if connection is None:
log.warning(f'Terminal server not found: {terminal_id}')