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. OneCronJob 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 CronJobExecutionErrorstr
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) -> Anyoutput: The original output from the agenttask: The task that was executedmetadata: 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 insteadfloat
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 tickOptional[Exception]
The most recent failure, or
None if the job has never failedMethods
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
CronJobExecutionError: If scheduling failed (including when nointervalwas configured), or if the job gave up after exhaustingmax_consecutive_errors. The message names the failure count and the last error.
- Schedules the task according to the configured interval
- Starts the background execution thread
- Blocks the calling thread until
stop()is called,KeyboardInterruptis received, or the job exhausts its error budget - On
KeyboardInterruptit 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
cron("task", **kwargs), is the same as cron.run("task", **kwargs).
batched_run
Schedule several tasks on the same interval, then block likerun().
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 themrun().
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.run_many instead.
run_many
Run several agents together, each on its own interval. A class method. ACronJob 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 individuallyCronJobConfigError: Ifschedulesis empty, or an entry is missing (or has an empty)agent,intervalortask. 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 exhaustedmax_consecutive_errors
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)start
Start the background scheduler thread.CronJobExecutionError: If the job fails to start
- Creates a daemon thread for job execution
- Sets
is_runningto True - Records
start_time - If already running, logs a warning
stop
Stop the scheduled job.CronJobExecutionError: If the job fails to stop properly
- Sets
is_runningto False - Waits up to 5 seconds for thread to terminate
- Clears the schedule
- Logs warning if thread doesn’t terminate gracefully
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) -> Anyget_execution_stats
Get execution statistics for the cron job.dict
Dictionary containing:
job_id: Job identifieris_running: Current running statusexecution_count: Number of successful executionsstart_time: Start timestampuptime: Time elapsed since start (seconds)interval: Configured interval stringerror_count: Total failed executionsconsecutive_errors: Failures since the last successlast_error: Most recent failure as a string, orNonestopped_due_to_error:Trueonly when the job gave up after exhaustingmax_consecutive_errors
Interval Formats
Theinterval parameter accepts strings in the format <number><unit>:
Supported Units
- Seconds:
"5seconds","30second" - Minutes:
"10minutes","1minute" - Hours:
"2hours","1hour"
Examples
Rejected at construction
These raiseCronJobConfigError 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-levelswarms 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 byrun_many for an empty or incomplete schedule list.
CronJobScheduleError
Defined for scheduling errors, butCronJob does not currently raise it. An invalid interval raises CronJobConfigError:
CronJobExecutionError
Raised byrun() 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
- Use descriptive job IDs: Make job identifiers meaningful for tracking
- Set appropriate intervals: Choose intervals based on task complexity and resource availability
- Implement callbacks: Use callbacks for logging, saving results, or sending notifications
- Monitor execution stats: Regularly check stats to ensure jobs are running as expected
- Handle interrupts:
run()catchesKeyboardInterrupt, stops the job and returns, so Ctrl-C shuts a job down cleanly - Consider agent limits: Ensure your agent’s
max_loopsis appropriate for scheduled tasks - Set an error budget for flaky dependencies:
max_consecutive_errorsstops a job that is failing every time. Leave it asNonewhen a task should retry indefinitely - Watch
consecutive_errors, not justerror_count: occasional failures on a long-running job are normal; a rising consecutive count is the signal something is actually broken - Use
run_manyfor mixed cadences: one job per agent keeps them isolated, so a failing agent cannot hold up the others - Log failures: Enable verbose mode and implement proper error logging
- Test intervals: Start with longer intervals and optimize based on performance
- Resource management: Be mindful of API rate limits and costs with frequent scheduling
- 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
schedulelibrary - Proper cleanup on stop() with timeout handling
Callback Metadata
The callback function receives a metadata dictionary with:- Logging execution history
- Conditional processing based on execution count
- Time-based analysis
- Debugging and monitoring