Skip to content

Commit 3a33bfa

Browse files
committed
Wrap fast-path tool lookups in a typed helper
Mypy on CI didn't like the bare ``router.agent.toolsets[0].tools[name]`` expression repeated across the per-tool tests: ``toolsets[0]`` is typed as ``AbstractToolset``, and ``tools`` is only an instance attribute on the concrete ``FunctionToolset`` subclass. Extract a single ``_fast_path_tool(router, name)`` helper using ``getattr`` (matching the pattern the registration test already uses) so the cast lives in one place and returns Any -- the per-tool tests then look up tools without tripping mypy.
1 parent 66f6751 commit 3a33bfa

1 file changed

Lines changed: 26 additions & 12 deletions

File tree

test/unit/app/test_agents.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ def setup_method(self):
7676
job_manager=None,
7777
)
7878

79+
@staticmethod
80+
def _fast_path_tool(router: QueryRouterAgent, name: str) -> Any:
81+
"""Look up a registered fast-path tool by name.
82+
83+
``router.agent.toolsets[0]`` is typed as ``AbstractToolset`` which
84+
doesn't expose ``tools`` -- the concrete ``FunctionToolset`` does, but
85+
only as an instance attribute. ``getattr`` keeps mypy quiet without
86+
casting.
87+
"""
88+
toolset = router.agent.toolsets[0]
89+
tools = getattr(toolset, "tools", None)
90+
assert tools is not None, "Router toolset is missing tools mapping"
91+
return tools[name]
92+
7993
def test_agent_config_fallback_chain(self):
8094
# Set up mock config with inference_services
8195
self.mock_config.inference_services = {
@@ -353,7 +367,7 @@ def test_router_registers_fast_path_tools(self):
353367
async def test_router_fast_path_list_histories(self):
354368
router = QueryRouterAgent(self.deps)
355369
ctx = SimpleNamespace(deps=self.deps)
356-
tool_def = router.agent.toolsets[0].tools["list_histories"]
370+
tool_def = self._fast_path_tool(router, "list_histories")
357371

358372
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
359373
MockOps.return_value.list_histories.return_value = {
@@ -370,7 +384,7 @@ async def test_router_fast_path_list_histories(self):
370384
async def test_router_fast_path_get_history_summary(self):
371385
router = QueryRouterAgent(self.deps)
372386
ctx = SimpleNamespace(deps=self.deps)
373-
tool_def = router.agent.toolsets[0].tools["get_history_summary"]
387+
tool_def = self._fast_path_tool(router, "get_history_summary")
374388

375389
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
376390
MockOps.return_value.get_history_details.return_value = {
@@ -387,7 +401,7 @@ async def test_router_fast_path_get_history_summary(self):
387401
async def test_router_fast_path_get_history_summary_invalid_id(self):
388402
router = QueryRouterAgent(self.deps)
389403
ctx = SimpleNamespace(deps=self.deps)
390-
tool_def = router.agent.toolsets[0].tools["get_history_summary"]
404+
tool_def = self._fast_path_tool(router, "get_history_summary")
391405

392406
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
393407
MockOps.return_value.get_history_details.side_effect = MalformedId("bad")
@@ -400,7 +414,7 @@ async def test_router_fast_path_get_history_summary_invalid_id(self):
400414
async def test_router_fast_path_list_workflows(self):
401415
router = QueryRouterAgent(self.deps)
402416
ctx = SimpleNamespace(deps=self.deps)
403-
tool_def = router.agent.toolsets[0].tools["list_workflows"]
417+
tool_def = self._fast_path_tool(router, "list_workflows")
404418

405419
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
406420
MockOps.return_value.list_workflows.return_value = {
@@ -420,7 +434,7 @@ async def test_router_fast_path_list_workflows_empty_filter(self):
420434
"""Empty filter string should pass search=None to the operations manager."""
421435
router = QueryRouterAgent(self.deps)
422436
ctx = SimpleNamespace(deps=self.deps)
423-
tool_def = router.agent.toolsets[0].tools["list_workflows"]
437+
tool_def = self._fast_path_tool(router, "list_workflows")
424438

425439
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
426440
MockOps.return_value.list_workflows.return_value = {
@@ -437,7 +451,7 @@ async def test_router_fast_path_list_workflows_empty_filter(self):
437451
async def test_router_fast_path_get_user_info(self):
438452
router = QueryRouterAgent(self.deps)
439453
ctx = SimpleNamespace(deps=self.deps)
440-
tool_def = router.agent.toolsets[0].tools["get_user_info"]
454+
tool_def = self._fast_path_tool(router, "get_user_info")
441455

442456
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
443457
MockOps.return_value.get_user.return_value = {
@@ -459,7 +473,7 @@ async def test_router_fast_path_get_user_info(self):
459473
async def test_router_fast_path_search_workflows(self):
460474
router = QueryRouterAgent(self.deps)
461475
ctx = SimpleNamespace(deps=self.deps)
462-
tool_def = router.agent.toolsets[0].tools["search_workflows"]
476+
tool_def = self._fast_path_tool(router, "search_workflows")
463477

464478
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
465479
MockOps.return_value.list_workflows.return_value = {
@@ -478,7 +492,7 @@ async def test_router_fast_path_search_workflows(self):
478492
async def test_router_fast_path_search_tools(self):
479493
router = QueryRouterAgent(self.deps)
480494
ctx = SimpleNamespace(deps=self.deps)
481-
tool_def = router.agent.toolsets[0].tools["search_tools"]
495+
tool_def = self._fast_path_tool(router, "search_tools")
482496

483497
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
484498
MockOps.return_value.search_tools.return_value = {
@@ -500,7 +514,7 @@ async def test_router_fast_path_search_tools_truncates(self):
500514
"""The router tool slices oversized results because ops.search_tools has no limit param."""
501515
router = QueryRouterAgent(self.deps)
502516
ctx = SimpleNamespace(deps=self.deps)
503-
tool_def = router.agent.toolsets[0].tools["search_tools"]
517+
tool_def = self._fast_path_tool(router, "search_tools")
504518

505519
many_tools = [{"id": f"tool_{i}", "name": f"Tool {i}", "description": "", "version": "1.0"} for i in range(25)]
506520
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
@@ -521,7 +535,7 @@ async def test_router_fast_path_search_tools_clamps_bad_limits(self, bad_limit):
521535
"""Zero/negative limits should fall back to the default, not slice from the tail."""
522536
router = QueryRouterAgent(self.deps)
523537
ctx = SimpleNamespace(deps=self.deps)
524-
tool_def = router.agent.toolsets[0].tools["search_tools"]
538+
tool_def = self._fast_path_tool(router, "search_tools")
525539

526540
many_tools = [{"id": f"tool_{i}", "name": f"Tool {i}", "description": "", "version": "1.0"} for i in range(25)]
527541
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
@@ -542,7 +556,7 @@ async def test_router_fast_path_search_tools_clamps_oversized_limit(self):
542556
"""Limits above the sanity cap (50) should be clamped down."""
543557
router = QueryRouterAgent(self.deps)
544558
ctx = SimpleNamespace(deps=self.deps)
545-
tool_def = router.agent.toolsets[0].tools["search_tools"]
559+
tool_def = self._fast_path_tool(router, "search_tools")
546560

547561
many_tools = [{"id": f"tool_{i}", "name": f"Tool {i}", "description": "", "version": "1.0"} for i in range(80)]
548562
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
@@ -561,7 +575,7 @@ async def test_router_fast_path_search_tools_clamps_oversized_limit(self):
561575
async def test_router_fast_path_get_server_info(self):
562576
router = QueryRouterAgent(self.deps)
563577
ctx = SimpleNamespace(deps=self.deps)
564-
tool_def = router.agent.toolsets[0].tools["get_server_info"]
578+
tool_def = self._fast_path_tool(router, "get_server_info")
565579

566580
with patch("galaxy.agents.router.AgentOperationsManager") as MockOps:
567581
MockOps.return_value.get_server_info.return_value = {

0 commit comments

Comments
 (0)