Writing Tasks¶
Tasks are the core of Leo's scheduling system. Each task is a prompt file that tells the assistant what to do when cron triggers it.
Anatomy of a Task¶
A task has two parts:
- Configuration in
leo.yaml— schedule, model, channels, routing - Prompt file in the task's workspace — instructions for the assistant
Configuration¶
tasks:
daily-briefing:
schedule: "0 7 * * *"
timezone: America/New_York
prompt_file: reports/daily-briefing.md
model: opus
max_turns: 20
channels: [plugin:telegram@claude-plugins-official]
notify_on_fail: true
enabled: true
silent: true
Prompt File¶
The prompt file is a plain markdown file with instructions:
# Daily Briefing
Check the following and compile a morning briefing:
1. Scan my inbox for anything urgent
2. Check today's calendar for meetings
3. Review any open PRs that need my attention
4. Check for breaking news in my industry
Format as a concise message. Deliver it via the configured channel plugin
using its MCP messaging tool.
What Leo Adds¶
When leo run <task> executes, it assembles the final prompt. You write the prompt file; Leo adds a silent preamble if silent: true and nothing else.
Silent Preamble (if silent: true)¶
Leo prepends instructions telling the assistant to:
- Work without narration or progress updates
- Only deliver output via a configured channel if there's something meaningful
- Output
NO_REPLYif there's nothing to report
Channels¶
Leo passes the task's channels: list to the spawned Claude process via the LEO_CHANNELS environment variable. The agent picks up its configured channels and uses whatever MCP tool the channel plugin exposes (e.g. the Telegram plugin's reply tool) to send its final message. Leo does not hardcode any channel-specific protocol.
Examples¶
Periodic Check¶
A task that runs every 30 minutes during waking hours and only messages when something needs attention:
# leo.yaml
tasks:
checks:
schedule: "0,30 7-22 * * *"
prompt_file: prompts/checks.md
model: sonnet
max_turns: 10
channels: [plugin:telegram@claude-plugins-official]
enabled: true
silent: true # silent: only report if something needs attention
<!-- prompts/checks.md -->
# Periodic Check
Run through this checklist. Only report items that need my attention.
- [ ] Unread messages that are urgent or time-sensitive
- [ ] Calendar events in the next 2 hours
- [ ] Pending tasks or reminders that are due
- [ ] Any alerts or notifications that need action
If everything is clear, output NO_REPLY.
If something needs attention, deliver a concise summary via your configured channel.
Weekly Report¶
A longer-running task that compiles a weekly summary:
tasks:
weekly-report:
schedule: "0 9 * * 1" # Monday at 9 AM
prompt_file: reports/weekly.md
model: opus # use opus for deeper analysis
max_turns: 30
channels: [plugin:telegram@claude-plugins-official]
enabled: true
<!-- reports/weekly.md -->
# Weekly Report
Compile a summary of the past week:
1. Key accomplishments and milestones
2. Open items and blockers
3. Upcoming deadlines this week
4. Recommendations or suggestions
Format for easy reading on mobile.
Custom Monitoring¶
A task that monitors something specific:
tasks:
repo-monitor:
schedule: "0 */4 * * *" # every 4 hours
prompt_file: reports/repo-monitor.md
model: sonnet
max_turns: 15
enabled: true
silent: true
<!-- reports/repo-monitor.md -->
# Repository Monitor
Check the following repositories for activity:
- github.com/myorg/main-app
- github.com/myorg/api-service
Look for:
- New PRs that need review
- Failed CI builds
- Security advisories
- Dependency updates
Only report if there's something actionable.
Task with Custom Workspace¶
A task that operates in a specific project directory:
tasks:
project-check:
schedule: "0 9 * * 1-5"
workspace: ~/projects/my-app # use this directory instead of default
prompt_file: .leo/daily-check.md
model: sonnet
max_turns: 10
enabled: true
silent: true
Best Practices¶
- Keep prompts focused — one clear objective per task
- Use silent mode for frequent checks to avoid notification spam
- Set appropriate max_turns — simple checks need fewer turns than complex analysis
- Choose the right model — use
sonnetfor routine tasks,opusfor tasks requiring deeper reasoning - Include output format guidance — tell the assistant how to format its final message for your channel
- Test manually first — run
leo run <task>before relying on the schedule
Creating a New Task¶
# 1. Write your prompt file
vim ~/.leo/workspace/reports/my-task.md
# 2. Add the task interactively
leo task add
# 3. Verify it's loaded
leo task list
Or edit leo.yaml directly and run leo service reload to pick up the changes in the running daemon.
See Also¶
leo task— managing tasksleo run— executing tasks- Scheduling — cron expressions and timezone handling
- Config Reference — full task field specification