Overview
Cron jobs are scheduled tasks that run at specified times. They can either send prompts to agents or execute deterministic shell commands directly. They support three schedule types: standard cron expressions, fixed intervals, and one-shot datetimes. The daemon manages all timers and executes jobs automatically.Schedule Types
Cron Expressions
Standard five-field cron syntax for precise recurring schedules.--cron:
Intervals
Fixed-duration intervals using a compact duration syntax. Supported units:s (seconds), m (minutes), h (hours), d (days).
One-Shot Datetime
Run a job exactly once at a specific ISO 8601 datetime. Accepts formats like2025-02-01T15:00, 2025-02-01T15:00:00Z, or 2025-02-01T15:00:00-03:00.
--delete-after flag is optional here since --at jobs are deleted by default, but it makes the intent explicit.
Timezone Handling
Cron expressions are evaluated in a specific timezone. Use--tz to set it:
--tz is omitted, the default timezone from ravi settings is used (configured via ravi settings set defaultTimezone America/Sao_Paulo).
The
--tz flag only applies to cron expressions. Interval and one-shot schedules are timezone-independent.Session Targets
Agent jobs run in one of two session modes:Main Session (default)
The job prompt is sent to the agent’s shared main session, the same session used by WhatsApp, Telegram, and CLI interactions. Responses are delivered to the channel the job was created from.Isolated Session
Each job gets its own dedicated session (agent:{agentId}:cron:{jobId}), completely separate from the main conversation. Useful for background tasks that should not mix with user conversations.
cross_send to deliver results to a specific channel or user when needed.
Prompt Format
When a cron job fires, the agent receives the message prefixed with a header that includes the job name and current timestamp:Shell Jobs
Use--shell or --exec for deterministic scripts that do not need agent reasoning. Shell jobs are tracked by ravi cron list/show/run like agent jobs, but successful runs do not publish any prompt and do not spend LLM tokens.
lastStatus=error, lastError, duration, and exit code. To involve an agent only when the command fails, add an explicit error action:
--timeout accepts seconds as a bare number or duration strings like 30s, 5m, or 1h. --env-file reads simple dotenv-style KEY=value lines and merges them into the shell process environment.
Anti-Drift
For interval-based jobs, the next run time is calculated from the originally scheduled time, not from when execution finishes. This prevents timing drift caused by variable execution durations. For example, with a--every 30m job scheduled at 09:00:
- If execution takes 2 minutes (finishes at 09:02), the next run is still 09:30
- If execution takes 10 minutes (finishes at 09:10), the next run is still 09:30
Job Properties
Each cron job has the following properties:
State fields (read-only, visible in
ravi cron show):
CLI Workflows
Creating Jobs
Listing and Inspecting
Enabling and Disabling
nextRunAt is recalculated from the current time so it does not immediately fire for all missed runs.
Updating Properties
Manual Execution
Run a job immediately, ignoring its schedule:Deleting Jobs
Practical Examples
Daily standup report (weekdays at 9am)
Periodic health check (every 2 hours)
One-time reminder
Weekly metrics every Monday morning
Email check every 15 minutes during business hours
Troubleshooting
Job not firing
- Check if enabled:
ravi cron show <id>— verifyEnabled: yes - Check next run time: The
Next runfield shows when the job is scheduled to fire next - Daemon running:
ravi daemon status— the daemon must be running to execute jobs - Check logs:
ravi daemon logs -f— look forcron:runnerentries - Manual test:
ravi cron run <id>— triggers immediately to verify the job works
Timing seems off
- Verify the timezone:
ravi cron show <id>displays the schedule including timezone - For cron expressions without
--tz, the system default timezone is used. Check withravi settings list - Interval jobs use anti-drift: if a job was disabled and re-enabled,
nextRunAtresets to “now + interval”
Job runs but no response appears
- Main session: The response routes to the channel the job was created from. If the job was created from CLI, responses go to the agent’s main session
- Isolated session: The agent must use
cross_sendto deliver results to a channel. Without it, the response stays in the isolated session - Check agent logs:
ravi daemon logs -f | grep cron
One-shot job shows “(expired)”
One-shot jobs (--at) whose datetime has passed show (expired) in the list. They will not fire again. If the job has delete-after enabled (the default for --at), it is automatically deleted after execution.