99 lines
2.5 KiB
Rust
99 lines
2.5 KiB
Rust
use std::future::Future;
|
|
|
|
use chrono::{DateTime, Utc};
|
|
use zeroclaw::config::Config as ZeroClawConfig;
|
|
use zeroclaw::cron::{self, CronJob, CronRun, JobType, Schedule, SessionTarget};
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct CronExecutionResult {
|
|
pub job_id: String,
|
|
pub success: bool,
|
|
pub output: String,
|
|
}
|
|
|
|
pub fn configure_embedded_cron(config: &mut ZeroClawConfig) {
|
|
config.cron.enabled = true;
|
|
config.cron.catch_up_on_startup = false;
|
|
config.scheduler.enabled = false;
|
|
config.scheduler.max_concurrent = 1;
|
|
config.scheduler.max_tasks = config.scheduler.max_tasks.max(1);
|
|
}
|
|
|
|
pub fn add_agent_job(
|
|
config: &ZeroClawConfig,
|
|
name: Option<String>,
|
|
schedule: Schedule,
|
|
prompt: &str,
|
|
allowed_tools: Option<Vec<String>>,
|
|
) -> anyhow::Result<CronJob> {
|
|
cron::add_agent_job(
|
|
config,
|
|
name,
|
|
schedule,
|
|
prompt,
|
|
SessionTarget::Isolated,
|
|
None,
|
|
None,
|
|
false,
|
|
allowed_tools,
|
|
)
|
|
}
|
|
|
|
pub fn list_jobs(config: &ZeroClawConfig) -> anyhow::Result<Vec<CronJob>> {
|
|
cron::list_jobs(config)
|
|
}
|
|
|
|
pub fn list_runs(
|
|
config: &ZeroClawConfig,
|
|
job_id: &str,
|
|
limit: usize,
|
|
) -> anyhow::Result<Vec<CronRun>> {
|
|
cron::list_runs(config, job_id, limit)
|
|
}
|
|
|
|
pub async fn run_due_jobs<F, Fut>(
|
|
config: &ZeroClawConfig,
|
|
now: DateTime<Utc>,
|
|
mut runner: F,
|
|
) -> anyhow::Result<Vec<CronExecutionResult>>
|
|
where
|
|
F: FnMut(&CronJob) -> Fut,
|
|
Fut: Future<Output = anyhow::Result<String>>,
|
|
{
|
|
let jobs = cron::due_jobs(config, now)?;
|
|
let mut results = Vec::with_capacity(jobs.len());
|
|
|
|
for job in jobs {
|
|
if !matches!(job.job_type, JobType::Agent) {
|
|
anyhow::bail!("unsupported cron job type in sgclaw compat: {:?}", job.job_type);
|
|
}
|
|
|
|
let started_at = Utc::now();
|
|
let (success, output) = match runner(&job).await {
|
|
Ok(output) => (true, output),
|
|
Err(err) => (false, err.to_string()),
|
|
};
|
|
let finished_at = Utc::now();
|
|
let duration_ms = (finished_at - started_at).num_milliseconds();
|
|
|
|
cron::record_run(
|
|
config,
|
|
&job.id,
|
|
started_at,
|
|
finished_at,
|
|
if success { "ok" } else { "error" },
|
|
Some(&output),
|
|
duration_ms,
|
|
)?;
|
|
cron::reschedule_after_run(config, &job, success, &output)?;
|
|
|
|
results.push(CronExecutionResult {
|
|
job_id: job.id,
|
|
success,
|
|
output,
|
|
});
|
|
}
|
|
|
|
Ok(results)
|
|
}
|