From 69ff657bd867f973e197034e0076d8433b27bb34 Mon Sep 17 00:00:00 2001 From: Ninthkitten <165195091+Ninthkitten@users.noreply.github.com> Date: Thu, 16 Jul 2026 23:47:33 +0200 Subject: [PATCH] fix(research): gate trigger_research behind the web-search toggle With web search toggled off, a research request still launched a full deep-research run: the toggle only disabled web_search/web_fetch, and trigger_research was not counted as a web tool. Gate it with the same switch. Fixes #5527. Co-Authored-By: Claude Fable 5 --- routes/chat_routes.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/routes/chat_routes.py b/routes/chat_routes.py index b8d9934b4c..b0ebf9d0fb 100644 --- a/routes/chat_routes.py +++ b/routes/chat_routes.py @@ -880,8 +880,11 @@ async def chat_stream(request: Request) -> StreamingResponse: if allow_bash is not None and str(allow_bash).lower() != "true": disabled_tools.add("bash") _explicit_web_intent = bool(_tool_intent and _tool_intent.category == "web") + # trigger_research reaches the internet too, so gate it with the same + # per-turn web toggle as web_search/web_fetch — "web off" must mean offline. + _web_gated_tools = set(WEB_TOOL_NAMES) | {"trigger_research"} if is_web_search_explicitly_denied(allow_web_search) or not _search_enabled: - disabled_tools.update(WEB_TOOL_NAMES) + disabled_tools.update(_web_gated_tools) if _explicit_web_intent: # A direct lookup/search request should not drift into personal # tools or shell fallbacks. It can only use web_search/web_fetch @@ -896,11 +899,11 @@ async def chat_stream(request: Request) -> StreamingResponse: "api_call", "builtin_browser", }) if _search_enabled: - disabled_tools.difference_update(WEB_TOOL_NAMES) + disabled_tools.difference_update(_web_gated_tools) else: - disabled_tools.update(WEB_TOOL_NAMES) + disabled_tools.update(_web_gated_tools) elif _search_enabled: - disabled_tools.difference_update(WEB_TOOL_NAMES) + disabled_tools.difference_update(_web_gated_tools) # Nobody/incognito mode: deny tools that would expose the user's # persistent memory, past chats, or other identity-linked data.