# Scheduled Tasks Guide This document explains how to use the **TaskScheduler** system for cron-like scheduled tasks that require Agent/LLM execution. ## 🎯 What's the Difference? ### Heartbeat (heartbeat.py) - Simple Health Checks **Use for:** Background health monitoring - ✅ Interval-based (every N minutes) - ✅ Active hours restriction (8am-10pm) - ✅ Uses Agent/LLM for checklist processing - ✅ Alerts when something needs attention - ❌ No specific time scheduling - ❌ No message sending to platforms **Example:** Check for stale tasks every 30 minutes during work hours ### TaskScheduler (scheduled_tasks.py) - Scheduled Agent Tasks **Use for:** Scheduled tasks requiring Agent execution - ✅ Cron-like scheduling (specific times) - ✅ Uses Agent/LLM to generate content - ✅ Can send output to Slack/Telegram - ✅ Daily, weekly, hourly schedules - ✅ Multiple tasks with different schedules - ✅ Manual task triggering **Example:** Send weather report to Slack every day at 8am and 6pm ## 📋 Task Configuration Tasks are defined in `config/scheduled_tasks.yaml`: ```yaml tasks: - name: morning-weather prompt: | Good morning! Provide: 1. Weather forecast 2. Pending tasks 3. Daily motivation schedule: "daily 08:00" enabled: true send_to_platform: "slack" send_to_channel: "C12345" username: "scheduler" ``` ### Configuration Fields | Field | Required | Description | Example | |-------|----------|-------------|---------| | `name` | ✅ | Unique task identifier | `"morning-weather"` | | `prompt` | ✅ | Message sent to Agent | `"Provide weather report"` | | `schedule` | ✅ | When to run | `"daily 08:00"` | | `enabled` | ❌ | Enable/disable task | `true` (default: `true`) | | `send_to_platform` | ❌ | Messaging platform | `"slack"`, `"telegram"`, or `null` | | `send_to_channel` | ❌ | Channel/chat ID | `"C12345"` or `"123456789"` | | `username` | ❌ | Agent memory username | `"scheduler"` (default) | ## ⏰ Schedule Formats ### Hourly ```yaml schedule: "hourly" ``` Runs every hour on the hour (00:00, 01:00, 02:00, etc.) ### Daily ```yaml schedule: "daily 08:00" schedule: "daily 18:30" ``` Runs every day at the specified time (24-hour format) ### Weekly ```yaml schedule: "weekly mon 09:00" schedule: "weekly fri 17:00" ``` Runs every week on the specified day at the specified time **Day codes:** `mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun` ## 🚀 Integration with Bot ### Option 1: Standalone (No Messaging) ```python from agent import Agent from scheduled_tasks import TaskScheduler agent = Agent(provider="claude") scheduler = TaskScheduler(agent) scheduler.start() # Tasks run, outputs logged locally ``` ### Option 2: With Messaging Platforms ```python from adapters.runtime import AdapterRuntime from scheduled_tasks import TaskScheduler # Create runtime with adapters runtime = AdapterRuntime(agent) runtime.add_adapter(slack_adapter) # Create scheduler scheduler = TaskScheduler(agent) # Register adapters so scheduler can send messages scheduler.add_adapter("slack", slack_adapter) scheduler.add_adapter("telegram", telegram_adapter) # Start both await runtime.start() scheduler.start() ``` ### Option 3: Use Example Bot ```bash python example_bot_with_scheduler.py ``` ## 📝 Example Tasks ### 1. Daily Weather Report (sent to Slack) ```yaml - name: weather-report prompt: | Provide today's weather report: 1. Current conditions 2. Forecast for the day 3. Any weather alerts Note: You may need to say you don't have API access, or suggest integrating a weather API. schedule: "daily 08:00" enabled: true send_to_platform: "slack" send_to_channel: "C12345" ``` **How it works:** 1. At 8:00 AM, scheduler triggers task 2. Agent receives the prompt 3. Agent generates weather report (or notes it needs API) 4. Output sent to Slack channel `C12345` ### 2. Evening Summary (sent to Telegram) ```yaml - name: evening-summary prompt: | End of day summary: 1. What did we accomplish today? 2. Any pending tasks? 3. Preview of tomorrow schedule: "daily 18:00" enabled: true send_to_platform: "telegram" send_to_channel: "123456789" ``` ### 3. Hourly Health Check (local only) ```yaml - name: health-check prompt: | Quick health check: - Any stale tasks (>24h)? - Memory system healthy? Respond "HEALTHY" or describe issues. schedule: "hourly" enabled: true # No send_to_platform = local logging only ``` ### 4. Weekly Team Review (Friday 5pm) ```yaml - name: weekly-review prompt: | Friday wrap-up! Provide: 1. Week highlights 2. Metrics (tasks completed) 3. Lessons learned 4. Next week goals schedule: "weekly fri 17:00" enabled: true send_to_platform: "slack" send_to_channel: "C12345" ``` ## 🔧 Advanced Usage ### Manual Task Execution ```python scheduler = TaskScheduler(agent) # Trigger a task immediately (ignoring schedule) scheduler.run_task_now("morning-weather") ``` ### Task Status ```python # List all tasks with their status for task in scheduler.list_tasks(): print(f"{task['name']}: next run at {task['next_run']}") ``` ### Custom Callback ```python def on_task_complete(task, response): print(f"Task {task.name} completed!") # Custom logic here (logging, alerts, etc.) scheduler.on_task_complete = on_task_complete ``` ### Integration with Weather API ```yaml - name: real-weather prompt: | Get weather from API and provide report: Location: New York API: Use the weather_api tool if available Format the response as: 🌤️ Current: [temp] [conditions] 📅 Today: [forecast] ⚠️ Alerts: [any alerts] schedule: "daily 08:00" enabled: true ``` Then add a weather API tool to your agent (via hooks or skills). ## 📊 Use Cases ### 1. **Daily Standup Bot** ```yaml - name: standup-reminder prompt: "Send standup reminder with today's priorities" schedule: "daily 09:00" send_to_platform: "slack" send_to_channel: "C_TEAM" ``` ### 2. **Build Health Reports** ```yaml - name: build-status prompt: "Check CI/CD status and report any failures" schedule: "hourly" send_to_platform: "slack" send_to_channel: "C_ENGINEERING" ``` ### 3. **Customer Metrics** ```yaml - name: daily-metrics prompt: "Summarize customer metrics from yesterday" schedule: "daily 10:00" send_to_platform: "slack" send_to_channel: "C_METRICS" ``` ### 4. **Weekly Newsletter** ```yaml - name: newsletter prompt: "Generate weekly newsletter with highlights" schedule: "weekly fri 16:00" send_to_platform: "slack" send_to_channel: "C_ALL_HANDS" ``` ## 🎯 Choosing Between Heartbeat and Scheduler | Feature | Heartbeat | TaskScheduler | |---------|-----------|---------------| | **Purpose** | Health monitoring | Scheduled content generation | | **Scheduling** | Interval (every N min) | Cron-like (specific times) | | **Agent/LLM** | ✅ Yes | ✅ Yes | | **Messaging** | ❌ No | ✅ Yes (Slack, Telegram) | | **Active hours** | ✅ Yes | ❌ No (always runs) | | **Use SDK** | ✅ Yes | ✅ Yes | | **Config** | HEARTBEAT.md | scheduled_tasks.yaml | **Use both together:** - **Heartbeat** for background health checks - **TaskScheduler** for user-facing scheduled reports ## 🚦 Getting Started ### 1. Edit Configuration Edit `config/scheduled_tasks.yaml`: ```yaml - name: my-task prompt: "Your prompt here" schedule: "daily 10:00" enabled: true send_to_platform: "slack" send_to_channel: "YOUR_CHANNEL_ID" ``` ### 2. Get Channel IDs **Slack:** - Right-click channel → View channel details → Copy ID - Format: `C01234ABCDE` **Telegram:** - For groups: Use @userinfobot - For DMs: Your user ID (numeric) ### 3. Run the Bot ```bash python example_bot_with_scheduler.py ``` ### 4. Monitor Tasks Tasks will run automatically. Check console output: ``` [Scheduler] Executing task: morning-weather [Scheduler] ✓ Task completed: morning-weather [Scheduler] ✓ Sent to slack:C12345 [Scheduler] Next run for morning-weather: 2026-02-13 08:00 ``` ## 🔐 Security Notes - **Credentials**: Store in environment variables - **Channel IDs**: Keep in config (not secrets, but control access) - **Prompts**: Review before enabling (agent will execute them) - **Rate limits**: Be mindful of hourly tasks + API limits ## 🐛 Troubleshooting **Task not running:** - Check `enabled: true` in config - Verify schedule format - Check console for errors **Message not sent:** - Verify channel ID is correct - Check adapter is registered - Ensure bot has permissions in channel **Wrong time:** - Times are in local server timezone - Use 24-hour format (08:00, not 8am) ## 📚 Resources - **Example:** `example_bot_with_scheduler.py` - **Config:** `config/scheduled_tasks.yaml` - **Code:** `scheduled_tasks.py` - **Old heartbeat:** `heartbeat.py` (still works!)