fix(tools): preserve sequential middleware trace

Signed-off-by: Alex Fournier <afournier@nvidia.com>
This commit is contained in:
Alex Fournier 2026-07-23 13:43:27 -07:00
parent 0be07b0553
commit a54e52aeb1
2 changed files with 53 additions and 0 deletions

View file

@ -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:

View file

@ -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(