feat: refactor sgclaw around zeroclaw compat runtime

This commit is contained in:
zyl
2026-03-26 16:23:31 +08:00
parent bca5b75801
commit ff0771a83f
1059 changed files with 409460 additions and 23 deletions

View File

@@ -0,0 +1,98 @@
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)
}