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)
- Phase 1 - Research: Perplexity API fetches real company data (funding, expansion, hiring)
- Phase 2 - Strategy: Intelligent router selects tone, approach, and personalization angles with confidence scores
- Phase 3 - Generation: Groq LLM generates personalized email body (single optimized call)
- Phase 4 - Quality: Deterministic evaluator scores across 6 dimensions (personalization, value, CTA, spam, tone, structure)
-
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
- 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
- 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
- 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
- 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
- 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)
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
# 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# 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# 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# Run batch campaign processing
python run_campaign.py --batch-size 10
# Expected: Autonomous prospect selection, rate-limit enforcement, email generation# 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)# Run comprehensive feature verification
python test_features.py
# Results: 6/6 features verified (orchestrator, campaign brain, scheduler, senders, webhooks, admin API)POST /api/v1/emails/generate- Generate single personalized emailPOST /api/v1/emails/batch- Generate multiple emails in parallel
POST /api/v1/admin/campaigns- Create campaignGET /api/v1/admin/campaigns- List campaignsPOST /api/v1/admin/campaigns/{id}/enable- Toggle campaignPOST /api/v1/admin/prospects/import- Bulk import prospects (JSON/CSV)POST /api/v1/admin/run_batch- Manually trigger batch sendGET /api/v1/admin/sent_emails- View sendsGET /api/v1/admin/sent_emails/{id}/events- View send history
POST /api/v1/orchestrator/run- Execute goal (e.g., "warm up domain with 5 emails")
POST /webhooks/sendgrid/events- Ingest SendGrid eventsGET /unsubscribe/{token}- One-click opt-out
GET /health- Liveness checkGET /api/v1/health- Component healthGET /api/v1/metrics- Performance metricsGET /api/v1/preflight- Configuration readiness
# 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"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
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
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
# === 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, productionCampaigns 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
- 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
# Test all 6 core features (quick)
python test_features.py
# Results: Orchestrator β | Campaign Brain β | Scheduler β | Senders β | Webhooks β | Admin API β# 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"}'Test files are in tests/ directory (can be extended based on needs)
# 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 -dRailway 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 upMake sure to set:
ENVIRONMENT=productionADMIN_API_KEY=secure_random_keyDATABASE_URL=postgresql://...(not SQLite)PUBLIC_BASE_URL=https://your-domain.com- All API keys (GROQ, Perplexity, SendGrid)
# Liveness check
GET /health
# Component health
GET /api/v1/health
# Detailed diagnostics
GET /api/v1/health/detailed# System metrics (email engine, routing, LLM stats)
GET /api/v1/metricsStructured logging with configurable levels set in .env:
LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERRORLogs show:
- Email generation flow (phases 1-4)
- Research API calls (Perplexity)
- LLM selection and costs
- Campaign brain decisions
- Email sends and failures
- 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
- Optional API key authentication (
ADMIN_API_KEY) - Rate limiting (per admin endpoint)
- CORS configuration
- Request validation with Pydantic
- Unsubscribe tokens (opaque, secure)
- Opted-out prospect exclusion
- Bounce & spam complaint tracking
- Auto-halt if safety thresholds exceeded
All prompts centralized in config/prompts.py:
- Research instructions
- Strategy templates
- Generation prompts
- Quality evaluation criteria
Edit to customize email tone, structure, or requirements.
Modify in database or via /api/v1/admin/campaigns:
- Campaign name, goal, tone
- Rate limits (daily/hourly)
- Business hours window
- Timezone
- Follow-up sequence
Edit in src/personalization_new/engine.py:
- Add new angle types
- Adjust confidence scoring
- Modify angle selection logic
Set in .env:
MIN_QUALITY_SCORE=70.0 # Minimum to send
MIN_CONFIDENCE_SCORE=0.5 # Minimum angle confidence- Without research: 2-3 seconds, $0.000050
- With Perplexity: 8-12 seconds, $0.000100
- Quality score average: 60-80/100
- Success rate: >95%
- Batch size: 50 emails
- Processing time: ~30-60 seconds (with research)
- Throughput: ~1-2 emails/second (parallel)
- Database writes: Transactional, idempotent
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
MIT License - Free for commercial and personal use.
- 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
- 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
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
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.