Merge pull request #5313 from RaresKeY/fix/chat-web-search-explicit-deny

fix(chat): require explicit web search enable
This commit is contained in:
Boody
2026-07-09 01:56:32 +03:00
committed by GitHub
5 changed files with 266 additions and 69 deletions
+10 -11
View File
@@ -24,7 +24,7 @@ from src.model_context import estimate_tokens
from src.settings import get_setting
from src.prompt_security import untrusted_context_message
from src.tool_security import blocked_tools_for_owner, plan_mode_disabled_tools
from src.tool_policy import GUIDE_ONLY_DIRECTIVE, ToolPolicy
from src.tool_policy import GUIDE_ONLY_DIRECTIVE, WEB_TOOL_NAMES, ToolPolicy
from src.tool_utils import _truncate, get_mcp_manager
from src.agent_tools import (
parse_tool_blocks,
@@ -321,7 +321,7 @@ _DOMAIN_RULES = {
}
_DOMAIN_TOOL_MAP = {
"web": {"web_search", "web_fetch"},
"web": set(WEB_TOOL_NAMES),
"documents": {"create_document", "edit_document", "update_document", "suggest_document", "manage_documents"},
"email": {"list_email_accounts", "list_emails", "read_email", "send_email", "reply_to_email", "bulk_email", "archive_email", "delete_email", "mark_email_read", "resolve_contact", "manage_contact"},
"cookbook": {"download_model", "serve_model", "serve_preset", "list_serve_presets", "list_served_models", "stop_served_model", "tail_serve_output", "list_downloads", "cancel_download", "search_hf_models", "list_cached_models", "list_cookbook_servers", "adopt_served_model"},
@@ -2847,13 +2847,12 @@ async def stream_agent_loop(
if "email" in (_intent.get("domains") or set()):
_relevant_tools.add("ui_control")
if "web" in (_intent.get("domains") or set()):
_relevant_tools.update({"web_search", "web_fetch"})
_removed_web_blocks = sorted({"web_search", "web_fetch"} & disabled_tools)
if _removed_web_blocks:
disabled_tools.difference_update({"web_search", "web_fetch"})
_relevant_tools.update(WEB_TOOL_NAMES)
_blocked_web_tools = sorted(WEB_TOOL_NAMES & disabled_tools)
if _blocked_web_tools:
logger.info(
"[agent-intent] web turn forced search tools enabled; removed disabled=%s",
_removed_web_blocks,
"[agent-intent] web domain selected but search tools remain disabled=%s",
_blocked_web_tools,
)
if "ui" in (_intent.get("domains") or set()):
_relevant_tools.add("ui_control")
@@ -2887,9 +2886,9 @@ async def stream_agent_loop(
_relevant_tools = set(ALWAYS_AVAILABLE)
_relevant_tools.update({"read_file", "grep", "ls", "manage_documents"})
# Per-request forced tools are stronger than retrieval. Search toggles and
# explicit lookup turns must make web tools visible even when tool RAG
# misses them; route-level disabled_tools decides what else is allowed.
# Per-request forced tools are stronger than retrieval. Explicit search
# settings make web tools visible even when tool RAG misses them;
# route-level disabled_tools decides what remains allowed.
if not guide_only and forced_tools:
forced_set = {t for t in forced_tools if t not in disabled_tools}
if _relevant_tools is None:
+33
View File
@@ -16,6 +16,39 @@ GUIDE_ONLY_DIRECTIVE = (
"output they will produce locally."
)
WEB_TOOL_NAMES = frozenset({"web_search", "web_fetch"})
def tool_toggle_enabled(value: object) -> bool:
"""Return true only for explicit true-like tool toggle values."""
return str(value).lower() == "true"
def tool_toggle_explicitly_denied(value: object) -> bool:
"""Return true when a caller explicitly supplied a non-true toggle value."""
return value is not None and not tool_toggle_enabled(value)
def is_web_search_explicitly_denied(allow_web_search: object) -> bool:
"""Whether the web-search agent toggle was explicitly set to false."""
return tool_toggle_explicitly_denied(allow_web_search)
def web_search_enabled_for_turn(allow_web_search: object, use_web: object = None) -> bool:
"""Return true only when this request explicitly enables web search.
Agent mode sends ``allow_web_search``; chat-mode pre-search sends
``use_web``. If both are present, an explicit ``allow_web_search=false``
wins so a stale or conflicting intent path cannot re-enable web tools.
"""
if is_web_search_explicitly_denied(allow_web_search):
return False
return tool_toggle_enabled(allow_web_search) or tool_toggle_enabled(use_web)
_COMMON_TOOL_NAMES = {
"api_call",