Skip to content

Repository files navigation

πŸš€ Autonomous Cold Email Outreach Agent

Production-Ready Multi-Agent Email Generation & Campaign Automation System

A sophisticated, autonomous cold email outreach platform featuring:

  • 4-Phase Email Pipeline (research β†’ strategy β†’ generation β†’ quality evaluation)
  • Autonomous Campaign Brain (intelligent prospect selection & timing)
  • Orchestrator Agent (goal-based autonomy with 11+ tools)
  • Full Event Tracking (webhooks, feedback loops, learning)
  • Production APIs (admin, orchestrator, email generation)

οΏ½ Core Architecture

4-Phase Email Generation Pipeline

  1. Phase 1 - Research: Perplexity API fetches real company data (funding, expansion, hiring)
  2. Phase 2 - Strategy: Intelligent router selects tone, approach, and personalization angles with confidence scores
  3. Phase 3 - Generation: Groq LLM generates personalized email body (single optimized call)
  4. Phase 4 - Quality: Deterministic evaluator scores across 6 dimensions (personalization, value, CTA, spam, tone, structure)

Autonomous Campaign Engine

  • Campaign Brain (src/autonomous/campaign_brain.py): Makes autonomous decisions about WHO to email, WHEN to send, and WHICH sequence step

    • Respects business hours and timezones
    • Enforces daily (100/day) and hourly (20/hour) rate limits
    • Handles initial outreach + follow-up sequences
    • Scores prospects by conversion probability
  • Campaign Scheduler (src/autonomous/scheduler.py): Executes campaigns at scale

    • Processes 50+ prospects in parallel
    • Generates personalized emails with quality threshold enforcement
    • Persists sends to database (idempotent - no duplicates)
    • Enforces deliverability guardrails

Orchestrator Agent

  • Goal-Based Autonomy (src/orchestrator/agent.py): LLM agent that understands goals and decides actions
  • 11+ Tools (src/orchestrator/tools.py): Create campaigns, import prospects, run batches, analyze performance, adjust settings
  • Respects All Guardrails: No tool bypasses safety constraints

βš™οΈ Key Features

πŸ›‘οΈ Safety & Compliance

  • Role address blocking (info@, support@, etc.)
  • Link density limits for spam prevention
  • Global bounce/spam rate thresholds with automatic halt
  • Opt-out enforcement (GDPR/CAN-SPAM compliant)
  • Unsubscribe token system with one-click opt-out

πŸ“Š Event Tracking & Feedback

  • SendGrid webhook handler ingests email events (delivered, open, click, bounce, spam, unsubscribe)
  • Automatic "replied" detection and exclusion
  • Phase 4 feedback loop learns which angles work best per segment
  • AngleSuccessDB tracks success rates for continuous improvement

πŸ”§ Production Features

  • FastAPI async backend with OpenAPI docs
  • SQLAlchemy ORM with PostgreSQL (prod) / SQLite (dev)
  • Structured logging and error handling
  • Docker & Railway ready
  • CORS enabled for external integrations

πŸ“§ Email Sending

  • SendGrid Integration: HTML emails with tracking (open/click)
  • SMTP Fallback: Development & testing mode
  • Auto-injected unsubscribe links
  • Custom metadata for webhook matching
  • Idempotent sends (no duplicates on retry)

πŸ“ Project Structure

