From f3d34bab4d05b1312a66c13dff171f35084fc386 Mon Sep 17 00:00:00 2001 From: javis-bot Date: Sun, 14 Jun 2026 02:55:33 +0900 Subject: [PATCH] fix: always offer controlBrowser in screen-share so on-screen search works MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The small router reflexively routed every "search/open" intent to webSearch and never surfaced controlBrowser, so "네이버에서 X 검색해줘" did nothing on the broadcast. Union controlBrowser (+browseAndPlay) into the allow-list every turn in screen-share mode (like setBroadcast), and steer the model in the system prompt to prefer the on-screen browser over webSearch when available. Co-Authored-By: Claude Opus 4.7 --- src/jarvis/reply/engine.py | 10 ++++++++++ src/jarvis/system_prompt.py | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/jarvis/reply/engine.py b/src/jarvis/reply/engine.py index 65e6b62..2200635 100644 --- a/src/jarvis/reply/engine.py +++ b/src/jarvis/reply/engine.py @@ -1036,6 +1036,16 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any], and "setBroadcast" not in routed_tools: routed_tools = routed_tools + ["setBroadcast"] + # In screen-share mode, always offer the on-screen browser control too. The + # small router reflexively picks webSearch for any "search/open/find" intent + # and never surfaces controlBrowser, so the model never gets the option to + # actually drive the visible browser (e.g. "네이버에서 X 검색해줘"). Offer it + # every turn; it self-gates (no-op when nothing is asked of the browser). + if getattr(cfg, "stream_browser", True): + for _bt in ("controlBrowser", "browseAndPlay"): + if _bt in _full_catalog_names and _bt not in routed_tools: + routed_tools = routed_tools + [_bt] + _planner_schema = generate_tools_json_schema(routed_tools, mcp_tools) _planner_tool_catalog: list[tuple[str, str]] = [] for _schema in (_planner_schema or []): diff --git a/src/jarvis/system_prompt.py b/src/jarvis/system_prompt.py index 5565f2a..c68b8aa 100644 --- a/src/jarvis/system_prompt.py +++ b/src/jarvis/system_prompt.py @@ -38,6 +38,10 @@ _SYSTEM_PROMPT_TEMPLATE: str = ( "Be concise, conversational, and actionable. " "This is a spoken voice assistant: answer in ONE short sentence whenever possible " "(two at the very most). No lists, no preamble, no 'is there anything else' offers. " + "When a controlBrowser tool is available, use IT (never webSearch) for anything that " + "should happen in the on-screen browser — opening a site, searching on a site " + "(controlBrowser action 'search' with the right site), clicking, typing — because only " + "controlBrowser is visible on the broadcast; webSearch shows nothing on screen. " "Never claim you performed an action — opening a website, navigating the browser, " "playing or showing something on screen, changing a setting, sending a message — unless a " "tool actually did it this turn and reported success. If you have no tool for what was asked, "