| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- """Tests for create_agent_template utility."""
- from pathlib import Path
- from unittest.mock import patch
- import pytest
- from agency_swarm.utils.create_agent_template import create_agent_template
- class TestCreateAgentTemplate:
- """Test the create_agent_template function."""
- def test_create_basic_agent_template(self, tmp_path: Path) -> None:
- """Test creating a basic agent template with minimal parameters."""
- agent_name = "Test Agent"
- result = create_agent_template(agent_name=agent_name, path=str(tmp_path))
- assert result is True
- # Check folder structure (now uses underscores)
- agent_folder = tmp_path / "test_agent"
- assert agent_folder.exists()
- assert agent_folder.is_dir()
- # Check required files
- assert (agent_folder / "__init__.py").exists()
- assert (agent_folder / "test_agent.py").exists()
- assert (agent_folder / "instructions.md").exists()
- # Check required directories
- assert (agent_folder / "tools").exists()
- assert (agent_folder / "files").exists()
- assert (agent_folder / "tools" / "__init__.py").exists()
- assert (agent_folder / "tools" / "ExampleTool.py").exists()
- def test_create_agent_template_without_description(self, tmp_path: Path) -> None:
- """Test creating agent template without description - should use default placeholder."""
- agent_name = "Simple Agent"
- assert create_agent_template(agent_name=agent_name, path=str(tmp_path)) is True
- agent_folder = tmp_path / "simple_agent"
- agent_file = agent_folder / "simple_agent.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- # Should NOT have description line
- assert "description=" not in agent_content
- assert f'name="{agent_name}"' in agent_content
- assert 'instructions="./instructions.md"' in agent_content
- # Instructions file should have structured template with placeholder
- instructions_file = agent_folder / "instructions.md"
- instructions_content = instructions_file.read_text(encoding="utf-8")
- assert "# Role" in instructions_content
- assert "**[insert role" in instructions_content
- assert "# Goals" in instructions_content
- assert "# Process" in instructions_content
- assert "# Output Format" in instructions_content
- assert "# Additional Notes" in instructions_content
- def test_agent_file_content_structure(self, tmp_path: Path) -> None:
- """Test that generated agent file has correct v1.x structure."""
- agent_name = "Data Processor"
- agent_description = "Processes and analyzes data"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- )
- is True
- )
- agent_folder = tmp_path / "data_processor"
- agent_file = agent_folder / "data_processor.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- # Check v1.x imports and structure
- assert "from agency_swarm import Agent, ModelSettings" in agent_content
- assert "data_processor = Agent(" in agent_content
- assert f'name="{agent_name}"' in agent_content
- assert f'description="{agent_description}"' in agent_content
- assert 'instructions="./instructions.md"' in agent_content
- assert 'files_folder="./files"' in agent_content
- assert 'tools_folder="./tools"' in agent_content
- assert 'model="gpt-5.4"' in agent_content # Updated default model
- assert "ModelSettings(" in agent_content
- # gpt-5.4 is a reasoning model - no temperature
- assert "temperature=" not in agent_content
- def test_instructions_file_content(self, tmp_path: Path) -> None:
- """Test that instructions file has correct structured template content."""
- agent_name = "Research Assistant"
- agent_description = "Helps with research tasks"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- )
- is True
- )
- agent_folder = tmp_path / "research_assistant"
- instructions_file = agent_folder / "instructions.md"
- instructions_content = instructions_file.read_text(encoding="utf-8")
- # Should have structured template sections
- assert "# Role" in instructions_content
- assert "You are" in instructions_content
- assert agent_description in instructions_content
- assert "# Goals" in instructions_content
- assert "# Process" in instructions_content
- assert "# Output Format" in instructions_content
- assert "# Additional Notes" in instructions_content
- def test_custom_instructions(self, tmp_path: Path) -> None:
- """Test creating agent with custom instructions."""
- agent_name = "Custom Agent"
- agent_description = "Custom description"
- custom_instructions = "These are custom instructions for the agent."
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- instructions=custom_instructions,
- )
- is True
- )
- agent_folder = tmp_path / "custom_agent"
- instructions_file = agent_folder / "instructions.md"
- instructions_content = instructions_file.read_text(encoding="utf-8")
- assert instructions_content == custom_instructions
- def test_custom_instructions_with_description(self, tmp_path: Path) -> None:
- """Test creating agent with custom instructions and description."""
- agent_name = "Custom Agent"
- agent_description = "Custom description"
- custom_instructions = "You are a specialized agent. Follow these rules: 1. Be precise 2. Be helpful"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- instructions=custom_instructions,
- path=str(tmp_path),
- )
- is True
- )
- agent_folder = tmp_path / "custom_agent"
- # Agent file should have description
- agent_file = agent_folder / "custom_agent.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- assert f'description="{agent_description}"' in agent_content
- # Instructions file should have custom content (not auto-generated)
- instructions_file = agent_folder / "instructions.md"
- instructions_content = instructions_file.read_text(encoding="utf-8")
- assert instructions_content == custom_instructions
- def test_custom_instructions_without_description(self, tmp_path: Path) -> None:
- """Test creating agent with custom instructions but no description."""
- agent_name = "Instruction Agent"
- custom_instructions = "You are a specialized agent with custom instructions."
- assert (
- create_agent_template(agent_name=agent_name, instructions=custom_instructions, path=str(tmp_path)) is True
- )
- agent_folder = tmp_path / "instruction_agent"
- # Agent file should NOT have description
- agent_file = agent_folder / "instruction_agent.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- assert "description=" not in agent_content
- # Instructions file should have custom content
- instructions_file = agent_folder / "instructions.md"
- instructions_content = instructions_file.read_text(encoding="utf-8")
- assert instructions_content == custom_instructions
- def test_use_txt_extension(self, tmp_path: Path) -> None:
- """Test creating agent with .txt instructions file."""
- agent_name = "Text Agent"
- agent_description = "Uses txt files"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- use_txt=True,
- )
- is True
- )
- agent_folder = tmp_path / "text_agent"
- # Should create .txt file instead of .md
- assert (agent_folder / "instructions.txt").exists()
- assert not (agent_folder / "instructions.md").exists()
- # Agent file should reference .txt extension
- agent_file = agent_folder / "text_agent.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- assert 'instructions="./instructions.txt"' in agent_content
- def test_without_example_tool(self, tmp_path: Path) -> None:
- """Test creating agent without example tool."""
- agent_name = "No Tool Agent"
- agent_description = "Agent without example tool"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- include_example_tool=False,
- )
- is True
- )
- agent_folder = tmp_path / "no_tool_agent"
- # Should not create ExampleTool.py
- assert not (agent_folder / "tools" / "ExampleTool.py").exists()
- # But should still create tools folder and __init__.py
- assert (agent_folder / "tools").exists()
- assert (agent_folder / "tools" / "__init__.py").exists()
- def test_init_file_content(self, tmp_path: Path) -> None:
- """Test that __init__.py file has correct imports."""
- agent_name = "Import Test Agent"
- agent_description = "Test imports"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- )
- is True
- )
- agent_folder = tmp_path / "import_test_agent"
- init_file = agent_folder / "__init__.py"
- init_content = init_file.read_text(encoding="utf-8")
- assert "from .import_test_agent import import_test_agent" in init_content
- def test_example_tool_content(self, tmp_path: Path) -> None:
- """Test that ExampleTool.py has correct v1.x structure."""
- agent_name = "Tool Test Agent"
- agent_description = "Test tool generation"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- )
- is True
- )
- agent_folder = tmp_path / "tool_test_agent"
- tool_file = agent_folder / "tools" / "ExampleTool.py"
- tool_content = tool_file.read_text(encoding="utf-8")
- # Check v1.x tool structure
- assert "from agency_swarm.tools import BaseTool" in tool_content
- assert "from pydantic import Field" in tool_content
- assert "from dotenv import load_dotenv" in tool_content
- assert "load_dotenv()" in tool_content
- assert "class ExampleTool(BaseTool):" in tool_content
- assert "def run(self):" in tool_content
- assert 'if __name__ == "__main__":' in tool_content
- def test_folder_already_exists_error(self, tmp_path: Path) -> None:
- """Test that creating agent in existing folder raises error."""
- agent_name = "Existing Agent"
- agent_description = "Test existing folder"
- # Create the folder first
- (tmp_path / "existing_agent").mkdir()
- # Should raise exception
- with pytest.raises(FileExistsError, match="Folder already exists"):
- create_agent_template(agent_name=agent_name, agent_description=agent_description, path=str(tmp_path))
- def test_agent_name_normalization(self, tmp_path: Path) -> None:
- """Test that agent names with spaces are normalized correctly."""
- agent_name = "Complex Agent Name With Spaces"
- agent_description = "Test name normalization"
- assert (
- create_agent_template(
- agent_name=agent_name,
- agent_description=agent_description,
- path=str(tmp_path),
- )
- is True
- )
- # Should create folder with underscores
- agent_folder = tmp_path / "complex_agent_name_with_spaces"
- assert agent_folder.exists()
- # Check that agent variable is correct in files
- agent_file = agent_folder / "complex_agent_name_with_spaces.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- assert "complex_agent_name_with_spaces = Agent(" in agent_content
- init_file = agent_folder / "__init__.py"
- init_content = init_file.read_text(encoding="utf-8")
- assert "from .complex_agent_name_with_spaces import complex_agent_name_with_spaces" in init_content
- def test_agent_name_with_dots_preserves_version_digits(self, tmp_path: Path) -> None:
- """Agent names containing dots should normalize to underscores without dropping digits."""
- agent_name = "Versioned Agent 1.2"
- assert create_agent_template(agent_name=agent_name, path=str(tmp_path)) is True
- agent_folder = tmp_path / "versioned_agent_1_2"
- assert agent_folder.exists()
- assert (agent_folder / "versioned_agent_1_2.py").exists()
- init_content = (agent_folder / "__init__.py").read_text(encoding="utf-8")
- assert "from .versioned_agent_1_2 import versioned_agent_1_2" in init_content
- @patch("builtins.input")
- def test_interactive_input(self, mock_input, tmp_path: Path) -> None:
- """Test interactive input when name not provided."""
- mock_input.return_value = "Interactive Agent"
- assert create_agent_template(path=str(tmp_path)) is True
- # Should create agent with input name
- agent_folder = tmp_path / "interactive_agent"
- assert agent_folder.exists()
- agent_file = agent_folder / "interactive_agent.py"
- agent_content = agent_file.read_text(encoding="utf-8")
- assert 'name="Interactive Agent"' in agent_content
- # Should NOT have description since we don't prompt for it anymore
- assert "description=" not in agent_content
|