diff --git a/agent/tool_executor.py b/agent/tool_executor.py index f5886e39add6..16b9f0f4dd58 100644 --- a/agent/tool_executor.py +++ b/agent/tool_executor.py @@ -1640,6 +1640,7 @@ def execute_tool_calls_sequential(agent, assistant_message, messages: list, effe skip_pre_tool_call_hook=True, skip_tool_request_middleware=True, skip_tool_execution_middleware=True, + tool_request_middleware_trace=list(middleware_trace), enabled_toolsets=getattr(agent, "enabled_toolsets", None), disabled_toolsets=getattr(agent, "disabled_toolsets", None), ) @@ -1659,6 +1660,7 @@ def execute_tool_calls_sequential(agent, assistant_message, messages: list, effe execute=_execute, scope_block=_ts_scope_block, display_index=i, + middleware_trace=middleware_trace, ) ) _spinner_result = function_result @@ -1708,6 +1710,7 @@ def execute_tool_calls_sequential(agent, assistant_message, messages: list, effe skip_pre_tool_call_hook=True, skip_tool_request_middleware=True, skip_tool_execution_middleware=True, + tool_request_middleware_trace=list(middleware_trace), enabled_toolsets=getattr(agent, "enabled_toolsets", None), disabled_toolsets=getattr(agent, "disabled_toolsets", None), ) @@ -1727,6 +1730,7 @@ def execute_tool_calls_sequential(agent, assistant_message, messages: list, effe execute=_execute, scope_block=_ts_scope_block, display_index=i, + middleware_trace=middleware_trace, ) ) except KeyboardInterrupt: diff --git a/tests/run_agent/test_run_agent.py b/tests/run_agent/test_run_agent.py index 6a024a6bd534..6e017a141266 100644 --- a/tests/run_agent/test_run_agent.py +++ b/tests/run_agent/test_run_agent.py @@ -3165,6 +3165,55 @@ class TestConcurrentToolExecution: assert starts == [("c1", "web_search", {"query": "hello"})] assert completes == [("c1", "web_search", {"query": "hello"}, '{"success": true}')] + @pytest.mark.parametrize("quiet_mode", [True, False]) + def test_sequential_registry_tool_forwards_request_middleware_trace( + self, + agent, + monkeypatch, + quiet_mode, + ): + from hermes_cli.middleware import RequestMiddlewareResult + + trace = [{"source": "test-middleware"}] + observed = [] + agent.quiet_mode = quiet_mode + tool_call = _mock_tool_call( + name="web_search", + arguments='{"query":"hello"}', + call_id="c1", + ) + mock_msg = _mock_assistant_msg(content="", tool_calls=[tool_call]) + monkeypatch.setattr( + "hermes_cli.middleware.apply_tool_request_middleware", + lambda _name, args, **_kwargs: RequestMiddlewareResult( + payload=args, + original_payload=args, + changed=True, + trace=trace, + ), + ) + monkeypatch.setattr( + "hermes_cli.middleware.run_tool_execution_middleware", + lambda _name, args, callback, **_kwargs: callback(args), + ) + monkeypatch.setattr( + "hermes_cli.plugins.resolve_pre_tool_block", + lambda *_args, **_kwargs: None, + ) + monkeypatch.setattr( + "agent.tool_executor._begin_tool_execution", + lambda *_args, **_kwargs: None, + ) + + def handle_function_call(*_args, **kwargs): + observed.append(kwargs) + return '{"success": true}' + + with patch("run_agent.handle_function_call", side_effect=handle_function_call): + agent._execute_tool_calls_sequential(mock_msg, [], "task-1") + + assert observed[0]["tool_request_middleware_trace"] == trace + def test_sequential_browser_type_callbacks_redact_api_key(self, agent): secret = "sk-proj-ABCD1234567890EFGH" tool_call = _mock_tool_call(