my-email-agent/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   └── email_engine.py              # 4-phase unified pipeline
β”‚   β”œβ”€β”€ autonomous/
β”‚   β”‚   β”œβ”€β”€ campaign_brain.py            # Autonomous decision engine
β”‚   β”‚   └── scheduler.py                 # Batch campaign executor
β”‚   β”œβ”€β”€ orchestrator/
β”‚   β”‚   β”œβ”€β”€ agent.py                     # Goal-based orchestrator
β”‚   β”‚   └── tools.py                     # 11+ tools for orchestrator
β”‚   β”œβ”€β”€ email_sender/
β”‚   β”‚   β”œβ”€β”€ sendgrid_sender.py           # SendGrid integration
β”‚   β”‚   └── smtp_sender.py               # SMTP fallback
β”‚   β”œβ”€β”€ research/
β”‚   β”‚   β”œβ”€β”€ executor.py                  # Research orchestration
β”‚   β”‚   └── perplexity_client.py         # Perplexity API wrapper
β”‚   β”œβ”€β”€ evaluation/
β”‚   β”‚   └── quality_evaluator.py         # Multi-dimension quality scorer
β”‚   β”œβ”€β”€ personalization_new/
β”‚   β”‚   └── engine.py                    # Angle selection with confidence
β”‚   β”œβ”€β”€ llm/
β”‚   β”‚   └── llm_interface.py             # Groq/OpenAI client
β”‚   β”œβ”€β”€ llm_routing/
β”‚   β”‚   └── router.py                    # Intelligent LLM selector
β”‚   β”œβ”€β”€ feedback/
β”‚   β”‚   └── processor.py                 # Phase 4 learning loop
β”‚   β”œβ”€β”€ deliverability/
β”‚   β”‚   └── guardrails.py                # Safety constraints
β”‚   └── health_check.py                  # Health endpoint
β”œβ”€β”€ api/
β”‚   β”œβ”€β”€ routes.py                        # Email generation endpoints
β”‚   β”œβ”€β”€ routes_admin.py                  # Campaign management API
β”‚   β”œβ”€β”€ routes_orchestrator.py           # Orchestrator API
β”‚   β”œβ”€β”€ routes_webhooks.py               # SendGrid webhook handler
β”‚   β”œβ”€β”€ routes_unsubscribe.py            # One-click opt-out
β”‚   β”œβ”€β”€ routes_health.py                 # Health check routes
β”‚   β”œβ”€β”€ auth.py                          # API authentication
β”‚   β”œβ”€β”€ schemas.py                       # Pydantic models
β”‚   └── dependencies.py                  # Dependency injection
β”œβ”€β”€ database/
β”‚   β”œβ”€β”€ models.py                        # SQLAlchemy models (Campaign, Prospect, SentEmail, EmailEvent, AnglePerformance)
β”‚   β”œβ”€β”€ connection.py                    # DB connection & pooling
β”‚   └── __init__.py
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ settings.py                      # Environment configuration
β”‚   β”œβ”€β”€ prompts.py                       # Prompt templates
β”‚   └── presets.py                       # Preset configurations
β”œβ”€β”€ alembic/
β”‚   β”œβ”€β”€ env.py
β”‚   └── versions/                        # Database migrations
β”œβ”€β”€ app.py                               # FastAPI server
β”œβ”€β”€ main.py                              # CLI entry point (demo, interactive, health, metrics)
β”œβ”€β”€ run_campaign.py                      # Manual campaign runner
β”œβ”€β”€ run_campaign_now.py                  # Immediate batch runner
β”œβ”€β”€ test_features.py                     # Feature verification suite
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ docker-compose.yml
β”œβ”€β”€ Procfile                             # Railway deployment
β”œβ”€β”€ .env.example
└── README.md

πŸš€ Quick Start

1. Setup

# Clone repository
cd my-email-agent

# Create & activate virtual environment
python -m venv .venv
.venv\Scripts\activate  # Windows
source .venv/bin/activate  # macOS/Linux

# Install dependencies
pip install -r requirements.txt

2. Configure Environment

# Copy example and edit
cp .env.example .env
notepad .env  # Windows or nano/vim on Linux

# Required keys:
GROQ_API_KEY=your_key_here  # Get free key from https://console.groq.com/keys
PERPLEXITY_API_KEY=optional_key  # For real-time research

# Optional for production:
SENDGRID_API_KEY=your_key  # For actual email sending
ADMIN_API_KEY=secure_key  # For admin endpoints

3. Test Email Generation

# Enable UTF-8 for Windows PowerShell
$env:PYTHONUTF8=1

# Run demo (generates 1 email with research)
python main.py --demo

# Expected output: Email with 60-80/100 quality score

4. Test Campaign Automation

# Run batch campaign processing
python run_campaign.py --batch-size 10

# Expected: Autonomous prospect selection, rate-limit enforcement, email generation

5. Start FastAPI Server

# Development
python -m uvicorn app:app --reload --port 8000

# Production (if deployed)
gunicorn app:app -w 4 -k uvicorn.workers.UvicornWorker

# Access: http://localhost:8000/docs (OpenAPI UI)

6. Test All Features

# Run comprehensive feature verification
python test_features.py

# Results: 6/6 features verified (orchestrator, campaign brain, scheduler, senders, webhooks, admin API)

πŸ’» API Endpoints

Email Generation

  • POST /api/v1/emails/generate - Generate single personalized email
  • POST /api/v1/emails/batch - Generate multiple emails in parallel

Campaign Management (Admin)

  • POST /api/v1/admin/campaigns - Create campaign
  • GET /api/v1/admin/campaigns - List campaigns
  • POST /api/v1/admin/campaigns/{id}/enable - Toggle campaign
  • POST /api/v1/admin/prospects/import - Bulk import prospects (JSON/CSV)
  • POST /api/v1/admin/run_batch - Manually trigger batch send
  • GET /api/v1/admin/sent_emails - View sends
  • GET /api/v1/admin/sent_emails/{id}/events - View send history

