{"id":31211462,"url":"https://github.com/dpguthrie/canonical-agent-architecture","last_synced_at":"2025-09-21T05:20:11.860Z","repository":{"id":313303764,"uuid":"1050885651","full_name":"dpguthrie/canonical-agent-architecture","owner":"dpguthrie","description":"A canonical agent architecture implementation with tools","archived":false,"fork":false,"pushed_at":"2025-09-05T05:20:29.000Z","size":42,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-05T07:21:36.707Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dpguthrie.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-05T05:18:00.000Z","updated_at":"2025-09-05T05:20:32.000Z","dependencies_parsed_at":"2025-09-05T07:21:38.878Z","dependency_job_id":"64ac3310-5da4-4b83-a630-a7754b5a44fd","html_url":"https://github.com/dpguthrie/canonical-agent-architecture","commit_stats":null,"previous_names":["dpguthrie/canonical-agent-architecture"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/dpguthrie/canonical-agent-architecture","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpguthrie%2Fcanonical-agent-architecture","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpguthrie%2Fcanonical-agent-architecture/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpguthrie%2Fcanonical-agent-architecture/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpguthrie%2Fcanonical-agent-architecture/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dpguthrie","download_url":"https://codeload.github.com/dpguthrie/canonical-agent-architecture/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpguthrie%2Fcanonical-agent-architecture/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276195600,"owners_count":25601145,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-21T02:00:07.055Z","response_time":72,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-09-21T05:20:09.451Z","updated_at":"2025-09-21T05:20:11.842Z","avatar_url":"https://github.com/dpguthrie.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Agent Architecture\n\nA canonical agent architecture implementation with tools, built for production-ready AI agents. This project demonstrates a clean, debuggable foundation using a while loop pattern with tool integration and comprehensive evaluation capabilities.\n\n**Inspired by:** [The canonical agent architecture: A while loop with tools](https://www.braintrust.dev/blog/agent-while-loop) - Braintrust's blog post on building reliable agents with simple, composable patterns.\n\n## Features\n\n- **Canonical Agent Architecture**: Clean while loop implementation with tool calling\n- **Customer Service Tools**: Pre-built tools for user management, notifications, and subscriptions\n- **Comprehensive Evaluation**: Built-in evaluation framework with custom scorers\n- **Braintrust Integration**: Advanced logging, tracing, and evaluation capabilities\n- **Type-Safe**: Full type annotations and validation\n- **Production Ready**: Error handling, logging, and monitoring\n\n## Quick Start\n\n### Prerequisites\n\n- Python 3.12 or higher\n- OpenAI API key\n- Braintrust account\n\n### Installation\n\n#### Option 1: Using uv (Recommended)\n\n**macOS/Linux:**\n```bash\n# Clone the repository\ngit clone https://github.com/dpguthrie/canonical-agent-architecture.git\ncd canonical-agent\n\n# Install uv if you haven't already\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n\n# Install dependencies\nuv sync\n```\n\n**Windows (PowerShell):**\n```powershell\n# Clone the repository\ngit clone https://github.com/dpguthrie/canonical-agent-architecture.git\ncd canonical-agent\n\n# Install uv if you haven't already\npowershell -c \"irm https://astral.sh/uv/install.ps1 | iex\"\n\n# Install dependencies\nuv sync\n```\n\n#### Option 2: Using pip\n\n**macOS/Linux:**\n```bash\n# Clone the repository\ngit clone https://github.com/dpguthrie/canonical-agent-architecture.git\ncd canonical-agent\n\n# Create virtual environment\npython -m venv .venv\nsource .venv/bin/activate\n\n# Install dependencies\npip install -e .\n```\n\n**Windows (Command Prompt):**\n```cmd\n# Clone the repository\ngit clone https://github.com/dpguthrie/canonical-agent-architecture.git\ncd canonical-agent\n\n# Create virtual environment\npython -m venv .venv\n.venv\\Scripts\\activate\n\n# Install dependencies\npip install -e .\n```\n\n**Windows (PowerShell):**\n```powershell\n# Clone the repository\ngit clone https://github.com/dpguthrie/canonical-agent-architecture.git\ncd canonical-agent\n\n# Create virtual environment\npython -m venv .venv\n.venv\\Scripts\\Activate.ps1\n\n# Install dependencies\npip install -e .\n```\n\n### Environment Setup\n\n1. **Create your environment file:**\n   ```bash\n   # Copy the example environment file\n   cp .env.example .env\n   ```\n\n2. **Edit the `.env` file with your API keys:**\n   ```env\n   # OpenAI Configuration\n   OPENAI_API_KEY=your_openai_api_key_here\n   \n   # Braintrust Configuration (optional, for evaluations)\n   BRAINTRUST_API_KEY=your_braintrust_api_key_here\n   BRAINTRUST_PROJECT_NAME=agent-arch-eval\n   ```\n\n### Running the Agent\n\n#### Basic Usage\n\n**Using uv:**\n```bash\nuv run src/main.py\n```\n\n**Using pip:**\n```bash\npython src/main.py\n```\n\n#### Running Evaluations\n\n**Using uv:**\n```bash\nuv run --env-file .env src/evals/eval_agent.py\n```\n\n**Using pip:**\n```bash\npython src/evals/eval_agent.py\n```\n\n## Project Structure\n\n```\nagent-arch/\n├── README.md                 # This file\n├── pyproject.toml           # Project configuration and dependencies\n├── uv.lock                  # Lock file for uv package manager\n├── .env.example             # Template for environment variables\n└── src/\n    ├── __init__.py          # Package initialization\n    ├── agent.py             # Core agent implementation (AgentWhileLoop)\n    ├── datasets.py          # Evaluation datasets\n    ├── main.py              # Example usage and entry point\n    ├── prompt.py            # System prompts for the agent\n    ├── push.py              # Utilities for pushing data to Braintrust\n    ├── scorers.py           # Custom evaluation scorers\n    ├── tools.py             # Tool implementations with Braintrust integration\n    └── evals/\n        ├── __init__.py      # Evaluation package initialization\n        ├── base.py          # Base evaluation utilities\n        └── eval_agent.py    # Main evaluation script\n```\n\n### Key Components\n\n#### Core Agent (`src/agent.py`)\n- **`AgentWhileLoop`**: The main agent class implementing the canonical while loop pattern\n- **`AgentOptions`**: Configuration dataclass for agent behavior\n- Integrates with OpenAI's function calling and Braintrust logging\n\n#### Tools (`src/tools.py`)\n- **`Tool`**: Abstract base class for all agent tools\n- **Customer Service Tools**:\n  - `SearchUsersTool`: Find users by various criteria\n  - `GetUserDetailsTool`: Retrieve detailed user information\n  - `NotifyCustomerTool`: Send notifications to customers\n  - `UpdateSubscriptionTool`: Manage user subscriptions\n- **Braintrust Integration**: Built-in registration and Pydantic model generation\n- **Lambda-Compatible**: Self-contained definitions that work in AWS Lambda environments\n\n#### Evaluation Framework (`src/evals/`)\n- **`eval_agent.py`**: Main evaluation script using Braintrust\n- **`base.py`**: Helper functions for running evaluations\n- **Custom Scorers**: Content accuracy and tool usage evaluation\n\n#### Datasets (`src/datasets.py`)\n- Pre-defined evaluation scenarios covering:\n  - Multi-step workflows\n  - Single lookups\n  - Subscription management\n  - Customer notifications\n\n## Usage Examples\n\n### Basic Agent Interaction\n\n```python\nimport asyncio\nfrom src.agent import AgentWhileLoop, AgentOptions\nfrom src.tools import get_tools\nfrom src.prompt import SYSTEM_PROMPT\n\nasync def main():\n    # Initialize tools\n    tools = get_tools()\n    \n    # Configure agent\n    options = AgentOptions(\n        model=\"gpt-4\",\n        max_iterations=10,\n        system_prompt=SYSTEM_PROMPT,\n        temperature=0.1,\n    )\n    \n    # Create and run agent\n    agent = AgentWhileLoop(tools=tools, options=options)\n    response = await agent.run(\"Check if john@example.com is an active subscriber\")\n    print(response)\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Custom Tool Implementation\n\n```python\nfrom src.tools import Tool, ToolResult\n\nclass CustomTool(Tool):\n    @property\n    def name(self) -\u003e str:\n        return \"custom_tool\"\n    \n    @property\n    def description(self) -\u003e str:\n        return \"A custom tool for specific functionality\"\n    \n    @property\n    def parameters(self) -\u003e dict:\n        return {\n            \"type\": \"object\",\n            \"properties\": {\n                \"input\": {\"type\": \"string\", \"description\": \"Input parameter\"}\n            },\n            \"required\": [\"input\"]\n        }\n    \n    def execute(self, input: str) -\u003e ToolResult:\n        # Your custom logic here\n        return {\n            \"success\": True,\n            \"message\": f\"Processed: {input}\",\n            \"data\": {\"result\": input.upper()}\n        }\n```\n\n## Development\n\n### Running Tests\n\n```bash\n# Using uv\nuv run pytest\n\n# Using pip\npython -m pytest\n```\n\n### Code Formatting\n\n```bash\n# Using uv\nuv run ruff format\nuv run ruff check\n\n# Using pip\npython -m ruff format\npython -m ruff check\n```\n\n### Development Dependencies\n\nInstall development dependencies for testing and linting:\n\n```bash\n# Using uv\nuv sync --dev\n\n# Using pip\npip install -e \".[dev]\"\n```\n\n## Evaluation and Monitoring\n\nThe project includes a comprehensive evaluation framework using Braintrust:\n\n1. **Custom Scorers**: Evaluate content accuracy and tool usage\n2. **Automated Testing**: Run evaluations on predefined datasets\n3. **Performance Tracking**: Monitor agent performance over time\n4. **Detailed Logging**: Full conversation and tool execution logs\n\n### Running Evaluations\n\nEvaluations test the agent against various customer service scenarios:\n\n```bash\n# Make sure your .env file is configured\nuv run --env-file .env src/evals/eval_agent.py\n```\n\n## Configuration\n\n### Environment Variables\n\n- `OPENAI_API_KEY`: Your OpenAI API key (required)\n- `BRAINTRUST_API_KEY`: Your Braintrust API key (optional, for evaluations)\n- `BRAINTRUST_PROJECT_NAME`: Project name for Braintrust logging (optional)\n\n### Agent Configuration\n\nCustomize agent behavior through `AgentOptions`:\n\n```python\noptions = AgentOptions(\n    model=\"gpt-4o\",           # OpenAI model to use\n    max_iterations=10,        # Maximum tool calling iterations\n    system_prompt=SYSTEM_PROMPT,  # System instructions\n    temperature=0.1,          # Response randomness (0.0-1.0)\n)\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests for new functionality\n5. Run the test suite and linting\n6. Submit a pull request\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n\n## Support\n\nFor questions and support:\n- Open an issue on GitHub\n- Check the documentation in the code\n- Review the evaluation examples for usage patterns\n\n## Architecture Notes\n\nThis implementation follows the \"canonical agent architecture\" pattern as described in [Braintrust's blog post](https://www.braintrust.dev/blog/agent-while-loop), which provides:\n\n- **Simplicity**: Easy to understand and debug\n- **Flexibility**: Easy to add new tools and capabilities\n- **Observability**: Full logging and tracing of agent behavior\n- **Reliability**: Proper error handling and iteration limits\n- **Testability**: Comprehensive evaluation framework\n\nThe while loop pattern ensures predictable behavior while allowing for complex multi-step reasoning and tool usage. As the blog post notes, this pattern wins for the same reason as UNIX pipes and React components: it's simple, composable, and flexible enough to handle complexity without becoming complex itself.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpguthrie%2Fcanonical-agent-architecture","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpguthrie%2Fcanonical-agent-architecture","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpguthrie%2Fcanonical-agent-architecture/lists"}