Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- 新增 66 个 @reserved 标注 (已有 22 个) - 覆盖: agent/butler/classroom/hand/mcp/pipeline/skill/trigger/viking/zclaw 等模块 - MCP 命令增加 @connected 注释说明前端接入路径 - @reserved 总数: 89 (含 identity_init)
129 lines
4.1 KiB
Rust
129 lines
4.1 KiB
Rust
//! Scheduled task commands
|
|
//!
|
|
//! Tasks are backed by kernel triggers (Schedule type).
|
|
//! The SchedulerService checks every 60 seconds for due triggers.
|
|
|
|
use serde::{Deserialize, Serialize};
|
|
use tauri::State;
|
|
|
|
use super::KernelState;
|
|
|
|
// ============================================================
|
|
// Scheduled Task Commands
|
|
// ============================================================
|
|
|
|
/// Request to create a scheduled task (maps to kernel trigger)
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct CreateScheduledTaskRequest {
|
|
pub name: String,
|
|
pub schedule: String,
|
|
pub schedule_type: String,
|
|
pub target: Option<ScheduledTaskTarget>,
|
|
pub description: Option<String>,
|
|
pub enabled: Option<bool>,
|
|
}
|
|
|
|
/// Target for a scheduled task
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ScheduledTaskTarget {
|
|
#[serde(rename = "type")]
|
|
pub target_type: String,
|
|
pub id: String,
|
|
}
|
|
|
|
/// Response for scheduled task creation
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct ScheduledTaskResponse {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub schedule: String,
|
|
pub status: String,
|
|
}
|
|
|
|
/// Create a scheduled task (backed by kernel TriggerManager)
|
|
///
|
|
/// Tasks are automatically executed by the SchedulerService which checks
|
|
/// every 60 seconds for due triggers.
|
|
// @reserved: scheduled task management
|
|
// @connected
|
|
#[tauri::command]
|
|
pub async fn scheduled_task_create(
|
|
state: State<'_, KernelState>,
|
|
request: CreateScheduledTaskRequest,
|
|
) -> Result<ScheduledTaskResponse, String> {
|
|
let kernel_lock = state.lock().await;
|
|
let kernel = kernel_lock.as_ref()
|
|
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
|
|
|
// Build TriggerConfig from request
|
|
let trigger_type = match request.schedule_type.as_str() {
|
|
"cron" | "schedule" => zclaw_hands::TriggerType::Schedule {
|
|
cron: request.schedule.clone(),
|
|
},
|
|
"interval" => zclaw_hands::TriggerType::Schedule {
|
|
cron: request.schedule.clone(), // interval as simplified cron
|
|
},
|
|
"once" => zclaw_hands::TriggerType::Schedule {
|
|
cron: request.schedule.clone(),
|
|
},
|
|
_ => return Err(format!("Unsupported schedule type: {}", request.schedule_type)),
|
|
};
|
|
|
|
let target_id = request.target.as_ref().map(|t| t.id.clone()).unwrap_or_default();
|
|
let task_id = format!("sched_{}", chrono::Utc::now().timestamp_millis());
|
|
|
|
let config = zclaw_hands::TriggerConfig {
|
|
id: task_id.clone(),
|
|
name: request.name.clone(),
|
|
hand_id: target_id,
|
|
trigger_type,
|
|
enabled: request.enabled.unwrap_or(true),
|
|
max_executions_per_hour: 60,
|
|
};
|
|
|
|
let entry = kernel.create_trigger(config).await
|
|
.map_err(|e| format!("Failed to create scheduled task: {}", e))?;
|
|
|
|
Ok(ScheduledTaskResponse {
|
|
id: entry.config.id,
|
|
name: entry.config.name,
|
|
schedule: request.schedule,
|
|
status: "active".to_string(),
|
|
})
|
|
}
|
|
|
|
/// List all scheduled tasks (kernel triggers of Schedule type)
|
|
// @reserved: scheduled task management
|
|
// @connected
|
|
#[tauri::command]
|
|
pub async fn scheduled_task_list(
|
|
state: State<'_, KernelState>,
|
|
) -> Result<Vec<ScheduledTaskResponse>, String> {
|
|
let kernel_lock = state.lock().await;
|
|
let kernel = kernel_lock.as_ref()
|
|
.ok_or_else(|| "Kernel not initialized".to_string())?;
|
|
|
|
let triggers = kernel.list_triggers().await;
|
|
let tasks: Vec<ScheduledTaskResponse> = triggers
|
|
.into_iter()
|
|
.filter(|t| matches!(t.config.trigger_type, zclaw_hands::TriggerType::Schedule { .. }))
|
|
.map(|t| {
|
|
let schedule = match t.config.trigger_type {
|
|
zclaw_hands::TriggerType::Schedule { cron } => cron,
|
|
_ => String::new(),
|
|
};
|
|
ScheduledTaskResponse {
|
|
id: t.config.id,
|
|
name: t.config.name,
|
|
schedule,
|
|
status: if t.config.enabled { "active".to_string() } else { "paused".to_string() },
|
|
}
|
|
})
|
|
.collect();
|
|
|
|
Ok(tasks)
|
|
}
|