Orchestrator (Goal-Based Autonomy)

  • POST /api/v1/orchestrator/run - Execute goal (e.g., "warm up domain with 5 emails")

Webhooks & Tracking

  • POST /webhooks/sendgrid/events - Ingest SendGrid events
  • GET /unsubscribe/{token} - One-click opt-out

Health & Diagnostics

  • GET /health - Liveness check
  • GET /api/v1/health - Component health
  • GET /api/v1/metrics - Performance metrics
  • GET /api/v1/preflight - Configuration readiness

Example Requests

# Generate single email
curl -X POST http://localhost:8000/api/v1/emails/generate \
  -H "Content-Type: application/json" \
  -d '{
    "prospect_name": "Jane Smith",
    "prospect_email": "jane@techcorp.com",
    "company_name": "TechCorp",
    "prospect_role": "VP Engineering"
  }'

# Run orchestrator with goal
curl -X POST http://localhost:8000/api/v1/orchestrator/run \
  -H "Content-Type: application/json" \
  -H "X-Admin-API-Key: your_admin_key" \
  -d '{
    "goal": "Check system health and run 5 test emails"
  }'

# Trigger campaign batch
curl -X POST http://localhost:8000/api/v1/admin/run_batch \
  -H "X-Admin-API-Key: your_admin_key"

🎯 System Architecture

Email Generation Flow (4 Phases)

Input: Prospect Info
  ↓
Phase 1: RESEARCH (Perplexity API)
  β”œβ”€ Fetches real company data (funding, expansion, hiring)
  β”œβ”€ Time: 5-10 seconds (with API call)
  └─ Sources: 1+ citations from Perplexity
  ↓
Phase 2: STRATEGY
  β”œβ”€ Selects tone (professional_warm, direct, conversational)
  β”œβ”€ Chooses approach (direct_pitch, social_proof, urgency)
  β”œβ”€ Builds 4-6 personalization angles
  └─ Each angle scored with confidence (70-95%)
  ↓
Phase 3: GENERATION (Groq LLM)
  β”œβ”€ Unified prompt with all research + strategy
  β”œβ”€ Single optimized LLM call
  β”œβ”€ Model: llama-3.3-70b-versatile (Groq)
  β”œβ”€ Cost: ~$0.00005 per email
  └─ Time: 1-3 seconds
  ↓
Phase 4: QUALITY EVALUATION
  β”œβ”€ Personalization Depth: 0-100
  β”œβ”€ Value Clarity: 0-100
  β”œβ”€ CTA Strength: 0-100
  β”œβ”€ Spam Likelihood: 0-100 (lower is better)
  β”œβ”€ Tone Quality: 0-100
  β”œβ”€ Structure Integrity: check
  β”œβ”€ Compliance Flags: GDPR/CAN-SPAM/CCPA checks
  └─ Verdict: EXCELLENT / APPROVED / NEEDS_REVISION / REJECTED
  ↓
Output: Subject + Body + Quality Metrics

Campaign Automation Flow

CampaignBrain (Autonomous Decisions)
  β”œβ”€ Check: Is it business hours? β†’ Yes/No
  β”œβ”€ Check: Rate limits (100/day, 20/hour) β†’ OK/Over
  β”œβ”€ Query: Prospects (not opted-out, not bounced, not replied)
  β”œβ”€ Score: By conversion probability
  β”œβ”€ Select: Initial outreach OR follow-up (day 2, 4, 7)
  └─ Return: EmailAction objects
  ↓
CampaignScheduler (Batch Execution)
  β”œβ”€ Fetch actions from CampaignBrain
  β”œβ”€ Run email_engine for each prospect (parallel)
  β”œβ”€ Filter: Keep only quality >= threshold (70.0)
  β”œβ”€ Create: Idempotent SentEmail record
  β”œβ”€ Send: Via SendGrid or SMTP
  β”œβ”€ Persist: Update Prospect counters
  └─ Track: Store cost, quality, metadata
  ↓
Webhook Handler (Event Tracking)
  β”œβ”€ Ingest: SendGrid events (delivered, open, click, bounce, spam, unsubscribe)
  β”œβ”€ Update: SentEmail.status
  β”œβ”€ Update: Prospect flags & counters
  └─ Trigger: Phase 4 learning (FeedbackProcessor)
  ↓
FeedbackProcessor (Learning Loop)
  β”œβ”€ Track: Angle success by segment
  β”œβ”€ Negative: Spam complaints, unsubscribes
  β”œβ”€ Positive: Opens, clicks, replies
  └─ Re-weight: Phase 2 angle confidence for next batch

