scheduler Agent
Run ensembles on a schedule. Cron syntax, distributed execution.Basic Usage
Copy
agents:
- name: schedule
agent: scheduler
inputs:
cron: "0 0 * * *" # Daily at midnight
ensemble: daily-report
inputs:
date: ${new Date().toISOString()}
Inputs
Copy
inputs:
cron:
type: string
required: true
description: Cron expression
ensemble:
type: string
required: true
description: Ensemble to execute
inputs:
type: object
description: Inputs for ensemble
timezone:
type: string
default: UTC
description: Timezone for cron
enabled:
type: boolean
default: true
description: Enable/disable schedule
Cron Syntax
Standard cron format:Copy
minute (0 - 59)
hour (0 - 23)
day of month (1 - 31)
month (1 - 12)
day of week (0 - 6) (Sunday to Saturday)
* * * * *
Common Patterns
Copy
# Every minute
cron: "* * * * *"
# Every 5 minutes
cron: "*/5 * * * *"
# Every hour
cron: "0 * * * *"
# Daily at midnight
cron: "0 0 * * *"
# Daily at 3 AM
cron: "0 3 * * *"
# Weekdays at 9 AM
cron: "0 9 * * 1-5"
# First day of month
cron: "0 0 1 * *"
# Every Sunday at noon
cron: "0 12 * * 0"
Configuration
Daily Report
Copy
agents:
- name: schedule-report
agent: scheduler
inputs:
cron: "0 8 * * *" # 8 AM daily
ensemble: generate-report
timezone: America/New_York
inputs:
recipients: [${env.REPORT_EMAILS}]
Hourly Sync
Copy
agents:
- name: schedule-sync
agent: scheduler
inputs:
cron: "0 * * * *" # Every hour
ensemble: sync-data
inputs:
source: ${env.SOURCE_DB}
target: ${env.TARGET_DB}
Weekly Cleanup
Copy
agents:
- name: schedule-cleanup
agent: scheduler
inputs:
cron: "0 2 * * 0" # Sunday 2 AM
ensemble: cleanup-old-data
inputs:
days_old: 90
Advanced Patterns
Multiple Schedules
Copy
ensemble: scheduled-tasks
agents:
# Daily report
- name: daily-report
agent: scheduler
inputs:
cron: "0 8 * * *"
ensemble: generate-report
# Hourly sync
- name: hourly-sync
agent: scheduler
inputs:
cron: "0 * * * *"
ensemble: sync-data
# Weekly backup
- name: weekly-backup
agent: scheduler
inputs:
cron: "0 3 * * 0"
ensemble: backup-database
Conditional Execution
Copy
agents:
- name: check-config
operation: storage
config:
type: kv
action: get
key: schedule-enabled
- name: schedule
condition: ${check-config.output.enabled}
agent: scheduler
inputs:
cron: "0 0 * * *"
ensemble: daily-task
Dynamic Scheduling
Copy
agents:
- name: get-schedule
operation: storage
config:
type: d1
query: SELECT cron, ensemble, inputs FROM schedules WHERE active = 1
- name: create-schedules
operation: code
config:
code: |
const schedules = ${get-schedule.output};
return {
schedules: schedules.map(s => ({
cron: s.cron,
ensemble: s.ensemble,
inputs: JSON.parse(s.inputs)
}))
};
With Error Handling
Copy
ensemble: scheduled-task
agents:
- name: execute
operation: code
config:
code: |
try {
// Task logic
return { success: true };
} catch (error) {
return { success: false, error: error.message };
}
- name: notify-failure
condition: ${!execute.output.success}
operation: email
config:
to: ${env.ADMIN_EMAIL}
subject: "Scheduled task failed"
body: |
Task: ${input.task_name}
Error: ${execute.output.error}
Time: ${new Date().toISOString()}
Complete Examples
Daily Data Pipeline
Copy
ensemble: daily-pipeline
agents:
# 1. Extract from source
- name: extract
operation: http
config:
url: ${env.SOURCE_API}/data
headers:
Authorization: Bearer ${env.API_KEY}
# 2. Transform
- name: transform
agent: transformer
inputs:
data: ${extract.output.body}
template: ${component.transform-template@v1.0.0}
# 3. Load to database
- name: load
operation: storage
config:
type: d1
query: INSERT INTO daily_data (date, data) VALUES (?, ?)
params:
- ${new Date().toISOString()}
- ${JSON.stringify(transform.output)}
# 4. Send report
- name: report
operation: email
config:
to: [${env.REPORT_EMAILS}]
subject: "Daily Data Pipeline - ${new Date().toISOString()}"
body: |
Pipeline completed successfully.
Records processed: ${transform.output.length}
# Schedule it
---
ensemble: scheduler-config
agents:
- name: schedule-pipeline
agent: scheduler
inputs:
cron: "0 1 * * *" # 1 AM daily
ensemble: daily-pipeline
timezone: UTC
Hourly Health Check
Copy
ensemble: health-check
agents:
# Check services
- name: check-api
agent: fetcher
inputs:
url: ${env.API_URL}/health
timeout: 5000
- name: check-database
operation: storage
config:
type: d1
query: SELECT 1
# Alert on failure
- name: alert
condition: ${check-api.failed || check-database.failed}
operation: sms
config:
to: ${env.ON_CALL_PHONE}
body: |
Health check failed!
API: ${check-api.failed ? 'DOWN' : 'UP'}
DB: ${check-database.failed ? 'DOWN' : 'UP'}
# Schedule it
---
ensemble: scheduler-config
agents:
- name: schedule-health-check
agent: scheduler
inputs:
cron: "*/15 * * * *" # Every 15 minutes
ensemble: health-check
Monthly Cleanup
Copy
ensemble: monthly-cleanup
agents:
# Delete old records
- name: cleanup-logs
operation: storage
config:
type: d1
query: DELETE FROM logs WHERE created_at < date('now', '-90 days')
- name: cleanup-cache
operation: storage
config:
type: kv
action: delete
key: ${input.stale_keys}
# Vacuum database
- name: vacuum
operation: storage
config:
type: d1
query: VACUUM
# Report
- name: report
operation: email
config:
to: [${env.ADMIN_EMAIL}]
subject: "Monthly Cleanup Complete"
body: |
Logs deleted: ${cleanup-logs.output.changes}
Cache cleared: ${cleanup-cache.output.count}
Database vacuumed
# Schedule it
---
ensemble: scheduler-config
agents:
- name: schedule-cleanup
agent: scheduler
inputs:
cron: "0 3 1 * *" # 1st of month at 3 AM
ensemble: monthly-cleanup
Best Practices
1. Use UTC for ConsistencyCopy
timezone: UTC # Avoid DST issues
Copy
ensemble: scheduled-task
agents:
- name: check-already-run
operation: storage
config:
type: kv
action: get
key: task-${new Date().toISOString().split('T')[0]}
- name: execute
condition: ${!check-already-run.output}
Copy
agents:
- name: log-execution
operation: storage
config:
type: d1
query: INSERT INTO execution_log (task, timestamp, status) VALUES (?, ?, ?)
params:
- ${input.task_name}
- ${Date.now()}
- success
Copy
agents:
- name: execute
operation: code
- name: retry-on-failure
condition: ${execute.failed}
agent: scheduler
inputs:
cron: "*/5 * * * *" # Retry in 5 minutes
ensemble: ${input.ensemble}
enabled: ${execute.error.retryable}
Copy
# Use short intervals for testing
cron: "* * * * *" # Every minute
# Then switch to production
cron: "0 0 * * *" # Daily
Monitoring
Track scheduled executions:Copy
ensemble: monitor-schedules
agents:
- name: query-executions
operation: storage
config:
type: d1
query: |
SELECT task, COUNT(*) as count, MAX(timestamp) as last_run
FROM execution_log
WHERE timestamp > datetime('now', '-24 hours')
GROUP BY task
- name: check-missing
operation: code
config:
code: |
const executions = ${query-executions.output};
const expected = ['daily-report', 'hourly-sync'];
const missing = expected.filter(task =>
!executions.find(e => e.task === task)
);
return { missing };
- name: alert
condition: ${check-missing.output.missing.length > 0}
operation: email
config:
to: ${env.ADMIN_EMAIL}
subject: "Missing scheduled executions"
body: |
These tasks haven't run in 24 hours:
${check-missing.output.missing.join(', ')}
Limitations
- Minimum interval: 1 minute
- Maximum concurrent: 100 schedules per account
- Execution timeout: 30 minutes per run
- No guaranteed ordering: Concurrent executions may overlap

