From 507b8b213cc6f4fbaa8e4dd71899681f4170f369 Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 1 Jun 2026 21:07:15 +0200 Subject: [PATCH] refac: mirror native FC code_interpreter authz gates onto legacy XML-tag path (#24724) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The native function-calling tool resolver in utils/tools.py applies five gates before exposing execute_code as a builtin tool: builtin-category enable, ENABLE_CODE_INTERPRETER global config, model capability, features.code_interpreter request flag, and the per-user features.code_interpreter permission. The legacy XML-tag detection path in streaming_chat_response_handler applied only the request-flag gate. Brings the legacy path to parity by running the same five-gate check before activating tag detection. Behaviour change is limited to deployments that previously relied on the asymmetry — admins who set ENABLE_CODE_INTERPRETER=False or revoked the per-user permission, on the legacy tool-calling mode, with the client supplying features.code_interpreter=true. Any of those three conditions met now correctly disables tag detection. Co-authored-by: sfwani --- backend/open_webui/utils/middleware.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index cbe5404867..a86f6c791c 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -72,7 +72,7 @@ from open_webui.socket.main import ( get_event_call, get_event_emitter, ) -from open_webui.utils.access_control import has_connection_access +from open_webui.utils.access_control import has_connection_access, has_permission from open_webui.utils.access_control.files import get_accessible_folder_files from open_webui.utils.chat import generate_chat_completion from open_webui.utils.code_interpreter import execute_code_jupyter @@ -3853,7 +3853,26 @@ async def streaming_chat_response_handler(response, ctx): reasoning_tags_param = metadata.get('params', {}).get('reasoning_tags') DETECT_REASONING_TAGS = reasoning_tags_param is not False - DETECT_CODE_INTERPRETER = metadata.get('features', {}).get('code_interpreter', False) + + # Mirror the five gates from utils/tools.py get_builtin_tools so the + # legacy XML-tag path enforces the same authz as native FC. + features = metadata.get('features', {}) or {} + model_capabilities = (model.get('info', {}).get('meta', {}).get('capabilities') or {}) + builtin_tools_meta = model.get('info', {}).get('meta', {}).get('builtinTools', {}) + DETECT_CODE_INTERPRETER = ( + bool(features.get('code_interpreter')) + and builtin_tools_meta.get('code_interpreter', True) + and getattr(request.app.state.config, 'ENABLE_CODE_INTERPRETER', True) + and model_capabilities.get('code_interpreter', True) + and ( + getattr(user, 'role', None) == 'admin' + or await has_permission( + getattr(user, 'id', ''), + 'features.code_interpreter', + request.app.state.config.USER_PERMISSIONS, + ) + ) + ) reasoning_tags = [] if DETECT_REASONING_TAGS: