Skip to content

Commit e7d95d6

Browse files
JackYPCOnlineJack Yuan
andauthored
fix: fix loading tools with same tool name (#772)
* fix: fix loading tools with same tool name * simplify if condition --------- Co-authored-by: Jack Yuan <[email protected]>
1 parent cb4b7fb commit e7d95d6

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

src/strands/tools/registry.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,13 @@ def register_tool(self, tool: AgentTool) -> None:
190190
tool.is_dynamic,
191191
)
192192

193+
# Check duplicate tool name, throw on duplicate tool names except if hot_reloading is enabled
194+
if tool.tool_name in self.registry and not tool.supports_hot_reload:
195+
raise ValueError(
196+
f"Tool name '{tool.tool_name}' already exists. Cannot register tools with exact same name."
197+
)
198+
199+
# Check for normalized name conflicts (- vs _)
193200
if self.registry.get(tool.tool_name) is None:
194201
normalized_name = tool.tool_name.replace("-", "_")
195202

tests/strands/tools/test_registry.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,39 @@ def function() -> str:
120120
"tool_f",
121121
]
122122
assert tru_tool_names == exp_tool_names
123+
124+
125+
def test_register_tool_duplicate_name_without_hot_reload():
126+
"""Test that registering a tool with duplicate name raises ValueError when hot reload is not supported."""
127+
tool_1 = PythonAgentTool(tool_name="duplicate_tool", tool_spec=MagicMock(), tool_func=lambda: None)
128+
tool_2 = PythonAgentTool(tool_name="duplicate_tool", tool_spec=MagicMock(), tool_func=lambda: None)
129+
130+
tool_registry = ToolRegistry()
131+
tool_registry.register_tool(tool_1)
132+
133+
with pytest.raises(
134+
ValueError, match="Tool name 'duplicate_tool' already exists. Cannot register tools with exact same name."
135+
):
136+
tool_registry.register_tool(tool_2)
137+
138+
139+
def test_register_tool_duplicate_name_with_hot_reload():
140+
"""Test that registering a tool with duplicate name succeeds when hot reload is supported."""
141+
# Create mock tools with hot reload support
142+
tool_1 = MagicMock(spec=PythonAgentTool)
143+
tool_1.tool_name = "hot_reload_tool"
144+
tool_1.supports_hot_reload = True
145+
tool_1.is_dynamic = False
146+
147+
tool_2 = MagicMock(spec=PythonAgentTool)
148+
tool_2.tool_name = "hot_reload_tool"
149+
tool_2.supports_hot_reload = True
150+
tool_2.is_dynamic = False
151+
152+
tool_registry = ToolRegistry()
153+
tool_registry.register_tool(tool_1)
154+
155+
tool_registry.register_tool(tool_2)
156+
157+
# Verify the second tool replaced the first
158+
assert tool_registry.registry["hot_reload_tool"] == tool_2

0 commit comments

Comments
 (0)