Skip to main content
Thank you for your interest in contributing to AgenticPal! This guide will help you get started.

Development Setup

1

Clone the Repository

git clone https://github.com/yourusername/agenticpal.git
cd agenticpal
2

Install Dependencies

AgenticPal uses uv for dependency management:
uv sync
This will install all required dependencies including:
  • google-api-python-client - Google API access
  • google-auth-oauthlib - OAuth 2.0 authentication
  • langchain-qwq - LLM integration
  • pydantic - Schema validation
  • python-dateutil - Date parsing
3

Configure Google Cloud

  1. Create a project in Google Cloud Console
  2. Enable the following APIs:
    • Google Calendar API
    • Gmail API
    • Google Tasks API
  3. Create OAuth 2.0 credentials:
    • Application type: Desktop application
    • Download credentials as credentials.json
    • Place in project root
  4. Add your email as a test user on the OAuth consent screen
4

Run the Application

python main.py
On first run, you’ll be prompted to authenticate via browser. The token is cached in token.json for future sessions.

Project Structure

agenticpal/
├── agent/
│   ├── graph/
│   │   └── nodes/          # Graph execution nodes
│   ├── tools/
│   │   ├── tool_definitions.py  # Tool metadata and schemas
│   │   ├── registry.py          # Tool wrappers
│   │   └── meta_tools.py        # Meta-tool system
│   ├── prompts/            # LLM prompts and DSPy modules
│   ├── schemas.py          # Pydantic parameter models
│   └── state.py            # Agent state definition
├── services/
│   ├── calendar.py         # Google Calendar integration
│   ├── gmail.py            # Gmail integration
│   └── tasks.py            # Google Tasks integration
├── auth/                   # Authentication handlers
├── main.py                 # Entry point
└── README.md

Development Workflow

Adding Features

Follow the three-layer architecture:
  1. Service Layer - Add API integration in services/
  2. Tool Layer - Create tool wrapper in agent/tools/registry.py
  3. Definition Layer - Register in agent/tools/tool_definitions.py
See the Custom Tools guide for detailed instructions.

Making Changes

1

Create a Branch

git checkout -b feature/your-feature-name
2

Make Your Changes

Follow the existing code style and patterns:
  • Use type hints for all function parameters and returns
  • Add docstrings to all public functions
  • Follow PEP 8 style guidelines
  • Keep functions focused and single-purpose
3

Test Your Changes

Test your changes thoroughly:
python main.py
Try various user inputs that exercise your new functionality.
4

Commit Your Changes

git add .
git commit -m "feat: add support for XYZ"
Use conventional commit messages:
  • feat: - New feature
  • fix: - Bug fix
  • docs: - Documentation changes
  • refactor: - Code refactoring
  • test: - Adding tests
  • chore: - Maintenance tasks
5

Push and Create PR

git push origin feature/your-feature-name
Then create a Pull Request on GitHub with:
  • Clear description of changes
  • Screenshots/examples if applicable
  • Reference to any related issues

Code Style

Python Style

  • Follow PEP 8
  • Use 4 spaces for indentation
  • Maximum line length: 100 characters
  • Use type hints:
def add_calendar_event(
    self,
    title: str,
    start_time: str,
    end_time: Optional[str] = None,
) -> dict:
    """Add a calendar event with type hints."""
    ...

Docstring Format

Use Google-style docstrings:
def search_events(self, query: str, max_results: int = 5) -> dict:
    """
    Search for events by title.

    Args:
        query: Search term to match in event titles
        max_results: Maximum number of results to return

    Returns:
        Dict with success status and matching events list
    """
    ...

Error Handling

Always return structured error responses:
try:
    result = api_call()
    return {
        "success": True,
        "message": "Operation completed.",
        "data": result,
    }
except SpecificError as error:
    return {
        "success": False,
        "message": f"Failed: {error}",
        "error": str(error),
    }

Testing Guidelines

While AgenticPal doesn’t currently have a formal test suite, you should:
  1. Manual Testing - Test all code paths with various inputs
  2. Edge Cases - Test boundary conditions and error scenarios
  3. Integration Testing - Test with real Google APIs
  4. Regression Testing - Ensure existing features still work

Example Test Scenarios

Calendar Tool:
  • Create event with valid data
  • Create event with invalid date format
  • Create event with missing required fields
  • Update non-existent event
  • Delete event with confirmation
Gmail Tool:
  • List messages with no results
  • Search with complex query syntax
  • Get details of non-existent message

Pull Request Guidelines

PR Checklist

  • Code follows project style guidelines
  • All functions have docstrings and type hints
  • Changes have been manually tested
  • Existing functionality still works
  • Commit messages follow conventional format
  • PR description is clear and complete

PR Description Template

## Description
Brief description of what this PR does.

## Changes
- List of specific changes made
- Another change

## Testing
How the changes were tested:
1. Step 1
2. Step 2

## Screenshots (if applicable)
[Add screenshots here]

## Related Issues
Fixes #123
Relates to #456

Architecture Guidelines

Separation of Concerns

Maintain clean boundaries between layers:
# ❌ Bad: Tool calling service directly
def list_emails_tool(query: str):
    service = build('gmail', 'v1', credentials=creds)
    return service.users().messages().list(...).execute()

# ✅ Good: Tool using service abstraction
def list_emails_tool(query: str) -> dict:
    return self.gmail.list_messages(query=query)

Return Value Consistency

All service and tool methods return dicts with consistent structure:
{
    "success": bool,
    "message": str,      # Human-readable message
    "data": ...,         # Actual result data
    "error": str | None, # Error details if failed
}

Configuration Management

Use environment variables for configuration:
import os

LLM_MODEL = os.getenv("LLM_MODEL", "gpt-4")
TIMEZONE = os.getenv("TIMEZONE", "UTC")

Common Patterns

Date/Time Handling

Use the date utilities:
from agent.date_utils import parse_datetime, calculate_end_time

parsed_start, is_all_day = parse_datetime("next Tuesday", timezone="UTC")
end_time = calculate_end_time(parsed_start, "1 hour")

Tool Parameter Validation

Use Pydantic schemas:
from pydantic import BaseModel, Field, validator

class CreateEventParams(BaseModel):
    title: str = Field(..., min_length=1, max_length=500)
    start_time: str
    
    @validator('start_time')
    def validate_time(cls, v):
        # Custom validation logic
        return v

Getting Help

Recognition

Contributors will be:
  • Added to the project README
  • Credited in release notes
  • Mentioned in documentation for significant contributions
Thank you for contributing to AgenticPal!

See Also

Custom Tools

Guide to adding new tools

Service Integration

How to integrate new services

Graph Nodes

Creating custom graph nodes

Testing

Testing guidelines

Build docs developers (and LLMs) love