diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d0c57fe..58052c9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,6 @@ # Contributing -First of all, __thank you__ for your interest in contributing to AgentStack! Even the smallest contributions help a _ton_. + +First of all, **thank you** for your interest in contributing to AgentStack! Even the smallest contributions help a _ton_. Our vision is to build the defacto CLI for quickly spinning up an AI Agent project. We want to be the [create-react-app](https://create-react-app.dev/) of agents. Our inspiration also includes the oh-so-convenient [Angular CLI](https://v17.angular.io/cli). @@ -17,9 +18,11 @@ The best place to engage in conversation about your contribution is in the Issue - This will install the CLI locally and in editable mode so you can use `agentstack ` to test your latest changes ## Project Structure + TODO ## Adding Tools + If you're reading this section, you probably have a product that AI agents can use as a tool. We're glad you're here! Adding tools is easy once you understand the project structure. A few things need to be done for a tool to be considered completely supported: @@ -36,4 +39,19 @@ Adding tools is easy once you understand the project structure. A few things nee 4. Manually test your tool integration by running `agentstack tools add ` and ensure it behaves as expected. ## Tests -HAHAHAHAHAHAHA good one \ No newline at end of file + +Tests are written in `tests` folder with the cli tests being in `tests/test_cli_loads.py`. + +Testing is sparse at the moment but contributions are very welcome! 🙏 + +You can run tests by first installing test dependencies with + +```bash +pip install ".[test]" +``` + +Then running tox with + +```bash +tox +``` diff --git a/tests/test_cli_loads.py b/tests/test_cli_loads.py index 98ff2318..d4d6d4d7 100644 --- a/tests/test_cli_loads.py +++ b/tests/test_cli_loads.py @@ -43,6 +43,75 @@ def test_init_command(self): # Clean up shutil.rmtree(test_dir) + + def setUp(self): + self.TEST_DIR = Path("test_project") + + def run_cli(self, *args, cwd=None): + """Helper method to run the CLI with arguments.""" + result = subprocess.run( + [*self.CLI_ENTRY, *args], + capture_output=True, + text=True, + cwd=cwd + ) + return result + + # TODO: this is definitely not a clean way to test the CLI and + # TODO: should be done more elegantly. For now, this allows + # TODO: the tests to run sequentially and maintain state between + # TODO: them without creating conflicting projects. + def test_project_build_command(self): + """Test the 'init' command to create a project directory.""" + # Ensure the directory doesn't exist from previous runs + if self.TEST_DIR.exists(): + shutil.rmtree(self.TEST_DIR) + + result = self.run_cli("init", str(self.TEST_DIR), "--no-wizard") + self.assertEqual(result.returncode, 0) + self.assertTrue(self.TEST_DIR.exists()) + + """Test the 'generate agent' command.""" + agent_name = "test_agent" + result = self.run_cli("generate", "agent", agent_name, cwd=self.TEST_DIR) + self.assertEqual(result.returncode, 0) + # Verify that the agent is added to agents.yaml + agents_config = self.TEST_DIR / Path("src/config/agents.yaml") + self.assertTrue(agents_config.exists()) + with open(agents_config, 'r') as f: + content = f.read() + self.assertIn(agent_name, content) + + """Test the 'generate task' command.""" + task_name = "test_task" + result = self.run_cli("generate", "task", task_name, cwd=self.TEST_DIR) + self.assertEqual(result.returncode, 0) + # Verify that the task is added to tasks.yaml + tasks_config = self.TEST_DIR /Path("src/config/tasks.yaml") + self.assertTrue(tasks_config.exists()) + with open(tasks_config, 'r') as f: + content = f.read() + self.assertIn(task_name, content) + + """Test the 'tools list' command.""" + result = self.run_cli("tools", "list", cwd=self.TEST_DIR) + self.assertEqual(result.returncode, 0) + self.assertIn("Available AgentStack Tools:", result.stdout) + + """Test the 'tools add' command.""" + tool_name = "ftp" + result = self.run_cli("tools", "add", tool_name, cwd=self.TEST_DIR) + self.assertEqual(result.returncode, 0) + self.assertIn(f"Tool {tool_name} added", result.stdout) + # Clean up: remove the tool + self.run_cli("tools", "remove", tool_name) + + """Test the 'run' command.""" + result = self.run_cli("run", cwd=self.TEST_DIR) + self.assertEqual(result.returncode, 0) + + # Clean up + shutil.rmtree(self.TEST_DIR) if __name__ == "__main__":