Orchestrator Agent Flow

Goal: "Warm up domain with 10 high-quality emails"
  ↓
Orchestrator Agent (Groq)
  β”œβ”€ Understand goal
  β”œβ”€ Analyze system state
  β”œβ”€ Decide actions (create campaign, import prospects, run batch)
  β”œβ”€ Call available tools:
  β”‚  β”œβ”€ list_campaigns
  β”‚  β”œβ”€ create_campaign
  β”‚  β”œβ”€ import_prospects
  β”‚  β”œβ”€ run_batch
  β”‚  β”œβ”€ get_campaign_stats
  β”‚  β”œβ”€ get_angle_performance
  β”‚  └─ ... 5 more tools
  └─ Report: What was accomplished

βš™οΈ Configuration

Environment Variables (.env)

# === REQUIRED ===

# Groq API (Email Generation - LLM)
GROQ_API_KEY=gsk_your_key_here
GROQ_MODEL=llama-3.3-70b-versatile

# === OPTIONAL but RECOMMENDED ===

# Perplexity API (Company Research)
PERPLEXITY_API_KEY=pplx_your_key_here
RESEARCH_MODE=quick  # skip, quick, deep

# === FOR SENDING EMAILS ===

# SendGrid (Production Email Sending)
SENDGRID_API_KEY=SG.your_key_here
FROM_EMAIL=outreach@yourdomain.com
SENDER_NAME=Your Company

# SMTP Fallback (Development)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your_email@gmail.com
SMTP_PASSWORD=your_app_password

# === CAMPAIGN SETTINGS ===

# Rate Limiting
DAILY_SEND_LIMIT=100
HOURLY_SEND_LIMIT=20

# Quality Thresholds
MIN_QUALITY_SCORE=70.0
MIN_CONFIDENCE_SCORE=0.5

# Timezone
TIMEZONE=America/New_York

# === API & SECURITY ===

# Admin API Authentication
ADMIN_API_KEY=your_secure_admin_key

# Public URL (for unsubscribe links)
PUBLIC_BASE_URL=https://your-domain.com

# === DATABASE ===

# Development (default)
DATABASE_URL=sqlite:///./cold_email_agent.db

# Production (PostgreSQL)
# DATABASE_URL=postgresql://user:password@localhost:5432/dbname

# === SYSTEM ===

# UTF-8 Support (Windows)
PYTHONUTF8=1

# Environment
ENVIRONMENT=development  # development, staging, production

Campaign Configuration

Campaigns are persisted in the database with:

  • Name, enabled flag
  • Goal (book_meeting, nurture, evangelize, etc.)
  • Tone (professional_warm, direct, conversational, etc.)
  • Daily & hourly limits
  • Timezone and business hours
  • Sequence settings (max follow-ups, delay days)
  • Language

Database Models

  • Campaign: Settings, limits, goals, sequences
  • Prospect: Target person, company, engagement data, suppression flags
  • SentEmail: Send attempts, quality metrics, LLM data
  • EmailEvent: Webhook events (delivered, open, click, bounce, etc.)
  • AnglePerformance: Success rates per personalization angle/segment

πŸ§ͺ Testing

Feature Verification Suite

# Test all 6 core features (quick)
python test_features.py

# Results: Orchestrator βœ“ | Campaign Brain βœ“ | Scheduler βœ“ | Senders βœ“ | Webhooks βœ“ | Admin API βœ“

Manual Testing

# Test 1: Email Generation (CLI)
$env:PYTHONUTF8=1
python main.py --demo

# Test 2: Campaign Automation
python run_campaign.py --batch-size 5

# Test 3: API Server
python -m uvicorn app:app --reload
# Then: curl http://localhost:8000/docs

# Test 4: Orchestrator Agent
curl -X POST http://localhost:8000/api/v1/orchestrator/run \
  -H "Content-Type: application/json" \
  -H "X-Admin-API-Key: test" \
  -d '{"goal": "Check system health"}'

Integration Tests

Test files are in tests/ directory (can be extended based on needs)


🐳 Docker & Deployment

Local Docker

# Build image
docker build -t cold-email-agent .

# Run container
docker run -p 8000:8000 --env-file .env cold-email-agent

# Or with compose
docker-compose up -d

Railway Deployment

Railway is pre-configured via Procfile and Dockerfile:

# 1. Connect to Railway
railway link

# 2. Set environment variables
railway variables set GROQ_API_KEY=your_key
railway variables set PERPLEXITY_API_KEY=your_key
railway variables set SENDGRID_API_KEY=your_key

# 3. Deploy
railway up

Environment on Production

