1- """Tests for meta tools ( tool_search + tool_execute)."""
1+ """Tests for tool_search + tool_execute (agent tool discovery )."""
22
33from __future__ import annotations
44
@@ -40,8 +40,8 @@ def _make_mock_tool(name: str = "test_tool", description: str = "A test tool") -
4040 )
4141
4242
43- def _make_meta_tools (toolset : MagicMock ) -> Tools :
44- """Build meta tools using the private helpers, wiring in a mock toolset."""
43+ def _make_tools (toolset : MagicMock ) -> Tools :
44+ """Build tool_search + tool_execute using the private helpers, wiring in a mock toolset."""
4545 search_tool = _create_search_tool (toolset .api_key )
4646 search_tool ._toolset = toolset
4747
@@ -66,34 +66,34 @@ def _make_mock_toolset(tools: list[StackOneTool] | None = None) -> MagicMock:
6666class TestBuildMetaTools :
6767 def test_returns_tools_collection (self ):
6868 toolset = _make_mock_toolset ()
69- result = _make_meta_tools (toolset )
69+ result = _make_tools (toolset )
7070
7171 assert isinstance (result , Tools )
7272 assert len (result ) == 2
7373
7474 def test_tool_names (self ):
7575 toolset = _make_mock_toolset ()
76- result = _make_meta_tools (toolset )
76+ result = _make_tools (toolset )
7777
7878 names = [t .name for t in result ]
7979 assert "tool_search" in names
8080 assert "tool_execute" in names
8181
8282 def test_search_tool_type (self ):
8383 toolset = _make_mock_toolset ()
84- result = _make_meta_tools (toolset )
84+ result = _make_tools (toolset )
8585 search = result .get_tool ("tool_search" )
8686 assert isinstance (search , _SearchTool )
8787
8888 def test_execute_tool_type (self ):
8989 toolset = _make_mock_toolset ()
90- result = _make_meta_tools (toolset )
90+ result = _make_tools (toolset )
9191 execute = result .get_tool ("tool_execute" )
9292 assert isinstance (execute , _ExecuteTool )
9393
9494 def test_private_attrs_excluded_from_serialization (self ):
9595 toolset = _make_mock_toolset ()
96- result = _make_meta_tools (toolset )
96+ result = _make_tools (toolset )
9797 search = result .get_tool ("tool_search" )
9898
9999 dumped = search .model_dump ()
@@ -103,8 +103,8 @@ def test_private_attrs_excluded_from_serialization(self):
103103class TestToolSearch :
104104 def test_delegates_to_search_tools (self ):
105105 toolset = _make_mock_toolset ()
106- meta = _make_meta_tools (toolset )
107- search = meta .get_tool ("tool_search" )
106+ built = _make_tools (toolset )
107+ search = built .get_tool ("tool_search" )
108108
109109 search .execute ({"query" : "find employees" })
110110
@@ -115,8 +115,8 @@ def test_delegates_to_search_tools(self):
115115 def test_returns_tool_names_descriptions_and_schemas (self ):
116116 mock_tool = _make_mock_tool (name = "bamboohr_list_employees" , description = "List employees" )
117117 toolset = _make_mock_toolset ([mock_tool ])
118- meta = _make_meta_tools (toolset )
119- search = meta .get_tool ("tool_search" )
118+ built = _make_tools (toolset )
119+ search = built .get_tool ("tool_search" )
120120
121121 result = search .execute ({"query" : "list employees" })
122122
@@ -130,8 +130,8 @@ def test_returns_tool_names_descriptions_and_schemas(self):
130130 def test_reads_config_from_toolset (self ):
131131 toolset = _make_mock_toolset ()
132132 toolset ._search_config = {"method" : "semantic" , "top_k" : 3 , "min_similarity" : 0.5 }
133- meta = _make_meta_tools (toolset )
134- search = meta .get_tool ("tool_search" )
133+ built = _make_tools (toolset )
134+ search = built .get_tool ("tool_search" )
135135
136136 search .execute ({"query" : "employees" })
137137
@@ -143,8 +143,8 @@ def test_reads_config_from_toolset(self):
143143 def test_reads_account_ids_from_toolset (self ):
144144 toolset = _make_mock_toolset ()
145145 toolset ._account_ids = ["acc-1" , "acc-2" ]
146- meta = _make_meta_tools (toolset )
147- search = meta .get_tool ("tool_search" )
146+ built = _make_tools (toolset )
147+ search = built .get_tool ("tool_search" )
148148
149149 search .execute ({"query" : "employees" })
150150
@@ -153,8 +153,8 @@ def test_reads_account_ids_from_toolset(self):
153153
154154 def test_string_arguments (self ):
155155 toolset = _make_mock_toolset ()
156- meta = _make_meta_tools (toolset )
157- search = meta .get_tool ("tool_search" )
156+ built = _make_tools (toolset )
157+ search = built .get_tool ("tool_search" )
158158
159159 result = search .execute (json .dumps ({"query" : "employees" }))
160160
@@ -163,8 +163,8 @@ def test_string_arguments(self):
163163
164164 def test_validation_error_returns_error_dict (self ):
165165 toolset = _make_mock_toolset ()
166- meta = _make_meta_tools (toolset )
167- search = meta .get_tool ("tool_search" )
166+ built = _make_tools (toolset )
167+ search = built .get_tool ("tool_search" )
168168
169169 result = search .execute ({"query" : "" })
170170
@@ -173,17 +173,17 @@ def test_validation_error_returns_error_dict(self):
173173
174174 def test_invalid_json_returns_error_dict (self ):
175175 toolset = _make_mock_toolset ()
176- meta = _make_meta_tools (toolset )
177- search = meta .get_tool ("tool_search" )
176+ built = _make_tools (toolset )
177+ search = built .get_tool ("tool_search" )
178178
179179 result = search .execute ("not valid json" )
180180
181181 assert "error" in result
182182
183183 def test_missing_query_returns_error_dict (self ):
184184 toolset = _make_mock_toolset ()
185- meta = _make_meta_tools (toolset )
186- search = meta .get_tool ("tool_search" )
185+ built = _make_tools (toolset )
186+ search = built .get_tool ("tool_search" )
187187
188188 result = search .execute ({})
189189
@@ -203,8 +203,8 @@ def test_delegates_to_fetch_and_execute(self):
203203 mock_tool .execute .return_value = {"result" : "ok" }
204204 toolset .fetch_tools .return_value = mock_tools
205205
206- meta = _make_meta_tools (toolset )
207- execute = meta .get_tool ("tool_execute" )
206+ built = _make_tools (toolset )
207+ execute = built .get_tool ("tool_execute" )
208208
209209 result = execute .execute ({"tool_name" : "test_tool" , "parameters" : {"id" : "123" }})
210210
@@ -219,8 +219,8 @@ def test_tool_not_found_returns_error(self):
219219 mock_tools .get_tool .return_value = None
220220 toolset .fetch_tools .return_value = mock_tools
221221
222- meta = _make_meta_tools (toolset )
223- execute = meta .get_tool ("tool_execute" )
222+ built = _make_tools (toolset )
223+ execute = built .get_tool ("tool_execute" )
224224
225225 result = execute .execute ({"tool_name" : "nonexistent_tool" })
226226
@@ -241,8 +241,8 @@ def test_api_error_returned_as_dict(self):
241241 mock_tools .get_tool .return_value = mock_tool
242242 toolset .fetch_tools .return_value = mock_tools
243243
244- meta = _make_meta_tools (toolset )
245- execute = meta .get_tool ("tool_execute" )
244+ built = _make_tools (toolset )
245+ execute = built .get_tool ("tool_execute" )
246246
247247 result = execute .execute ({"tool_name" : "test_tool" , "parameters" : {}})
248248
@@ -252,17 +252,17 @@ def test_api_error_returned_as_dict(self):
252252
253253 def test_validation_error_returns_error_dict (self ):
254254 toolset = _make_mock_toolset ()
255- meta = _make_meta_tools (toolset )
256- execute = meta .get_tool ("tool_execute" )
255+ built = _make_tools (toolset )
256+ execute = built .get_tool ("tool_execute" )
257257
258258 result = execute .execute ({"tool_name" : "" })
259259
260260 assert "error" in result
261261
262262 def test_invalid_json_returns_error_dict (self ):
263263 toolset = _make_mock_toolset ()
264- meta = _make_meta_tools (toolset )
265- execute = meta .get_tool ("tool_execute" )
264+ built = _make_tools (toolset )
265+ execute = built .get_tool ("tool_execute" )
266266
267267 result = execute .execute ("not valid json" )
268268
@@ -280,8 +280,8 @@ def test_caches_fetched_tools(self):
280280 mock_tools .get_tool .return_value = mock_tool
281281 toolset .fetch_tools .return_value = mock_tools
282282
283- meta = _make_meta_tools (toolset )
284- execute = meta .get_tool ("tool_execute" )
283+ built = _make_tools (toolset )
284+ execute = built .get_tool ("tool_execute" )
285285
286286 execute .execute ({"tool_name" : "test_tool" })
287287 execute .execute ({"tool_name" : "test_tool" })
@@ -300,8 +300,8 @@ def test_passes_account_ids_from_toolset(self):
300300 mock_tools .get_tool .return_value = mock_tool
301301 toolset .fetch_tools .return_value = mock_tools
302302
303- meta = _make_meta_tools (toolset )
304- execute = meta .get_tool ("tool_execute" )
303+ built = _make_tools (toolset )
304+ execute = built .get_tool ("tool_execute" )
305305
306306 execute .execute ({"tool_name" : "test_tool" })
307307
@@ -319,20 +319,20 @@ def test_string_arguments(self):
319319 mock_tools .get_tool .return_value = mock_tool
320320 toolset .fetch_tools .return_value = mock_tools
321321
322- meta = _make_meta_tools (toolset )
323- execute = meta .get_tool ("tool_execute" )
322+ built = _make_tools (toolset )
323+ execute = built .get_tool ("tool_execute" )
324324
325325 result = execute .execute (json .dumps ({"tool_name" : "test_tool" , "parameters" : {}}))
326326
327327 assert result == {"ok" : True }
328328
329329
330330class TestLangChainConversion :
331- def test_meta_tools_convert_to_langchain (self ):
331+ def test_tools_convert_to_langchain (self ):
332332 toolset = _make_mock_toolset ()
333- meta = _make_meta_tools (toolset )
333+ built = _make_tools (toolset )
334334
335- langchain_tools = meta .to_langchain ()
335+ langchain_tools = built .to_langchain ()
336336
337337 assert len (langchain_tools ) == 2
338338 names = [t .name for t in langchain_tools ]
@@ -342,8 +342,8 @@ def test_meta_tools_convert_to_langchain(self):
342342 def test_execute_tool_parameters_field_is_dict_type (self ):
343343 """The 'parameters' field of tool_execute should map to dict, not str."""
344344 toolset = _make_mock_toolset ()
345- meta = _make_meta_tools (toolset )
346- execute_tool = meta .get_tool ("tool_execute" )
345+ built = _make_tools (toolset )
346+ execute_tool = built .get_tool ("tool_execute" )
347347
348348 langchain_tool = execute_tool .to_langchain ()
349349 annotations = langchain_tool .args_schema .__annotations__
@@ -352,11 +352,11 @@ def test_execute_tool_parameters_field_is_dict_type(self):
352352
353353
354354class TestOpenAIConversion :
355- def test_meta_tools_convert_to_openai (self ):
355+ def test_tools_convert_to_openai (self ):
356356 toolset = _make_mock_toolset ()
357- meta = _make_meta_tools (toolset )
357+ built = _make_tools (toolset )
358358
359- openai_tools = meta .to_openai ()
359+ openai_tools = built .to_openai ()
360360
361361 assert len (openai_tools ) == 2
362362 names = [t ["function" ]["name" ] for t in openai_tools ]
@@ -365,9 +365,9 @@ def test_meta_tools_convert_to_openai(self):
365365
366366 def test_nullable_fields_not_required (self ):
367367 toolset = _make_mock_toolset ()
368- meta = _make_meta_tools (toolset )
368+ built = _make_tools (toolset )
369369
370- openai_tools = meta .to_openai ()
370+ openai_tools = built .to_openai ()
371371 search_fn = next (t for t in openai_tools if t ["function" ]["name" ] == "tool_search" )
372372 required = search_fn ["function" ]["parameters" ].get ("required" , [])
373373
@@ -390,11 +390,11 @@ def test_openai_default_fetches_all_tools(self):
390390 assert len (result ) == 1
391391 assert result [0 ]["function" ]["name" ] == "test_tool"
392392
393- def test_openai_search_and_execute_returns_meta_tools (self ):
393+ def test_openai_search_and_execute_returns_tools (self ):
394394 toolset = StackOneToolSet (api_key = "test-key" )
395- mock_meta = Tools ([_make_mock_tool (name = "tool_search" ), _make_mock_tool (name = "tool_execute" )])
395+ mock_built = Tools ([_make_mock_tool (name = "tool_search" ), _make_mock_tool (name = "tool_execute" )])
396396
397- with patch .object (toolset , "_build_tools" , return_value = mock_meta ) as mock_build :
397+ with patch .object (toolset , "_build_tools" , return_value = mock_built ) as mock_build :
398398 result = toolset .openai (mode = "search_and_execute" )
399399
400400 mock_build .assert_called_once_with (account_ids = None )
@@ -432,9 +432,9 @@ def test_openai_account_ids_overrides_execute_config(self):
432432
433433 def test_openai_search_and_execute_with_execute_config (self ):
434434 toolset = StackOneToolSet (api_key = "test-key" , execute = {"account_ids" : ["acc-1" ]})
435- mock_meta = Tools ([_make_mock_tool (name = "tool_search" ), _make_mock_tool (name = "tool_execute" )])
435+ mock_built = Tools ([_make_mock_tool (name = "tool_search" ), _make_mock_tool (name = "tool_execute" )])
436436
437- with patch .object (toolset , "_build_tools" , return_value = mock_meta ) as mock_build :
437+ with patch .object (toolset , "_build_tools" , return_value = mock_built ) as mock_build :
438438 toolset .openai (mode = "search_and_execute" )
439439
440440 mock_build .assert_called_once_with (account_ids = ["acc-1" ])
@@ -443,39 +443,39 @@ def test_openai_search_and_execute_with_execute_config(self):
443443class TestToolSetExecuteMethod :
444444 """Tests for StackOneToolSet.execute() convenience method."""
445445
446- def test_execute_delegates_to_meta_tool (self ):
446+ def test_execute_delegates_to_tool (self ):
447447 toolset = StackOneToolSet (api_key = "test-key" , search = {"method" : "auto" })
448448 mock_tool = MagicMock ()
449449 mock_tool .execute .return_value = {"result" : "ok" }
450- mock_meta = MagicMock ()
451- mock_meta .get_tool .return_value = mock_tool
450+ mock_built = MagicMock ()
451+ mock_built .get_tool .return_value = mock_tool
452452
453- with patch .object (toolset , "_build_tools" , return_value = mock_meta ):
453+ with patch .object (toolset , "_build_tools" , return_value = mock_built ):
454454 result = toolset .execute ("tool_search" , {"query" : "employees" })
455455
456456 assert result == {"result" : "ok" }
457- mock_meta .get_tool .assert_called_once_with ("tool_search" )
457+ mock_built .get_tool .assert_called_once_with ("tool_search" )
458458 mock_tool .execute .assert_called_once_with ({"query" : "employees" })
459459
460- def test_execute_caches_meta_tools (self ):
460+ def test_execute_caches_tools (self ):
461461 toolset = StackOneToolSet (api_key = "test-key" , search = {"method" : "auto" })
462462 mock_tool = MagicMock ()
463463 mock_tool .execute .return_value = {"ok" : True }
464- mock_meta = MagicMock ()
465- mock_meta .get_tool .return_value = mock_tool
464+ mock_built = MagicMock ()
465+ mock_built .get_tool .return_value = mock_tool
466466
467- with patch .object (toolset , "_build_tools" , return_value = mock_meta ) as mock_build :
467+ with patch .object (toolset , "_build_tools" , return_value = mock_built ) as mock_build :
468468 toolset .execute ("tool_search" , {"query" : "a" })
469469 toolset .execute ("tool_execute" , {"tool_name" : "b" })
470470
471471 mock_build .assert_called_once ()
472472
473473 def test_execute_returns_error_for_unknown_tool (self ):
474474 toolset = StackOneToolSet (api_key = "test-key" , search = {"method" : "auto" })
475- mock_meta = MagicMock ()
476- mock_meta .get_tool .return_value = None
475+ mock_built = MagicMock ()
476+ mock_built .get_tool .return_value = None
477477
478- with patch .object (toolset , "_build_tools" , return_value = mock_meta ):
478+ with patch .object (toolset , "_build_tools" , return_value = mock_built ):
479479 result = toolset .execute ("nonexistent" , {})
480480
481481 assert "error" in result
@@ -484,10 +484,10 @@ def test_execute_accepts_string_arguments(self):
484484 toolset = StackOneToolSet (api_key = "test-key" , search = {"method" : "auto" })
485485 mock_tool = MagicMock ()
486486 mock_tool .execute .return_value = {"ok" : True }
487- mock_meta = MagicMock ()
488- mock_meta .get_tool .return_value = mock_tool
487+ mock_built = MagicMock ()
488+ mock_built .get_tool .return_value = mock_tool
489489
490- with patch .object (toolset , "_build_tools" , return_value = mock_meta ):
490+ with patch .object (toolset , "_build_tools" , return_value = mock_built ):
491491 result = toolset .execute ("tool_search" , '{"query": "test"}' )
492492
493493 assert result == {"ok" : True }
0 commit comments