77 lines
2.0 KiB
Python
77 lines
2.0 KiB
Python
from unittest.mock import MagicMock, patch
|
|||
|
|
|
||
|
|
from nanobot.agent.tools.base import Tool
|
||
|
|
from nanobot.agent.tools.loader import ToolLoader
|
||
|
|
|
||
|
|
|
||
|
|
def test_loader_discovers_entry_point_tools():
|
||
|
|
"""Simulate an entry-point plugin being discovered."""
|
||
|
|
mock_ep = MagicMock()
|
||
|
|
mock_ep.name = "my_plugin"
|
||
|
|
|
||
|
|
class _FakeTool(Tool):
|
||
|
|
__name__ = "FakeTool"
|
||
|
|
_plugin_discoverable = True
|
||
|
|
_scopes = {"core"}
|
||
|
|
|
||
|
|
@property
|
||
|
|
def name(self) -> str:
|
||
|
|
return "fake_tool"
|
||
|
|
|
||
|
|
@property
|
||
|
|
def description(self) -> str:
|
||
|
|
return "A fake tool for testing."
|
||
|
|
|
||
|
|
@property
|
||
|
|
def parameters(self) -> dict:
|
||
|
|
return {"type": "object"}
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def enabled(cls, ctx):
|
||
|
|
return True
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def create(cls, ctx):
|
||
|
|
return MagicMock()
|
||
|
|
|
||
|
|
async def execute(self, **_):
|
||
|
|
return "ok"
|
||
|
|
|
||
|
|
mock_ep.load.return_value = _FakeTool
|
||
|
|
|
||
|
|
with patch("nanobot.agent.tools.loader.entry_points", return_value=[mock_ep]):
|
||
|
|
loader = ToolLoader()
|
||
|
|
discovered = loader._discover_plugins()
|
||
|
|
|
||
|
|
assert "my_plugin" in discovered
|
||
|
|
assert discovered["my_plugin"] is _FakeTool
|
||
|
|
|
||
|
|
|
||
|
|
def test_loader_skips_abstract_entry_point_tools():
|
||
|
|
"""Verify abstract tool classes registered via entry_points are skipped."""
|
||
|
|
mock_ep = MagicMock()
|
||
|
|
mock_ep.name = "abstract_plugin"
|
||
|
|
|
||
|
|
class _AbstractTool(Tool):
|
||
|
|
__name__ = "AbstractTool"
|
||
|
|
_plugin_discoverable = True
|
||
|
|
_scopes = {"core"}
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def enabled(cls, ctx):
|
||
|
|
return True
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def create(cls, ctx):
|
||
|
|
return MagicMock()
|
||
|
|
|
||
|
|
# Intentionally missing abstract properties (name, description, parameters, execute)
|
||
|
|
|
||
|
|
mock_ep.load.return_value = _AbstractTool
|
||
|
|
|
||
|
|
with patch("nanobot.agent.tools.loader.entry_points", return_value=[mock_ep]):
|
||
|
|
loader = ToolLoader()
|
||
|
|
discovered = loader._discover_plugins()
|
||
|
|
|
||
|
|
assert "abstract_plugin" not in discovered
|