Skip to main content

Overview

The CronJob class wraps any callable (including Swarms agents) and turns it into a scheduled job that runs at specified intervals. It provides scheduling, failure handling, execution tracking, and optional callbacks for output customization. One CronJob binds one agent to one interval. For several agents on different cadences, use run_many.
Failure model. A task that raises is logged, recorded as a failed execution, and retried at the next interval, the way cron behaves. It does not take the schedule down, and a failing task is not retried any faster than its interval. Set max_consecutive_errors to stop a job that is failing every time; when that budget is exhausted the job stops and run() raises, so a dead schedule is never mistaken for a healthy one.

Constructor

Create a CronJob instance to schedule recurring agent executions.

Parameters

Union[Any, Callable]
default:"None"
The Swarms Agent instance or callable to be scheduled. Required: None raises CronJobConfigError. An object with a callable run attribute is called as agent.run(task=task, **kwargs); anything else is called as agent(task, **kwargs)
str
default:"None"
The interval string (e.g., “5seconds”, “10minutes”, “1hour”). Must be greater than zero. A malformed or empty value raises CronJobConfigError at construction. Leaving it None is accepted at construction, but run() then raises CronJobExecutionError
str
default:"None"
Optional unique identifier for the job. If not provided, one will be generated.
int
default:"None"
Stop the job after this many back-to-back failed executions. None (the default) never gives up and retries forever, which is what cron does. When the budget is exhausted the job stops and run() raises CronJobExecutionError.
Callable[[Any, str, dict], Any]
default:"None"
Optional callback function to customize output processing.Signature: callback(output: Any, task: str, metadata: dict) -> Any
  • output: The original output from the agent
  • task: The task that was executed
  • metadata: Dictionary containing job_id, timestamp, execution_count, etc.
  • Returns: The customized output

Attributes

str
Unique identifier for the job
bool
Flag indicating if the job is currently running
int
Number of successful executions. Failed executions are counted in error_count instead
float
Timestamp when the job was started
int
Total number of failed executions over the job’s life
int
Failures since the last success. Reset to 0 on any successful tick
Optional[Exception]
The most recent failure, or None if the job has never failed

Methods

run

Schedule and run the job with a specified task.
str
required
The task string to be executed by the agent
Any
Additional parameters to pass to the agent’s run method (e.g., img, imgs, correct_answer, streaming_callback)
schedule.Job
The scheduled job, returned once the schedule stops
Raises:
  • CronJobExecutionError: If scheduling failed (including when no interval was configured), or if the job gave up after exhausting max_consecutive_errors. The message names the failure count and the last error.
Behavior:
  • Schedules the task according to the configured interval
  • Starts the background execution thread
  • Blocks the calling thread until stop() is called, KeyboardInterrupt is received, or the job exhausts its error budget
  • On KeyboardInterrupt it stops the job itself and returns normally
  • A task that raises is logged and retried at the next interval; it does not stop the schedule
Calling the instance, cron("task", **kwargs), is the same as cron.run("task", **kwargs).

batched_run

Schedule several tasks on the same interval, then block like run().
List[str]
required
List of task strings to execute
Any
Additional parameters to pass to the agent’s run method
List[schedule.Job]
One scheduled job per task, in input order, returned once the schedule stops. Agent outputs are not collected; use a callback to capture them
Raises: the same exceptions as run(). Behavior: every task in tasks is registered on the job’s interval before blocking, so all of them run on each tick. This is one agent doing several things on one cadence.
Earlier versions scheduled only the first task: batched_run called run() per task, and run() blocked, so the loop never reached the second task. That is fixed — all tasks are scheduled, and the list of scheduled jobs is returned.
For several agents on different cadences, use run_many instead.

run_many

Run several agents together, each on its own interval. A class method. A CronJob binds one agent to one interval, so a fleet on mixed cadences needs one job per agent. run_many builds them, starts them all, and optionally blocks. Each job keeps its own scheduler thread, so the agents are isolated: one failing does not delay or stop the others, and each carries its own error budget.
List[Dict[str, Any]]
required
One mapping per agent.Required keys: agent, interval, taskOptional keys: job_id, callback, max_consecutive_errors, and kwargs (a dict forwarded to that agent’s run)
bool
default:"True"
Hold the calling thread until KeyboardInterrupt or until every job has stopped, then stop them all. Pass False to start the fleet and return immediately, leaving the caller responsible for stop_many.
List[CronJob]
The started jobs, in the order given, so they can be inspected via get_execution_stats() or stopped individually
Raises:
  • CronJobConfigError: If schedules is empty, or an entry is missing (or has an empty) agent, interval or task. The message names the index and the missing key. Entries are checked as they are started, so jobs for earlier entries are already running when a later entry fails.
  • CronJobExecutionError: If, once blocking ends, any job had stopped because it exhausted max_consecutive_errors
