Proactive Notifications System - Setup & Deployment Guide¶
๐ฏ Overview¶
The proactive notification system enables Sage to automatically alert you about: - โ Urgent emails requiring immediate attention - โ Calendar event changes and conflicts - โ Flight departure reminders and travel updates - โ Cancellation deadlines to avoid fees - โ Morning calendar previews - โ Evening prep reminders
โจ What Was Fixed¶
Issue #1: Workflows Not Registered โ โ โ ¶
Problem: The proactive workflow files existed but were never imported, so they never registered with the system.
Solution:
- Updated app/superpowers/catalog/__init__.py to import all 6 proactive workflows
- Updated app/superpowers/catalog/proactive/__init__.py to export all workflows
Files Changed:
Issue #2: Scheduler Disabled by Default โ โ โ ¶
Problem: The proactive scheduler was disabled by default and required an environment variable to enable.
Solution: Set ENABLE_PROACTIVE_SCHEDULER=true in Railway environment variables
Location: app/main.py:115-124
Issue #3: Outdated LLM Usage โ ๏ธ โ โ ¶
Problem: Workflows were using llm_model_default (GPT-5) instead of llm_model_fast (GPT-5 Mini) for fast analysis.
Solution: Updated all workflows to use GPT-5 Mini for cost-efficient, fast analysis.
Files Changed:
app/superpowers/catalog/proactive/email_urgency.py
app/superpowers/catalog/proactive/calendar_events.py
app/superpowers/catalog/proactive/evening_prep.py
Issue #4: Direct MessageDelivery Usage โ ๏ธ โ โ ¶
Problem: Some workflows were calling MessageDelivery directly (Telegram-only) instead of ProactiveSender (multi-platform).
Solution: Updated workflows to use ProactiveSender which auto-detects platform (Telegram/iMessage).
Files Changed:
app/superpowers/catalog/proactive/email_urgency.py
app/superpowers/catalog/proactive/calendar_events.py
app/superpowers/catalog/proactive/evening_prep.py
Issue #5: Missing Error Handling โ ๏ธ โ โ ¶
Problem: LLM JSON parsing had no handling for markdown code blocks, causing silent failures.
Solution: Added robust JSON parsing with markdown extraction and error logging.
Improvements:
- Handle markdown code blocks (json...)
- Log parsing errors with context
- Graceful fallbacks on failures
- Try/except blocks around all sends
๐ Deployment Steps¶
Step 1: Enable the Scheduler¶
The scheduler is disabled by default. You need to enable it via Railway environment variable:
Option A: Via Railway Dashboard (Recommended)
1. Go to Railway project: https://railway.app/
2. Select the archety-backend service
3. Go to Variables tab
4. Click + New Variable
5. Add: ENABLE_PROACTIVE_SCHEDULER = true
6. Click Deploy to restart with new variable
Option B: Via Railway CLI
Step 2: Commit and Push Changes¶
# Review changes
git status
git diff
# Commit all changes
git add .
git commit -m "fix: Enable proactive notifications system with latest improvements
- Import all 6 proactive workflows in catalog
- Use GPT-5 Mini for fast, cost-efficient analysis
- Use ProactiveSender for multi-platform support (Telegram/iMessage)
- Add robust JSON parsing with markdown handling
- Add comprehensive error logging
- Update email_urgency, calendar_events, and evening_prep workflows"
# Push to Railway for deployment
git push origin claude/email-calendar-alerts-011CUxuEseqDZYvQnTQsYrXT
Step 3: Verify Deployment¶
After deploying, check the logs to confirm the scheduler started:
# Via Railway dashboard: Deployments โ View Logs
# Or via Railway CLI:
railway logs --service archety-backend
Expected log output:
Starting up Persona Passport Orchestrator...
Proactive scheduler started
Scheduler service started with 6 proactive workflows
If scheduler is still disabled, you'll see:
๐ Proactive Workflows Schedule¶
Once enabled, these workflows run automatically:
| Workflow | Schedule | Purpose |
|---|---|---|
| Email Urgency Scan | Every 15 min, 8am-8pm | Scan for urgent emails requiring attention |
| Calendar Events Monitor | Every 30 min, 8am-10pm | Detect calendar changes and conflicts |
| Morning Calendar Check | 7:30 AM daily | Preview today's schedule |
| Evening Prep | 5:30 PM daily | Prep for tomorrow with schedule + tasks |
| Travel Brain | Every 20 min, 8am-11pm | Flight departure reminders, travel alerts |
| Cancellation Protector | 4x daily (8am, noon, 4pm, 8pm) | Warn about cancellation deadlines |
๐ง Technical Architecture¶
Workflow Registration Flow¶
1. app/main.py imports app/superpowers/catalog
2. catalog/__init__.py imports catalog/proactive
3. Each proactive/*.py file calls register_workflow()
4. WorkflowRegistry stores all workflows
5. SchedulerService queries registry and schedules jobs
Scheduler Service Flow¶
1. APScheduler triggers workflow at scheduled time
2. SchedulerService.run_*() gets active users from DB
3. For each user:
- Execute workflow via WorkflowEngine
- Workflow scans Gmail/Calendar (OAuth required)
- LLM analyzes for urgency/importance
- ProactiveSender routes to Telegram or iMessage
- Log notification to database
ProactiveSender Platform Detection¶
# Auto-detects user's platform
def send_proactive_message(user_phone, message_text, priority):
platform = _get_user_platform(user_phone) # Check DB + edge agent
if platform == 'imessage':
return _send_via_imessage(...) # Via EdgeAgentManager
elif platform == 'telegram':
return _send_via_telegram(...) # Via MessageDelivery
else:
return _send_via_messenger(...) # Generic fallback
๐งช Testing Proactive Notifications¶
Test Email Urgency¶
- Send yourself an email with "URGENT" in subject
- Mark it as unread
- Wait up to 15 minutes for next scan
- Check if you receive a Telegram/iMessage alert
Test Travel Brain¶
- Forward a flight confirmation email to yourself
- Ensure it's from last 14 days
- Wait up to 20 minutes for scan
- If flight is within 4-6 hours, you'll get a reminder
Test Calendar Events¶
- Change an existing calendar event time
- Wait up to 30 minutes for scan
- LLM will analyze if change is conversation-worthy
- You'll get alert if change is significant
Manual Trigger (Development)¶
# Run a workflow manually for testing
from app.superpowers.engine import WorkflowEngine
from app.superpowers.workflow import get_workflow_registry
engine = WorkflowEngine()
result = await engine.execute_workflow(
workflow_id="proactive_email_urgency",
user_id="+16463831222", # Your phone/chat ID
trigger_data={'scan_hours': 2, 'user_phone': '+16463831222'}
)
๐ OAuth Requirements¶
Gmail & Calendar access required for most workflows:
- User must authorize OAuth via link:
https://yourdomain.com/auth/google - Grants read-only access to Gmail + Calendar
- Tokens stored in
oauth_tokenstable - Scheduler checks for valid tokens before running
Without OAuth: - Email urgency: Won't run - Calendar events: Won't run - Morning calendar: Won't run - Evening prep: Partial (no email/calendar data) - Travel brain: Won't find flights - Cancellation protector: Won't find deadlines
To check OAuth status:
๐ Troubleshooting¶
Scheduler Not Starting¶
Symptom: Logs show "Proactive scheduler DISABLED"
Solution:
1. Confirm ENABLE_PROACTIVE_SCHEDULER=true is set in Railway
2. Restart the service to pick up the new variable
3. Check logs again for "Proactive scheduler started"
Workflows Not Triggering¶
Symptom: No notifications received after 24 hours
Possible causes:
1. No OAuth tokens - User hasn't authorized Gmail/Calendar
2. No active users - _get_active_users() returns empty list
3. Circuit breaker open - Workflow failed 3+ times and is paused
4. LLM threshold not met - Emails/events not urgent enough
Debug steps:
# Check active users with OAuth tokens
SELECT DISTINCT user_phone FROM oauth_tokens WHERE expires_at > NOW();
# Check recent proactive notifications
SELECT * FROM proactive_notifications
WHERE notified_at > NOW() - INTERVAL '24 hours'
ORDER BY notified_at DESC;
# Check workflow execution logs
# Look for: "Running email urgency scan..." in Railway logs
JSON Parsing Failures¶
Symptom: Logs show "LLM response parsing failed"
This is now handled gracefully:
- Workflow continues without crash
- Error logged with response snippet
- Returns should_notify: false to skip send
- Circuit breaker prevents repeated failures
To investigate:
Messages Not Delivering¶
Symptom: Workflow runs but no message received
Check ProactiveSender logs:
Possible issues:
1. Platform detection failed โ Check users table platform column
2. Telegram bot token invalid โ Check TELEGRAM_BOT_TOKEN env var
3. iMessage edge agent offline โ Check edge agent status
4. User blocked bot โ Check Telegram bot status
๐ Monitoring & Metrics¶
Key Metrics to Track¶
Via Database:
-- Notifications sent per day
SELECT
DATE(notified_at) as date,
notification_type,
COUNT(*) as count
FROM proactive_notifications
WHERE notified_at > NOW() - INTERVAL '7 days'
GROUP BY DATE(notified_at), notification_type
ORDER BY date DESC;
-- Notification success rate (vs workflow runs)
-- This requires adding workflow execution logging
Via Logs:
# Count workflow executions today
railway logs | grep "Running.*scan" | grep $(date +%Y-%m-%d) | wc -l
# Count successful sends today
railway logs | grep "Sent.*alert" | grep $(date +%Y-%m-%d) | wc -l
Expected Patterns¶
Normal operation: - Email scans: ~45/day (every 15 min, 8am-8pm) - Calendar scans: ~28/day (every 30 min, 8am-10pm) - Notifications sent: 3-10/day per user (depends on activity) - LLM cost: ~$0.10-0.30/day per active user (GPT-5 Mini)
Abnormal patterns: - Zero notifications for 24+ hours โ OAuth expired or no activity - 50+ notifications/day โ LLM threshold too low or logic bug - Repeated parsing failures โ LLM output format changed
๐ฐ Cost Optimization¶
Current Optimizations¶
- GPT-5 Mini Usage: Workflows use
llm_model_fast(GPT-5 Mini) instead of GPT-5 - Cost: ~$0.00015/1K tokens (prompt) vs $0.005/1K tokens
-
97% cost reduction for analysis tasks
-
Token Limits: Reduced max_tokens across workflows
- Email urgency: 400 tokens (was 800)
- Calendar events: 600 tokens
-
Evening prep: 400 tokens
-
Email Scanning: Reduced from 50 to 15 emails per scan
-
Snippet-only (no full body) saves tokens in prompts
-
Memory Context: Reduced from 20 to 5 memories per analysis
-
Smaller prompts = faster + cheaper
-
Scheduling Frequency:
- Email urgency: Every 15 min (not 5 min) during waking hours only
- Calendar events: Every 30 min (not every 10 min)
Cost Estimates¶
Per user per day: - Email scans: 45 runs ร \(0.0002 = **\)0.009/day** - Calendar scans: 28 runs ร \(0.0003 = **\)0.008/day** - Travel/cancellation: 10 runs ร \(0.0001 = **\)0.001/day** - Morning/evening: 2 runs ร \(0.0005 = **\)0.001/day**
Total: ~$0.02/user/day or $0.60/user/month
For 100 active users: ~$60/month in LLM costs
๐ Security & Privacy¶
OAuth Token Security¶
- Tokens encrypted at rest in database
- Stored in
oauth_tokenstable withexpires_at - Auto-refresh handled by
TokenManager - Revocation supported via "stop checking my calendar" command
Data Access Principles¶
- Read-only: No write access to Gmail/Calendar
- Scoped: Only request minimum necessary permissions
- Time-limited: Tokens expire and require re-auth
- Transparent: User told exactly what we're looking at
PII Handling¶
- Proactive notifications contain user data (email subjects, calendar events)
- Stored in
proactive_notificationstable with user_phone identifier - NOT shared across users
- Can be deleted via cleanup endpoint
๐ Additional Resources¶
- PRD:
/prd.md(sections on proactive workflows) - Flow Documentation:
/docs/architecture/PROACTIVE_FLOW_COMPLETE.md - Edge Agent Architecture:
/docs/edge/ARCHITECTURE.md(iMessage integration) - Scheduler Service:
/app/scheduler/background_service.py - Workflow Files:
/app/superpowers/catalog/proactive/
โ Checklist for Deployment¶
- Set
ENABLE_PROACTIVE_SCHEDULER=truein Railway - Commit all code changes
- Push to branch
claude/email-calendar-alerts-011CUxuEseqDZYvQnTQsYrXT - Verify deployment succeeded in Railway logs
- Check "Proactive scheduler started" in logs
- Ensure user has OAuth tokens (check
oauth_tokenstable) - Wait 15-30 minutes for first workflow execution
- Verify notification sent to Telegram/iMessage
- Monitor logs for errors or circuit breaker triggers
๐ Success Criteria¶
You'll know the system is working when:
1. โ
Railway logs show "Proactive scheduler started with 6 workflows"
2. โ
Logs show "Running email urgency scan..." every 15 minutes
3. โ
Logs show "Running calendar events scan..." every 30 minutes
4. โ
You receive at least 1-2 proactive notifications per day
5. โ
Notifications are contextually relevant and well-timed
6. โ
Messages appear in your Telegram or iMessage
7. โ
Database shows entries in proactive_notifications table
Last Updated: 2025-11-09 Implemented by: Claude (Session: 011CUxuEseqDZYvQnTQsYrXT)