Features: - Multi-platform bot (Slack, Telegram) - Memory system with SQLite FTS - Tool use capabilities (file ops, commands) - Scheduled tasks system - Dynamic model switching (/sonnet, /haiku) - Prompt caching for cost optimization Optimizations: - Default to Haiku 4.5 (12x cheaper) - Reduced context: 3 messages, 2 memory results - Optimized SOUL.md (48% smaller) - Automatic caching when using Sonnet (90% savings) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
8.7 KiB
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:
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
schedule: "hourly"
Runs every hour on the hour (00:00, 01:00, 02:00, etc.)
Daily
schedule: "daily 08:00"
schedule: "daily 18:30"
Runs every day at the specified time (24-hour format)
Weekly
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)
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
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
python example_bot_with_scheduler.py
📝 Example Tasks
1. Daily Weather Report (sent to Slack)
- 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:
- At 8:00 AM, scheduler triggers task
- Agent receives the prompt
- Agent generates weather report (or notes it needs API)
- Output sent to Slack channel
C12345
2. Evening Summary (sent to Telegram)
- 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)
- 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)
- 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
scheduler = TaskScheduler(agent)
# Trigger a task immediately (ignoring schedule)
scheduler.run_task_now("morning-weather")
Task Status
# List all tasks with their status
for task in scheduler.list_tasks():
print(f"{task['name']}: next run at {task['next_run']}")
Custom Callback
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
- 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
- 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
- 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
- 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
- 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:
- 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
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: truein 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!)