Overview
Background agents are defined as Markdown files in theagents/ directory and scheduled via ~/.rowboat/config/agent-schedule.json. The background runner polls every minute to check for agents that need to run.
Runner Implementation:
apps/x/packages/core/src/agent-schedule/runner.ts:1The runner executes as a background service, managing schedules, timeouts, and state persistence.Schedule Configuration
Configuration File
Schedules are defined in~/.rowboat/config/agent-schedule.json:
Schedule Types
Cron Schedule
Cron Schedule
Runs at exact times defined by cron expressionCommon expressions:Location:
*/5 * * * *- Every 5 minutes0 8 * * *- Every day at 8am0 9 * * 1- Every Monday at 9am0 0 1 * *- First day of every month at midnight0 */2 * * *- Every 2 hours30 14 * * 1-5- Weekdays at 2:30pm
apps/x/packages/core/src/agent-schedule/runner.ts:62Window Schedule
Window Schedule
Runs once during a time window (randomized)The agent runs once at a random time within the window. Use this for flexible timing (“sometime in the morning” rather than “exactly at 8am”).Next run calculation:Location:
apps/x/packages/core/src/agent-schedule/runner.ts:72Once Schedule
Once Schedule
Runs exactly once at a specific timeUse for one-time tasks like migrations or setup scripts. The Location:
runAt time is in local time (no Z suffix).Execution check:apps/x/packages/core/src/agent-schedule/runner.ts:128Starting Message
Optional message sent to the agent on startup:"go" if not specified.
Location: apps/x/packages/core/src/agent-schedule/runner.ts:13
Description
Optional description displayed in the UI:Schedule State
IMPORTANT: Do NOT manually edit
agent-schedule-state.json - it is managed automatically by the runner.~/.rowboat/config/agent-schedule-state.json:
State Fields
| Field | Description |
|---|---|
status | scheduled, running, finished, failed, triggered |
lastRunAt | ISO timestamp of last execution |
nextRunAt | ISO timestamp of next scheduled execution |
startedAt | ISO timestamp when current run started (null if not running) |
lastError | Error message from last failed run (null if successful) |
runCount | Total number of executions |
Runner Implementation
Main Loop
The runner executes every minute:apps/x/packages/core/src/agent-schedule/runner.ts:323
Interruptible Sleep
Allows immediate wake on trigger:apps/x/packages/core/src/agent-schedule/runner.ts:28
Poll and Run
apps/x/packages/core/src/agent-schedule/runner.ts:258
Run Agent
apps/x/packages/core/src/agent-schedule/runner.ts:146
Complete Example
Multi-Agent Workflow
Email reader agent (agents/email_reader.md):
agents/daily_summary.md):
~/.rowboat/config/agent-schedule.json):
Best Practices
Agent Design
Agent Design
Single responsibility - Each agent should do one thing wellAutonomous operation - Add “Don’t ask for human input” to instructionsClear delegation - Explicitly state when to call other agentsData passing - Make it clear what data to extract and pass between agentsError handling - Background agents should handle errors gracefully
Security
Security
Avoid executeCommand - Don’t attach
executeCommand to background agents running unattendedUse specific tools - Use workspace-readFile, workspace-writeFile, etc. insteadValidate inputs - Check data before processingFile paths - Ask users for output paths, then hardcode in instructionsScheduling
Scheduling
Choose appropriate schedule type:
- Cron - Predictable, exact timing
- Window - Flexible timing (“sometime in the morning”)
- Once - One-time tasks, migrations
- Too frequent = wasted resources
- Too infrequent = stale data
- All times are in local machine timezone
- Document expected timezone in descriptions
Troubleshooting
Next Steps
Runtime Architecture
Understand how agents execute
Skills
Explore available skills