"""Tests for SubagentManager.""" from pathlib import Path from unittest.mock import MagicMock import pytest from nanobot.agent.subagent import SubagentManager from nanobot.agent.tools.filesystem import FileToolsConfig from nanobot.bus.queue import MessageBus from nanobot.config.schema import ToolsConfig from nanobot.providers.base import LLMProvider @pytest.mark.asyncio async def test_subagent_uses_tool_loader(): """Verify subagent registers tools via ToolLoader, not hard-coded imports.""" provider = MagicMock(spec=LLMProvider) provider.get_default_model.return_value = "test" sm = SubagentManager( provider=provider, workspace=Path("/tmp"), bus=MessageBus(), model="test", max_tool_result_chars=16_000, ) tools = sm._build_tools() assert tools.has("read_file") assert tools.has("write_file") assert not tools.has("message") assert not tools.has("spawn") @pytest.mark.asyncio async def test_subagent_build_tools_isolates_file_read_state(tmp_path): """Each spawned subagent needs a fresh file-state cache.""" (tmp_path / "note.txt").write_text("hello\n", encoding="utf-8") provider = MagicMock(spec=LLMProvider) provider.get_default_model.return_value = "test" sm = SubagentManager( provider=provider, workspace=tmp_path, bus=MessageBus(), model="test", max_tool_result_chars=16_000, ) first_read = sm._build_tools().get("read_file") second_read = sm._build_tools().get("read_file") assert first_read is not second_read assert (await first_read.execute(path="note.txt")).startswith("1| hello") second_result = await second_read.execute(path="note.txt") assert second_result.startswith("1| hello") assert "File unchanged" not in second_result def test_subagent_respects_file_tool_toggle(tmp_path): provider = MagicMock(spec=LLMProvider) provider.get_default_model.return_value = "test" sm = SubagentManager( provider=provider, workspace=tmp_path, bus=MessageBus(), model="test", max_tool_result_chars=16_000, tools_config=ToolsConfig(file=FileToolsConfig(enable=False)), ) tools = sm._build_tools() file_tools = { "apply_patch", "edit_file", "find_files", "grep", "list_dir", "read_file", "write_file", } assert file_tools.isdisjoint(tools.tool_names)