test_create_agent_template_integration.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. """Integration tests for CLI create-agent-template functionality."""
  2. import subprocess
  3. import sys
  4. from pathlib import Path
  5. class TestCreateAgentTemplateIntegration:
  6. """Integration tests for the create-agent-template CLI command."""
  7. def test_create_agent_template_cli_integration(self, tmp_path: Path) -> None:
  8. """Test the complete CLI workflow for creating an agent template."""
  9. # Run the CLI command as a subprocess
  10. result = subprocess.run(
  11. [
  12. sys.executable,
  13. "-m",
  14. "agency_swarm.cli.main",
  15. "create-agent-template",
  16. "Integration Test Agent",
  17. "--description",
  18. "An agent for integration testing",
  19. "--path",
  20. str(tmp_path),
  21. ],
  22. capture_output=True,
  23. text=True,
  24. cwd=Path(__file__).parent.parent.parent.parent, # Project root
  25. )
  26. # Check command succeeded
  27. assert result.returncode == 0, f"CLI command failed: {result.stderr}"
  28. # Verify output message
  29. assert "Agent folder created successfully" in result.stdout
  30. assert "Import it with: from integration_test_agent import integration_test_agent" in result.stdout
  31. # Verify folder structure was created
  32. agent_folder = tmp_path / "integration_test_agent"
  33. assert agent_folder.exists()
  34. assert agent_folder.is_dir()
  35. # Verify all required files exist
  36. required_files = ["__init__.py", "integration_test_agent.py", "instructions.md"]
  37. for file_name in required_files:
  38. file_path = agent_folder / file_name
  39. assert file_path.exists(), f"Missing file: {file_name}"
  40. assert file_path.is_file()
  41. # Verify directories exist
  42. assert (agent_folder / "tools").exists()
  43. assert (agent_folder / "files").exists()
  44. assert (agent_folder / "tools" / "__init__.py").exists()
  45. assert (agent_folder / "tools" / "ExampleTool.py").exists()
  46. def test_create_agent_with_txt_extension(self, tmp_path: Path) -> None:
  47. """Test creating agent with --use-txt option."""
  48. result = subprocess.run(
  49. [
  50. sys.executable,
  51. "-m",
  52. "agency_swarm.cli.main",
  53. "create-agent-template",
  54. "TXT Agent",
  55. "--use-txt",
  56. "--path",
  57. str(tmp_path),
  58. ],
  59. capture_output=True,
  60. text=True,
  61. cwd=Path(__file__).parent.parent.parent.parent,
  62. )
  63. assert result.returncode == 0
  64. # Check that .txt file was created instead of .md
  65. agent_folder = tmp_path / "txt_agent"
  66. assert (agent_folder / "instructions.txt").exists()
  67. assert not (agent_folder / "instructions.md").exists()
  68. # Check that agent file references .txt extension
  69. agent_file = agent_folder / "txt_agent.py"
  70. content = agent_file.read_text(encoding="utf-8")
  71. assert 'instructions="./instructions.txt"' in content
  72. def test_create_agent_with_instructions_parameter(self, tmp_path: Path) -> None:
  73. """Test creating agent with --instructions option."""
  74. custom_instructions = "You are a specialized test agent. Always be precise and helpful."
  75. result = subprocess.run(
  76. [
  77. sys.executable,
  78. "-m",
  79. "agency_swarm.cli.main",
  80. "create-agent-template",
  81. "Instruction Agent",
  82. "--instructions",
  83. custom_instructions,
  84. "--path",
  85. str(tmp_path),
  86. ],
  87. capture_output=True,
  88. text=True,
  89. cwd=Path(__file__).parent.parent.parent.parent,
  90. )
  91. assert result.returncode == 0
  92. # Check that custom instructions were used
  93. agent_folder = tmp_path / "instruction_agent"
  94. instructions_file = agent_folder / "instructions.md"
  95. instructions_content = instructions_file.read_text(encoding="utf-8")
  96. assert instructions_content == custom_instructions
  97. # Agent file should NOT have description since none was provided
  98. agent_file = agent_folder / "instruction_agent.py"
  99. agent_content = agent_file.read_text(encoding="utf-8")
  100. assert "description=" not in agent_content
  101. def test_cli_help_command(self) -> None:
  102. """Test that CLI help command works."""
  103. result = subprocess.run(
  104. [sys.executable, "-m", "agency_swarm.cli.main", "--help"],
  105. capture_output=True,
  106. text=True,
  107. cwd=Path(__file__).parent.parent.parent.parent,
  108. )
  109. assert result.returncode == 0
  110. assert "Agency Swarm CLI tools" in result.stdout
  111. assert "create-agent-template" in result.stdout
  112. def test_create_agent_template_help_command(self) -> None:
  113. """Test that create-agent-template help command works."""
  114. result = subprocess.run(
  115. [sys.executable, "-m", "agency_swarm.cli.main", "create-agent-template", "--help"],
  116. capture_output=True,
  117. text=True,
  118. cwd=Path(__file__).parent.parent.parent.parent,
  119. )
  120. assert result.returncode == 0
  121. # Check for key help text elements (more flexible matching)
  122. assert "create-agent-template" in result.stdout
  123. assert "--description" in result.stdout
  124. assert "--instructions" in result.stdout
  125. assert "--use-txt" in result.stdout
  126. assert "--path" in result.stdout
  127. def test_generated_agent_can_be_imported(self, tmp_path: Path) -> None:
  128. """Test that the generated agent can be imported and used."""
  129. # Create agent
  130. result = subprocess.run(
  131. [
  132. sys.executable,
  133. "-m",
  134. "agency_swarm.cli.main",
  135. "create-agent-template",
  136. "Import Test Agent",
  137. "--description",
  138. "Test agent for import validation",
  139. "--path",
  140. str(tmp_path),
  141. ],
  142. capture_output=True,
  143. text=True,
  144. cwd=Path(__file__).parent.parent.parent.parent,
  145. )
  146. assert result.returncode == 0
  147. # Test that the generated Python code is syntactically valid
  148. agent_file = tmp_path / "import_test_agent" / "import_test_agent.py"
  149. # Read and compile the generated code to check syntax
  150. with open(agent_file, encoding="utf-8") as f:
  151. code = f.read()
  152. # This will raise SyntaxError if the code is invalid
  153. compile(code, str(agent_file), "exec")
  154. # Verify the agent variable is defined in the code
  155. assert "import_test_agent = Agent(" in code
  156. # Test that the tool file is also syntactically valid
  157. tool_file = tmp_path / "import_test_agent" / "tools" / "ExampleTool.py"
  158. with open(tool_file, encoding="utf-8") as f:
  159. tool_code = f.read()
  160. compile(tool_code, str(tool_file), "exec")
  161. def test_missing_agent_name_fails(self) -> None:
  162. """Test that missing agent name causes CLI to fail."""
  163. result = subprocess.run(
  164. [sys.executable, "-m", "agency_swarm.cli.main", "create-agent-template"],
  165. capture_output=True,
  166. text=True,
  167. cwd=Path(__file__).parent.parent.parent.parent,
  168. )
  169. # Should fail with non-zero exit code
  170. assert result.returncode != 0
  171. assert "required" in result.stderr.lower() or "error" in result.stderr.lower()
  172. def test_folder_already_exists_error(self, tmp_path: Path) -> None:
  173. """Test that creating agent in existing folder fails gracefully."""
  174. # Create the folder first
  175. (tmp_path / "existing_agent").mkdir()
  176. result = subprocess.run(
  177. [
  178. sys.executable,
  179. "-m",
  180. "agency_swarm.cli.main",
  181. "create-agent-template",
  182. "Existing Agent",
  183. "--path",
  184. str(tmp_path),
  185. ],
  186. capture_output=True,
  187. text=True,
  188. cwd=Path(__file__).parent.parent.parent.parent,
  189. )
  190. # Should fail with non-zero exit code
  191. assert result.returncode != 0
  192. assert "Folder already exists" in result.stderr
  193. def test_invalid_agent_name_returns_error(self, tmp_path: Path) -> None:
  194. """Invalid agent names should surface a non-zero exit code."""
  195. result = subprocess.run(
  196. [
  197. sys.executable,
  198. "-m",
  199. "agency_swarm.cli.main",
  200. "create-agent-template",
  201. "Invalid<Name>",
  202. "--path",
  203. str(tmp_path),
  204. ],
  205. capture_output=True,
  206. text=True,
  207. cwd=Path(__file__).parent.parent.parent.parent,
  208. )
  209. assert result.returncode != 0
  210. assert "Agent name contains invalid characters" in result.stdout
  211. def test_cli_propagates_validation_errors(self, tmp_path: Path) -> None:
  212. """CLI should fail fast when validation rejects input."""
  213. result = subprocess.run(
  214. [
  215. sys.executable,
  216. "-m",
  217. "agency_swarm.cli.main",
  218. "create-agent-template",
  219. "Invalid Temperature Agent",
  220. "--temperature",
  221. "3.0",
  222. "--path",
  223. str(tmp_path),
  224. ],
  225. capture_output=True,
  226. text=True,
  227. cwd=Path(__file__).parent.parent.parent.parent,
  228. )
  229. assert result.returncode == 1
  230. assert "ERROR: Temperature must be between 0.0 and 2.0" in result.stdout
  231. def test_create_agent_with_all_options(self, tmp_path: Path) -> None:
  232. """Test create-agent-template command with all available options."""
  233. result = subprocess.run(
  234. [
  235. sys.executable,
  236. "-m",
  237. "agency_swarm.cli.main",
  238. "create-agent-template",
  239. "Full Options Agent",
  240. "--description",
  241. "Agent created with all CLI options",
  242. "--path",
  243. str(tmp_path),
  244. "--use-txt",
  245. ],
  246. capture_output=True,
  247. text=True,
  248. cwd=Path(__file__).parent.parent.parent.parent,
  249. )
  250. assert result.returncode == 0
  251. agent_folder = tmp_path / "full_options_agent"
  252. assert agent_folder.exists()
  253. # Verify description is in agent file
  254. agent_file = agent_folder / "full_options_agent.py"
  255. agent_content = agent_file.read_text(encoding="utf-8")
  256. assert "Agent created with all CLI options" in agent_content
  257. # Verify txt extension was used
  258. assert (agent_folder / "instructions.txt").exists()
  259. assert 'instructions="./instructions.txt"' in agent_content