From 5469a746aaa2fff5e0169cd7f334c80ef2c16df5 Mon Sep 17 00:00:00 2001 From: "2285166171@qq.com" <2285166171@qq.com> Date: Fri, 20 Mar 2026 10:26:09 +0800 Subject: [PATCH] fix(tools): prevent tool_runner from exiting when server_tool_use blocks are present When the API responds with server_tool_use blocks (e.g. web_search, web_fetch) and stop_reason='pause_turn', the tool runner's _generate_tool_call_response() only looks for type='tool_use' blocks. Since server tools have type='server_tool_use', it returns None and the runner exits prematurely. Detect server_tool_use blocks and return an empty user message to continue the loop, allowing the server to process and return results. Fixes #1170 --- src/anthropic/lib/tools/_beta_runner.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/anthropic/lib/tools/_beta_runner.py b/src/anthropic/lib/tools/_beta_runner.py index d2c55ea7..294c1a50 100644 --- a/src/anthropic/lib/tools/_beta_runner.py +++ b/src/anthropic/lib/tools/_beta_runner.py @@ -306,6 +306,13 @@ def _generate_tool_call_response(self) -> BetaMessageParam | None: tool_use_blocks = [block for block in content if block.type == "tool_use"] if not tool_use_blocks: + # When server-side tools (e.g. web_search, web_fetch) are present, + # the API responds with server_tool_use blocks and stop_reason="pause_turn". + # The runner should continue the loop so the server can return results. + has_server_tools = any(block.type == "server_tool_use" for block in content) + if has_server_tools: + log.debug("Server tool use detected, continuing runner loop.") + return {"role": "user", "content": []} return None results: list[BetaToolResultBlockParam] = [] @@ -598,6 +605,10 @@ async def _generate_tool_call_response(self) -> BetaMessageParam | None: tool_use_blocks = [block for block in content if block.type == "tool_use"] if not tool_use_blocks: + has_server_tools = any(block.type == "server_tool_use" for block in content) + if has_server_tools: + log.debug("Server tool use detected, continuing runner loop (async).") + return {"role": "user", "content": []} return None results: list[BetaToolResultBlockParam] = []