diff --git a/backend/open_webui/utils/models.py b/backend/open_webui/utils/models.py index f27a2c761..86ba292c5 100644 --- a/backend/open_webui/utils/models.py +++ b/backend/open_webui/utils/models.py @@ -286,11 +286,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) } ] - def get_function_module_by_id(function_id): - function_module, _, _ = get_function_module_from_cache(request, function_id) - return function_module - - # Batch-prefetch all needed function IDs to avoid N+1 queries + # Batch-prefetch all needed function records to avoid N+1 queries all_function_ids = set() for model in models: all_function_ids.update(model.get("action_ids", [])) @@ -302,6 +298,12 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) f.id: f for f in Functions.get_functions_by_ids(list(all_function_ids)) } + # Pre-warm the function module cache once per unique function ID. + # This ensures each function's DB freshness check runs exactly once, + # not once per (model × function) pair. + for function_id in all_function_ids: + get_function_module_from_cache(request, function_id) + for model in models: action_ids = [ action_id @@ -320,7 +322,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) if action_function is None: raise Exception(f"Action not found: {action_id}") - function_module = get_function_module_by_id(action_id) + function_module = request.app.state.FUNCTIONS.get(action_id) model["actions"].extend( get_action_items_from_module(action_function, function_module) ) @@ -331,7 +333,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None) if filter_function is None: raise Exception(f"Filter not found: {filter_id}") - function_module = get_function_module_by_id(filter_id) + function_module = request.app.state.FUNCTIONS.get(filter_id) if getattr(function_module, "toggle", None): model["filters"].extend(