372 lines
8.7 KiB
Markdown
372 lines
8.7 KiB
Markdown
|
|
# 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!)
|