Make sure to set:

  • ENVIRONMENT=production
  • ADMIN_API_KEY=secure_random_key
  • DATABASE_URL=postgresql://... (not SQLite)
  • PUBLIC_BASE_URL=https://your-domain.com
  • All API keys (GROQ, Perplexity, SendGrid)

πŸ“Š Monitoring & Observability

Health Endpoints

# Liveness check
GET /health

# Component health
GET /api/v1/health

# Detailed diagnostics
GET /api/v1/health/detailed

Metrics

# System metrics (email engine, routing, LLM stats)
GET /api/v1/metrics

Logging

Structured logging with configurable levels set in .env:

LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR

Logs show:

  • Email generation flow (phases 1-4)
  • Research API calls (Perplexity)
  • LLM selection and costs
  • Campaign brain decisions
  • Email sends and failures

πŸ”’ Security & Compliance

Email Compliance

  • CAN-SPAM compliance (unsubscribe links, from address)
  • GDPR compliance (opt-out tracking, data minimization)
  • CCPA compliance heuristics
  • Role address blocking (info@, support@, etc.)
  • Link density limits

API Security

  • Optional API key authentication (ADMIN_API_KEY)
  • Rate limiting (per admin endpoint)
  • CORS configuration
  • Request validation with Pydantic

Data Security

  • Unsubscribe tokens (opaque, secure)
  • Opted-out prospect exclusion
  • Bounce & spam complaint tracking
  • Auto-halt if safety thresholds exceeded

🎨 Customization

Prompts

All prompts centralized in config/prompts.py:

  • Research instructions
  • Strategy templates
  • Generation prompts
  • Quality evaluation criteria

Edit to customize email tone, structure, or requirements.

Campaign Settings

Modify in database or via /api/v1/admin/campaigns:

  • Campaign name, goal, tone
  • Rate limits (daily/hourly)
  • Business hours window
  • Timezone
  • Follow-up sequence

Personalization Angles

Edit in src/personalization_new/engine.py:

  • Add new angle types
  • Adjust confidence scoring
  • Modify angle selection logic

Quality Thresholds

Set in .env:

MIN_QUALITY_SCORE=70.0      # Minimum to send
MIN_CONFIDENCE_SCORE=0.5    # Minimum angle confidence

πŸ“ˆ Performance Benchmarks

Email Generation (Groq llama-3.3-70b-versatile)

  • Without research: 2-3 seconds, $0.000050
  • With Perplexity: 8-12 seconds, $0.000100
  • Quality score average: 60-80/100
  • Success rate: >95%

Campaign Processing

  • Batch size: 50 emails
  • Processing time: ~30-60 seconds (with research)
  • Throughput: ~1-2 emails/second (parallel)
  • Database writes: Transactional, idempotent

🀝 Contributing

Areas for improvement:

  • Reply classification (IMAP/webhook)
  • Richer personalization signals
  • LinkedIn scraper integration
  • Dashboard UI (React/Next.js)
  • SMS/multi-channel sending
  • Advanced segmentation
  • A/B testing framework
  • Sentiment analysis on replies

πŸ“ License

MIT License - Free for commercial and personal use.


πŸ—ΊοΈ Roadmap

Completed βœ…

  • 4-phase email generation pipeline
  • Perplexity API research integration
  • Campaign brain (autonomous decisions)
  • Campaign scheduler (batch automation)
  • Orchestrator agent (goal-based)
  • FastAPI backend with all endpoints
  • SendGrid integration
  • Webhook event tracking
  • Phase 4 feedback loops
  • Admin API
  • Database persistence
  • Quality evaluation (6 dimensions)
  • Guardrails & safety constraints

In Development / Planned πŸš€

  • Reply classification system (IMAP/webhooks)
  • LinkedIn prospect enrichment
  • Advanced segmentation
  • Web dashboard (React/Next.js)
  • SMS/multi-channel sending
  • A/B testing framework
  • Sentiment analysis on replies
  • Cached personalization banks
  • Self-learning from engagement
  • Calendar integration for timing

πŸ™ Acknowledgments

Built with:

  • Groq: Fast LLM inference
  • Perplexity: Real-time research API
  • SendGrid: Email delivery
  • FastAPI: Modern async web framework
  • SQLAlchemy: Robust ORM
  • Pydantic: Data validation

πŸ“§ Support

For issues or questions:

  • Open an issue on GitHub
  • Check the documentation in code comments
  • Review test_features.py for working examples

Version: 1.0.0
Last Updated: February 2026
Status: Production Ready βœ…

Built for autonomous, compliant cold outreach at scale.

About

AI-powered cold email generation system

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages