Skip to content

Reminder and Proactive Messaging System

Last Updated: December 9, 2025

Overview

This document describes the reminder and proactive messaging system in Archety. The system supports:

  1. User Reminders - One-time and recurring reminders set by users
  2. Proactive Messages - Automated insights from calendar, email, and travel monitoring

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        Background Scheduler                          │
│                    (APScheduler - AsyncIO)                          │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐    │
│   │ Reminder Check  │  │ Calendar Checks │  │ Email Urgency   │    │
│   │  (every 1 min)  │  │  (7:30am daily) │  │ (3x daily)      │    │
│   └────────┬────────┘  └────────┬────────┘  └────────┬────────┘    │
│            │                    │                    │              │
│            └────────────────────┼────────────────────┘              │
│                                 ▼                                   │
│                    ┌─────────────────────────┐                      │
│                    │    SmartScheduler       │                      │
│                    │ (jitter, rate limiting) │                      │
│                    └────────────┬────────────┘                      │
│                                 ▼                                   │
│                    ┌─────────────────────────┐                      │
│                    │   ProactiveSender       │                      │
│                    └────────────┬────────────┘                      │
│                                 ▼                                   │
│                    ┌─────────────────────────┐                      │
│                    │   Edge Agent Manager    │                      │
│                    │   (WebSocket/HTTP)      │                      │
│                    └────────────┬────────────┘                      │
└─────────────────────────────────┼───────────────────────────────────┘
                    ┌─────────────────────────┐
                    │   Mac Mini Edge Agent   │
                    │   (iMessage delivery)   │
                    └─────────────────────────┘

Components

1. Reminder Service (app/scheduler/reminder_service.py)

Manages user reminders with support for:

  • One-time reminders: Send at a specific datetime
  • Daily reminders: Send at a specific time every day
  • Weekly reminders: Send at a specific time on specific day(s)

Key Features: - Timezone-aware scheduling using user's stored timezone - Automatic calculation of next send time for recurring reminders - Support for "minutes before" to remind before an event

Example Usage:

from app.scheduler.reminder_service import get_reminder_service
from datetime import time

service = get_reminder_service()

# Create a weekly reminder for Monday at 1:00 PM (1 hour before 2:00 PM event)
service.create_reminder(
    user_phone="+14155551234",
    title="Shibuya Crossing",
    reminder_type="weekly",
    day_of_week=0,  # Monday
    time_of_day=time(14, 0),  # 2:00 PM local time
    minutes_before=60,  # Remind 1 hour before
)

2. Background Scheduler Service (app/scheduler/background_service.py)

APScheduler-based service that runs scheduled jobs:

Job Schedule Description
reminder_check Every minute Check and send due reminders
morning_calendar_check 7:30 AM daily Analyze calendar for stress
email_urgency_scan 8am, 1pm, 6pm Scan for urgent emails
calendar_events_scan Every 30 min (8am-10pm) Monitor calendar changes
evening_prep 5:30 PM daily Evening preparation reminder
travel_brain Every 20 min (8am-11pm) Flight tracking and travel reminders
cancellation_protector 8am, noon, 4pm, 8pm Warn about cancellation deadlines

Enabling the Scheduler: Set environment variable:

ENABLE_PROACTIVE_SCHEDULER=true

3. User Timezone Storage

Users have a timezone column in the users table:

ALTER TABLE users ADD COLUMN timezone VARCHAR(50) DEFAULT 'America/Los_Angeles';

Supported Values: Any IANA timezone (e.g., America/New_York, Asia/Tokyo, Europe/London)

4. Database Schema (user_reminders table)

CREATE TABLE user_reminders (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_phone VARCHAR(20) NOT NULL,
    persona_id VARCHAR(50) DEFAULT 'sage',

    -- Content
    title VARCHAR(255) NOT NULL,
    description TEXT,

    -- Timing
    reminder_type VARCHAR(20) NOT NULL,  -- one_time, daily, weekly
    remind_at TIMESTAMPTZ,               -- For one-time
    day_of_week INTEGER,                 -- 0=Monday to 6=Sunday
    time_of_day TIME,                    -- In user's local timezone
    minutes_before INTEGER DEFAULT 60,

    -- Linked event (optional)
    linked_event_id VARCHAR(255),
    linked_event_title VARCHAR(255),

    -- Status
    status VARCHAR(20) DEFAULT 'active',  -- active, paused, completed, deleted
    last_sent_at TIMESTAMPTZ,
    next_send_at TIMESTAMPTZ,
    send_count INTEGER DEFAULT 0,

    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

Message Delivery Flow

  1. Scheduler checks for due reminders (every minute)
  2. ReminderService.get_due_reminders() returns reminders where next_send_at <= NOW()
  3. Generate message in Sage's voice
  4. SmartScheduler applies jitter and rate limiting
  5. ProactiveSender routes to edge agent
  6. EdgeAgentManager queues command (WebSocket or HTTP polling)
  7. Mac Mini Edge Agent delivers via iMessage
  8. ReminderService.mark_reminder_sent() updates status and calculates next occurrence

Anti-Hallucination System

Sage's passport now includes explicit capabilities to prevent hallucination:

{
  "capabilities": {
    "can_do": [
      "Have conversations and provide emotional support",
      "Remember things about the user",
      "Search the web for information",
      "Check calendar events IF user has connected Google Calendar via OAuth",
      "Check emails IF user has connected Gmail via OAuth"
    ],
    "cannot_do": [
      "Set reminders or alarms (feature not yet implemented)",
      "Schedule messages for later delivery",
      "Send notifications at specific times"
    ],
    "anti_hallucination": {
      "rule": "NEVER claim to have done something you cannot do",
      "examples_of_violations": [
        "BAD: 'okie setting ur weekly schedule~'",
        "BAD: 'mmk connected! setting reminders'"
      ]
    }
  }
}

Note: When the reminder system is fully integrated with Sage's conversation flow, update the can_do list to include reminder capabilities.

Configuration

Environment Variables

Variable Default Description
ENABLE_PROACTIVE_SCHEDULER false Enable background scheduler

Railway Deployment

To enable proactive messages in Railway:

  1. Go to Railway dashboard
  2. Select the service
  3. Click "Variables"
  4. Add: ENABLE_PROACTIVE_SCHEDULER=true
  5. Redeploy the service

Testing

Test Reminder Creation

from app.scheduler.reminder_service import get_reminder_service
from datetime import time

service = get_reminder_service()

# Create a test reminder for next minute
from datetime import datetime, timedelta
import pytz

reminder = service.create_reminder(
    user_phone="+14155551234",
    title="Test reminder",
    reminder_type="one_time",
    remind_at=datetime.now(pytz.UTC) + timedelta(minutes=2),
    minutes_before=0,
)
print(f"Created reminder: {reminder}")

Check Due Reminders

from app.scheduler.reminder_service import get_reminder_service

service = get_reminder_service()
due = service.get_due_reminders()
print(f"Due reminders: {due}")

Future Enhancements

  1. Natural Language Reminder Parsing - Allow users to say "remind me tomorrow at 3pm"
  2. Calendar Integration - Automatically create reminders for calendar events
  3. Snooze Support - Allow users to snooze reminders
  4. Reminder Preferences - Let users customize reminder timing and frequency
  5. Group Reminders - Reminders that notify multiple users in a group