Cron Scheduling
源码版本v2026.7.20
Responsibility
Let the agent "run automatically on schedule": timed reports, backups, briefings, etc., with no human present. The cron/ subsystem provides a scheduler, job store, execution records, a lifecycle guard, a blueprints/suggestions catalog, and per-job toolset isolation (timed jobs can disable some tools to prevent dangerous actions while unattended). The gateway drives the scheduler with a 60s heartbeat.
Key Files
def run_job:2659— core that executes a single job_run_job_script / _run_job_script_with_claim_heartbeat:2113-2247— script-job execution + lease heartbeatruntime state & interruption:352-445—get_running_job_ids/mark_running_jobs_interrupted/_consume_interrupted_flagtoolsets resolution:143-210—_resolve_cron_disabled_toolsets/_resolve_cron_enabled_toolsets(tool isolation for timed jobs)thread pools:501-547—_get_parallel_pool/_get_sequential_pool_CronStorePaths / _current_cron_store:106-157— job store pathslock & output dir:251-360—_jobs_lock_file/_job_output_dir_normalize_job_record:426-461— job record normalizationexecution state machine:99-156—create_execution/mark_execution_running/finish_executionrecover_interrupted_executions:156-213— crash recovery +list_executions/latest_executioncheck_gateway_lifecycle:69-112— prevents timed scripts from accidentally altering gateway lifecycleblueprint_catalog— job blueprint catalogsuggestion_catalog/suggestions— cron suggestion generation_start_cron_ticker:22335— 60s heartbeat inside the gateway drives scheduling
Data Flow
- The gateway starts
_start_cron_ticker:22335, which triggers the scheduler every 60s. - The scheduler reads the job store (
cron/jobs.py:106) and selects due jobs by cron expression. - For each due job:
check_gateway_lifecycle:112scans the script to prevent accidental gateway-lifecycle changes- the job's toolsets are resolved (
cron/scheduler.py:210), typically disabling dangerous tools (see the same auto-deny idea in Subagent) - an execution is recorded via
create_execution(cron/executions.py:99) run_job(cron/scheduler.py:2659) actually runs: script jobs go through_run_job_script:2113; conversational jobs are fed torun_conversation:588
- On crash during execution, the next
recover_interrupted_executions(cron/executions.py:156) recovers the markers. - Results are delivered by the gateway (or mirrored to a designated platform).
Summary
The cron subsystem focuses on "unattended safety": toolset isolation, a lifecycle guard against misoperations, and an execution state machine for crash recovery. Scheduling itself is driven by the gateway heartbeat; no external cron daemon is required.