Architecture: GitHub Actions for orchestration + Vercel for web layer.
GitHub Actions (Thursday 9am UTC)
↓
Runs: python3 orchestrator_v2.py
↓
7 Managed Agents → newsletter generated → email sent
↓
Commits latest_issue.html back to repo
↓
Vercel auto-deploys → /latest endpoint serves new issue
Why this split?
Go to your GitHub repo → Settings → Secrets and variables → Actions → New repository secret
Add these secrets:
| Secret Name | Value | Required |
|---|---|---|
ANTHROPIC_API_KEY |
Your Anthropic API key | ✅ Yes |
SMTP_USER |
Gmail address | ✅ Yes |
SMTP_PASSWORD |
Gmail App Password | ✅ Yes |
APP_BASE_URL |
https://your-domain.vercel.app |
✅ Yes |
SUPABASE_URL |
Your Supabase project URL | ✅ Yes — auto-fetches subscribers |
SUPABASE_ANON_KEY |
Supabase anon key | ✅ Yes — auto-fetches subscribers |
RECIPIENT_EMAILS |
email1@x.com,email2@y.com |
❌ Fallback only (used if Supabase fails) |
SMTP_HOST |
smtp.gmail.com (default) |
❌ No |
SMTP_PORT |
587 (default) |
❌ No |
SMTP_FROM |
Sender (defaults to SMTP_USER) | ❌ No |
Subscriber List Source:
subscribers table (auto-fetched on every run)RECIPIENT_EMAILS env var (only if Supabase unavailable)This means subscribe/unsubscribe via the website automatically takes effect on the next Thursday’s send. No manual env var updates needed.
SMTP_PASSWORDThese are needed for the web layer (status endpoint, /latest serving).
Go to Vercel Dashboard → Your Project → Settings → Environment Variables
Same secrets as GitHub (Vercel needs them for the Flask app + status endpoint).
cd /Users/pranamyavadlamani/Desktop/agent_app
git add .
git commit -m "deploy: github actions + vercel web layer"
git push origin main
Vercel auto-deploys the web layer. GitHub Actions auto-installs the workflow.
Before waiting until Thursday, trigger manually:
Expected output:
✓ Setup Python
✓ Install dependencies
✓ Run orchestrator
- Memory agent runs
- Research (parallel) runs
- Evaluator runs
- Writer/Critic loop runs
- Delivery runs (email sent)
✓ Commit latest issue back to repo
✓ Upload run artifacts
After successful run:
latest_issue.html committed to repo/latest page shows new newsletterIn .github/workflows/newsletter.yml:
on:
schedule:
- cron: '0 9 * * 4' # Thursday 9am UTC
In GitHub Actions UI, click “Run workflow” with optional session_id:
Each run uploads logs + run summary as GitHub artifacts (30-day retention):
logs/ — structured JSON logs per sessionruns/ — run summary metricsbriefs/ — full agent output logsmemory_local/ — Memory Stores JSONL filesDownload from Actions → click run → Artifacts section
While a run is happening:
# Check status (Vercel reads its own logs)
curl https://your-domain.vercel.app/api/status?session_id=<id>
# See recent runs (last 20)
curl https://your-domain.vercel.app/api/status?recent=true
Note: Vercel’s /api/status reads from Vercel’s filesystem. Since GitHub Actions runs the orchestrator, Vercel won’t have full state unless you set up shared storage. For now:
/latest: shows last published newsletterEdit .github/workflows/newsletter.yml:
on:
schedule:
- cron: '0 9 * * 4' # ← Change this
Common schedules:
0 9 * * 4 → Every Thursday at 9am UTC
0 9 * * 1 → Every Monday at 9am UTC
0 9 * * 0 → Every Sunday at 9am UTC
0 9 * * 1-5 → Every weekday at 9am UTC
0 0 1 * * → First of month at midnight UTC
Push the change → workflow updates automatically.
Check:
Note: GitHub Actions cron is best-effort. May run within ~15 min of scheduled time.
Fix: Workflow already has permissions: contents: write. If still failing:
Check:
Check:
ANTHROPIC_API_KEY is valid and has creditsGitHub Actions: 6 hour limit (job-level), workflow has timeout-minutes: 30. If your pipeline exceeds 30 min, increase timeout-minutes in the workflow file.
| Service | Cost | Notes |
|---|---|---|
| GitHub Actions | Free | 2000 min/month for private repos, unlimited for public |
| Vercel Hobby | Free | Web layer only (no cron needed now) |
| Anthropic API | ~$2-8/run | Token usage by Managed Agents |
| Gmail SMTP | Free | Rate limited by Gmail |
Monthly estimate (4 runs): ~$8-32 in Anthropic API costs.
If something breaks after a deployment:
git revert <commit> then push# Run orchestrator locally (uses .env file)
python3 orchestrator_v2.py
# Resume a session
python3 orchestrator_v2.py --session-id newsletter_...
# Run a single step (debug)
python3 orchestrator_v2.py --session-id newsletter_... --step evaluate
# Check status
python3 api/status.py newsletter_...
# Recent runs
python3 api/status.py recent
# Run web app locally
python3 app.py
# → http://127.0.0.1:5000
If migrating from previous Vercel cron setup:
.github/workflows/newsletter.ymlcrons from vercel.json.gitignore to allow latest_issue.*/latest updatedSee:
ARCHITECTURE.md — full system designMIGRATION.md — Phase 1/2/3 migration historyorchestrator_v2.py — implementation