diff --git a/python/packages/core/agent_framework/_harness/_tool_approval.py b/python/packages/core/agent_framework/_harness/_tool_approval.py index 7c6df089c9d..2232093ea3f 100644 --- a/python/packages/core/agent_framework/_harness/_tool_approval.py +++ b/python/packages/core/agent_framework/_harness/_tool_approval.py @@ -130,10 +130,9 @@ def __init__( server_label: Optional hosted-tool server boundary. Hosted approvals only match future approvals from the same server label. """ - normalized_name = tool_name.strip() - if not normalized_name: + if not tool_name.strip(): raise ValueError("Tool approval rule tool_name must be a non-empty string.") - self.tool_name = normalized_name + self.tool_name = tool_name self.arguments = dict(arguments) if arguments is not None else None self.server_label = server_label diff --git a/python/packages/core/tests/core/test_harness_tool_approval.py b/python/packages/core/tests/core/test_harness_tool_approval.py index 24db9cad0b5..a0d1c54bfa0 100644 --- a/python/packages/core/tests/core/test_harness_tool_approval.py +++ b/python/packages/core/tests/core/test_harness_tool_approval.py @@ -37,6 +37,7 @@ SessionContext, SupportsAgentRun, ToolApprovalMiddleware, + ToolApprovalRule, ToolApprovalState, create_always_approve_tool_response, create_always_approve_tool_with_arguments_response, @@ -66,6 +67,14 @@ def _function_call(request: Content) -> Content: return request.function_call +def test_tool_approval_rule_preserves_tool_name_whitespace() -> None: + """Tool approval rules must preserve the exact approved tool identity.""" + rule = ToolApprovalRule("run_shell ") + + assert rule.tool_name == "run_shell " + assert ToolApprovalRule.from_dict(rule.to_dict()).tool_name == "run_shell " + + class _MarkUntrusted(FunctionMiddleware): async def process( self,