Non-blocking use:

stop_many

Stop every job in a list, continuing past any that fail to stop. A static method.
List[CronJob]
required
The jobs to stop, typically the return value of run_many(..., block=False)
Behavior: one job refusing to stop is logged and does not strand the rest.

start

Start the background scheduler thread.
start() does not schedule a task. It only starts the thread that runs tasks already scheduled. Use run(), batched_run() or run_many() to schedule work; they call start() for you.
Raises:
  • CronJobExecutionError: If the job fails to start
Behavior:
  • Creates a daemon thread for job execution
  • Sets is_running to True
  • Records start_time
  • If already running, logs a warning

stop

Stop the scheduled job.
Raises:
  • CronJobExecutionError: If the job fails to stop properly
Behavior:
  • Sets is_running to False
  • Waits up to 5 seconds for thread to terminate
  • Clears the schedule
  • Logs warning if thread doesn’t terminate gracefully
Safe to call from another thread while run() is blocking, and safe to call on a job that is already stopped. A clean stop() makes run() return normally.

set_callback

Set or update the callback function for output customization.
Callable[[Any, str, dict], Any]
required
Callback function with signature: callback(output, task, metadata) -> Any

get_execution_stats

Get execution statistics for the cron job.
dict
Dictionary containing:
  • job_id: Job identifier
  • is_running: Current running status
  • execution_count: Number of successful executions
  • start_time: Start timestamp
  • uptime: Time elapsed since start (seconds)
  • interval: Configured interval string
  • error_count: Total failed executions
  • consecutive_errors: Failures since the last success
  • last_error: Most recent failure as a string, or None
  • stopped_due_to_error: True only when the job gave up after exhausting max_consecutive_errors

Interval Formats

The interval parameter accepts strings in the format <number><unit>:

Supported Units

  • Seconds: "5seconds", "30second"
  • Minutes: "10minutes", "1minute"
  • Hours: "2hours", "1hour"

Examples

Rejected at construction

These raise CronJobConfigError immediately rather than failing later:

Complete Examples

Basic Scheduled Analysis

Multi-Stock Analysis with Batching

Custom Callback for Output Processing

Image Analysis with Scheduling

Monitoring Execution Stats

run_many(..., block=False) schedules the task and returns at once, which leaves your thread free to poll the stats.

Exception Handling

The CronJob module defines several custom exceptions. They are not exported from the top-level swarms package, so import them from swarms.structs.cron_job:

CronJobError

Base exception class for all CronJob errors.

CronJobConfigError

Raised at construction for a missing agent or a malformed, empty or zero interval, and by run_many for an empty or incomplete schedule list.

CronJobScheduleError

Defined for scheduling errors, but CronJob does not currently raise it. An invalid interval raises CronJobConfigError:

CronJobExecutionError

Raised by run() and batched_run() when scheduling fails (for example, no interval was set) or when the job gives up after max_consecutive_errors failures in a row, and by start() and stop() when the thread cannot be started or stopped. A single failed execution does not raise; it is recorded in the error counters.

Best Practices

  1. Use descriptive job IDs: Make job identifiers meaningful for tracking
  2. Set appropriate intervals: Choose intervals based on task complexity and resource availability
  3. Implement callbacks: Use callbacks for logging, saving results, or sending notifications
  4. Monitor execution stats: Regularly check stats to ensure jobs are running as expected
  5. Handle interrupts: run() catches KeyboardInterrupt, stops the job and returns, so Ctrl-C shuts a job down cleanly
  6. Consider agent limits: Ensure your agent’s max_loops is appropriate for scheduled tasks
  7. Set an error budget for flaky dependencies: max_consecutive_errors stops a job that is failing every time. Leave it as None when a task should retry indefinitely
  8. Watch consecutive_errors, not just error_count: occasional failures on a long-running job are normal; a rising consecutive count is the signal something is actually broken
  9. Use run_many for mixed cadences: one job per agent keeps them isolated, so a failing agent cannot hold up the others
  10. Log failures: Enable verbose mode and implement proper error logging
  11. Test intervals: Start with longer intervals and optimize based on performance
  12. Resource management: Be mindful of API rate limits and costs with frequent scheduling
  13. Graceful shutdown: Always call stop() when terminating scheduled jobs

Thread Safety

CronJob uses threading for background execution:
  • Daemon threads are used to prevent blocking program exit
  • Thread-safe scheduling with the schedule library
  • Proper cleanup on stop() with timeout handling

Callback Metadata

The callback function receives a metadata dictionary with:
The callback runs only after a successful execution. A failed execution skips it, and a callback that raises is logged and the original output is used. Use this metadata for:
  • Logging execution history
  • Conditional processing based on execution count
  • Time-based analysis
  • Debugging and monitoring