From e42d260744c618d9954f0f2f3aaf1290f4d80131 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 04:06:28 +0000 Subject: [PATCH] Add regression test for server_tool_use + input_json_delta skip behavior Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/7c68dcb2-b577-4e36-b423-664b8fe3ac1d Co-authored-by: chetantoshniwal <255221507+chetantoshniwal@users.noreply.github.com> --- .../anthropic/tests/test_anthropic_client.py | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/python/packages/anthropic/tests/test_anthropic_client.py b/python/packages/anthropic/tests/test_anthropic_client.py index 258cc275ca..d497409441 100644 --- a/python/packages/anthropic/tests/test_anthropic_client.py +++ b/python/packages/anthropic/tests/test_anthropic_client.py @@ -1123,6 +1123,53 @@ def test_parse_contents_from_anthropic_input_json_delta_no_duplicate_name( assert result[0].arguments == '"San Francisco"}' +def test_parse_contents_server_tool_use_input_json_delta_ignored( + mock_anthropic_client: MagicMock, +) -> None: + """Regression test: input_json_delta events are ignored after a server_tool_use block. + + Server-managed tools have their execution handled server-side, so streaming + input_json_delta events must not produce Content.from_function_call(name='') + entries that would cause Anthropic API 400 errors on subsequent turns. + """ + client = create_test_anthropic_client(mock_anthropic_client) + + # Simulate a server_tool_use event that sets _last_call_content_type + server_tool_content = MagicMock() + server_tool_content.type = "server_tool_use" + server_tool_content.id = "srvtool_abc" + server_tool_content.name = "web_search" + server_tool_content.input = {} + + result = client._parse_contents_from_anthropic([server_tool_content]) + # server_tool_use falls through to function_call (not mcp_tool_use / code_execution) + assert len(result) == 1 + assert result[0].type == "function_call" + assert client._last_call_content_type == "server_tool_use" # type: ignore[attr-defined] + + # input_json_delta events after server_tool_use must be silently ignored + delta_content = MagicMock() + delta_content.type = "input_json_delta" + delta_content.partial_json = '{"query": "latest news"}' + + result = client._parse_contents_from_anthropic([delta_content]) + assert result == [], ( + "input_json_delta after server_tool_use should produce no content, " + "but got: %r" % result + ) + + # A second delta must also be ignored + delta_content_2 = MagicMock() + delta_content_2.type = "input_json_delta" + delta_content_2.partial_json = '{"extra": true}' + + result = client._parse_contents_from_anthropic([delta_content_2]) + assert result == [], ( + "subsequent input_json_delta after server_tool_use should also be ignored, " + "but got: %r" % result + ) + + # Stream Processing Tests