File tree Expand file tree Collapse file tree 5 files changed +38
-31
lines changed Expand file tree Collapse file tree 5 files changed +38
-31
lines changed Original file line number Diff line number Diff line change @@ -108,14 +108,10 @@ def find_normalized_tool_name() -> Optional[str]:
108
108
# all tools that can be represented with the normalized name
109
109
if "_" in name :
110
110
filtered_tools = [
111
- tool_name
112
- for (tool_name , tool ) in tool_registry .items ()
113
- if tool_name .replace ("-" , "_" ) == name
111
+ tool_name for (tool_name , tool ) in tool_registry .items () if tool_name .replace ("-" , "_" ) == name
114
112
]
115
113
116
- if len (filtered_tools ) > 1 :
117
- raise AttributeError (f"Multiple tools matching '{ name } ' found: { ', ' .join (filtered_tools )} " )
118
-
114
+ # The registry itself defends against similar names, so we can just take the first match
119
115
if filtered_tools :
120
116
return filtered_tools [0 ]
121
117
Original file line number Diff line number Diff line change 13
13
14
14
from opentelemetry import trace
15
15
from opentelemetry .exporter .otlp .proto .http .trace_exporter import OTLPSpanExporter
16
-
17
- # See https://github.com/open-telemetry/opentelemetry-python/issues/4615 for the type ignore
18
- from opentelemetry .sdk .resources import Resource # type: ignore[attr-defined]
16
+ from opentelemetry .sdk .resources import Resource
19
17
from opentelemetry .sdk .trace import TracerProvider
20
18
from opentelemetry .sdk .trace .export import BatchSpanProcessor , ConsoleSpanExporter , SimpleSpanProcessor
21
19
from opentelemetry .trace import StatusCode
Original file line number Diff line number Diff line change @@ -189,6 +189,21 @@ def register_tool(self, tool: AgentTool) -> None:
189
189
tool .is_dynamic ,
190
190
)
191
191
192
+ if self .registry .get (tool .tool_name ) is None :
193
+ normalized_name = tool .tool_name .replace ("-" , "_" )
194
+
195
+ matching_tools = [
196
+ tool_name
197
+ for (tool_name , tool ) in self .registry .items ()
198
+ if tool_name .replace ("-" , "_" ) == normalized_name
199
+ ]
200
+
201
+ if matching_tools :
202
+ raise ValueError (
203
+ f"Tool name '{ tool .tool_name } ' alre
10000
ady exists as '{ matching_tools [0 ]} '."
204
+ " Cannot add a duplicate tool which differs by a '-' or '_'"
205
+ )
206
+
192
207
# Register in main registry
193
208
self .registry [tool .tool_name ] = tool
194
209
Original file line number Diff line number Diff line change @@ -739,28 +739,6 @@ def function(system_prompt: str) -> str:
739
739
}
740
740
741
741
742
- def test_agent_tool_with_multiple_normalized_matches (agent , tool_registry , mock_randint ):
743
- agent .tool_handler = unittest .mock .Mock ()
744
-
745
- @strands .tools .tool (name = "system-prompter_1" )
746
- def function1 (system_prompt : str ) -> str :
747
- return system_prompt
748
-
749
- @strands .tools .tool (name = "system-prompter-1" )
750
- def function2 (system_prompt : str ) -> str :
751
- return system_prompt
752
-
753
- agent .tool_registry .register_tool (strands .tools .tools .FunctionTool (function1 ))
754
- agent .tool_registry .register_tool (strands .tools .tools .FunctionTool (function2 ))
755
-
756
- mock_randint .return_value = 1
757
-
758
- with pytest .raises (AttributeError ) as err :
759
- agent .tool .system_prompter_1 (system_prompt = "tool prompt" )
760
-
761
- assert str (err .value ) == "Multiple tools matching 'system_prompter_1' found: system-prompter_1, system-prompter-1"
762
-
763
-
764
742
def test_agent_tool_with_no_normalized_match (agent , tool_registry , mock_randint ):
765
743
agent .tool_handler = unittest .mock .Mock ()
766
744
Original file line number Diff line number Diff line change 2
2
Tests for the SDK tool registry module.
3
3
"""
4
4
5
+ from unittest .mock import MagicMock
6
+
5
7
import pytest
6
8
9
+ from strands .tools import PythonAgentTool
7
10
from strands .tools .registry import ToolRegistry
8
11
9
12
@@ -23,3 +26,20 @@ def test_process_tools_with_invalid_path():
23
26
24
27
with pytest .raises (ValueError , match = f"Failed to load tool { invalid_path .split ('.' )[0 ]} : Tool file not found:.*" ):
25
28
tool_registry .process_tools ([invalid_path ])
29
+
30
+
31
+ def test_register_tool_with_similar_name_raises ():
32
+ tool_1 = PythonAgentTool (tool_name = "tool-like-this" , tool_spec = MagicMock (), callback = lambda : None )
33
+ tool_2 = PythonAgentTool (tool_name = "tool_like_this" , tool_spec = MagicMock (), callback = lambda : None )
34
+
35
+ tool_registry = ToolRegistry ()
36
+
37
+ tool_registry .register_tool (tool_1 )
38
+
39
+ with pytest .raises (ValueError ) as err :
40
+ tool_registry .register_tool (tool_2 )
41
+
42
+ assert (
43
+ str (err .value ) == "Tool name 'tool_like_this' already exists as 'tool-like-this'. "
44
+ "Cannot add a duplicate tool which differs by a '-' or '_'"
45
+ )
You can’t perform that action at this time.
0 commit comments