//! Auto Task System - Self-Executing Intelligent Tasks //! //! This module provides the "Auto Task" functionality that enables tasks to //! automatically execute themselves using LLM-generated BASIC programs. //! It integrates with the Intent Compiler, Safety Layer, and MCP servers //! to create a fully autonomous task execution system. //! //! # Architecture //! //! ```text //! User Intent → Auto Task → Intent Compiler → Execution Plan → Safety Check → Execute //! ↓ ↓ ↓ ↓ ↓ ↓ //! "Build CRM" Create task Generate BASIC Validate plan Simulate Run steps //! with metadata program & approve impact with audit //! ``` //! //! # Features //! //! - **Automatic Execution**: Tasks execute themselves when conditions are met //! - **Safety First**: All actions are simulated and validated before execution //! - **Decision Framework**: Ambiguous situations generate options for user choice //! - **Audit Trail**: Complete logging of all actions and decisions //! - **MCP Integration**: Leverage registered MCP servers for extended capabilities //! - **Rollback Support**: Automatic rollback on failure when possible use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; // AUTO TASK DATA STRUCTURES /// Represents an auto-executing task #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AutoTask { /// Unique task identifier pub id: String, /// Human-readable task title pub title: String, /// Original intent/description pub intent: String, /// Current task status pub status: AutoTaskStatus, /// Execution mode pub mode: ExecutionMode, /// Priority level pub priority: TaskPriority, /// Generated execution plan ID pub plan_id: Option, /// Generated BASIC program pub basic_program: Option, /// Current execution step (0 = not started) pub current_step: i32, /// Total steps in the plan pub total_steps: i32, /// Execution progress (0.0 - 1.0) pub progress: f64, /// Step execution results pub step_results: Vec, /// Pending decisions requiring user input pub pending_decisions: Vec, /// Active approvals waiting pub pending_approvals: Vec, /// Risk assessment summary pub risk_summary: Option, /// Resource usage tracking pub resource_usage: ResourceUsage, /// Error information if failed pub error: Option, /// Rollback state if available pub rollback_state: Option, /// Session that created this task pub session_id: String, /// Bot executing this task pub bot_id: String, /// User who created the task pub created_by: String, /// Assigned executor (user or "auto") pub assigned_to: String, /// Scheduling information pub schedule: Option, /// Tags for organization pub tags: Vec, /// Parent task ID if this is a subtask pub parent_task_id: Option, /// Child task IDs pub subtask_ids: Vec, /// Dependencies on other tasks pub depends_on: Vec, /// Tasks that depend on this one pub dependents: Vec, /// MCP servers being used pub mcp_servers: Vec, /// External APIs being called pub external_apis: Vec, /// Timestamps pub created_at: DateTime, pub updated_at: DateTime, pub started_at: Option>, pub completed_at: Option>, /// Estimated completion time pub estimated_completion: Option>, } /// Auto task status #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum AutoTaskStatus { /// Task created, not yet analyzed Draft, /// Intent being compiled to BASIC program Compiling, /// Plan generated, waiting for approval PendingApproval, /// Simulating execution impact Simulating, /// Waiting for user decision on options WaitingDecision, /// Ready to execute Ready, /// Currently executing Running, /// Paused by user or system Paused, /// Waiting for external resource Blocked, /// Completed successfully Completed, /// Failed with error Failed, /// Cancelled by user Cancelled, /// Rolling back changes RollingBack, /// Rollback completed RolledBack, } impl Default for AutoTaskStatus { fn default() -> Self { AutoTaskStatus::Draft } } impl std::fmt::Display for AutoTaskStatus { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AutoTaskStatus::Draft => write!(f, "Draft"), AutoTaskStatus::Compiling => write!(f, "Compiling"), AutoTaskStatus::PendingApproval => write!(f, "Pending Approval"), AutoTaskStatus::Simulating => write!(f, "Simulating"), AutoTaskStatus::WaitingDecision => write!(f, "Waiting for Decision"), AutoTaskStatus::Ready => write!(f, "Ready"), AutoTaskStatus::Running => write!(f, "Running"), AutoTaskStatus::Paused => write!(f, "Paused"), AutoTaskStatus::Blocked => write!(f, "Blocked"), AutoTaskStatus::Completed => write!(f, "Completed"), AutoTaskStatus::Failed => write!(f, "Failed"), AutoTaskStatus::Cancelled => write!(f, "Cancelled"), AutoTaskStatus::RollingBack => write!(f, "Rolling Back"), AutoTaskStatus::RolledBack => write!(f, "Rolled Back"), } } } /// Execution mode for the task #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum ExecutionMode { /// Fully automatic - execute without user intervention FullyAutomatic, /// Semi-automatic - pause for approvals on high-risk steps SemiAutomatic, /// Supervised - pause after each step for review Supervised, /// Manual - user triggers each step Manual, /// Dry run - simulate only, don't execute DryRun, } impl Default for ExecutionMode { fn default() -> Self { ExecutionMode::SemiAutomatic } } /// Task priority #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Ord, PartialOrd, Eq)] pub enum TaskPriority { Critical = 4, High = 3, Medium = 2, Low = 1, Background = 0, } impl Default for TaskPriority { fn default() -> Self { TaskPriority::Medium } } /// Result of executing a single step #[derive(Debug, Clone, Serialize, Deserialize)] pub struct StepExecutionResult { pub step_id: String, pub step_order: i32, pub step_name: String, pub status: StepStatus, pub started_at: DateTime, pub completed_at: Option>, pub duration_ms: Option, pub output: Option, pub error: Option, pub logs: Vec, pub resources_used: ResourceUsage, pub can_rollback: bool, pub rollback_data: Option, } /// Status of a single step #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub enum StepStatus { Pending, Running, Completed, Failed, Skipped, RolledBack, } /// Execution log entry #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionLog { pub timestamp: DateTime, pub level: LogLevel, pub message: String, pub details: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum LogLevel { Debug, Info, Warning, Error, } /// A decision point requiring user input #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PendingDecision { pub id: String, pub decision_type: DecisionType, pub title: String, pub description: String, pub options: Vec, pub default_option: Option, pub timeout_seconds: Option, pub timeout_action: TimeoutAction, pub context: serde_json::Value, pub created_at: DateTime, pub expires_at: Option>, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum DecisionType { /// Choose between multiple approaches ApproachSelection, /// Confirm a high-risk action RiskConfirmation, /// Resolve ambiguous intent AmbiguityResolution, /// Provide missing information InformationRequest, /// Handle an error ErrorRecovery, /// Custom decision type Custom(String), } /// An option in a decision #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DecisionOption { pub id: String, pub label: String, pub description: String, pub pros: Vec, pub cons: Vec, pub estimated_impact: ImpactEstimate, pub recommended: bool, pub risk_level: RiskLevel, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ImpactEstimate { pub cost_change: f64, pub time_change_minutes: i32, pub risk_change: f64, pub description: String, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum TimeoutAction { UseDefault, Pause, Cancel, Escalate, } impl Default for TimeoutAction { fn default() -> Self { TimeoutAction::Pause } } /// A pending approval request #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PendingApproval { pub id: String, pub approval_type: ApprovalType, pub title: String, pub description: String, pub risk_level: RiskLevel, pub approver: String, pub step_id: Option, pub impact_summary: String, pub simulation_result: Option, pub timeout_seconds: i32, pub default_action: ApprovalDefault, pub created_at: DateTime, pub expires_at: DateTime, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ApprovalType { PlanApproval, StepApproval, HighRiskAction, ExternalApiCall, DataModification, CostOverride, SecurityOverride, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ApprovalDefault { Approve, Reject, Pause, Escalate, } impl Default for ApprovalDefault { fn default() -> Self { ApprovalDefault::Pause } } /// Risk level classification #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Ord, PartialOrd, Eq)] pub enum RiskLevel { None = 0, Low = 1, Medium = 2, High = 3, Critical = 4, } impl Default for RiskLevel { fn default() -> Self { RiskLevel::Low } } /// Risk assessment summary #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RiskSummary { pub overall_risk: RiskLevel, pub data_risk: RiskLevel, pub cost_risk: RiskLevel, pub security_risk: RiskLevel, pub compliance_risk: RiskLevel, pub risk_factors: Vec, pub mitigations_applied: Vec, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RiskFactor { pub id: String, pub category: RiskCategory, pub description: String, pub probability: f64, pub impact: RiskLevel, pub mitigation: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum RiskCategory { Data, Cost, Security, Compliance, Performance, Availability, Integration, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ResourceUsage { pub compute_hours: f64, pub storage_gb: f64, pub api_calls: i32, pub llm_tokens: i32, pub estimated_cost_usd: f64, pub mcp_servers_used: Vec, pub external_services: Vec, } impl Default for ResourceUsage { fn default() -> Self { ResourceUsage { compute_hours: 0.0, storage_gb: 0.0, api_calls: 0, llm_tokens: 0, estimated_cost_usd: 0.0, mcp_servers_used: Vec::new(), external_services: Vec::new(), } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TaskError { pub code: String, pub message: String, pub step_id: Option, pub recoverable: bool, pub details: Option, pub occurred_at: DateTime, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct RollbackState { pub available: bool, pub steps_rolled_back: Vec, pub rollback_data: HashMap, pub started_at: Option>, pub completed_at: Option>, } impl Default for RollbackState { fn default() -> Self { RollbackState { available: false, steps_rolled_back: Vec::new(), rollback_data: HashMap::new(), started_at: None, completed_at: None, } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TaskSchedule { pub schedule_type: ScheduleType, pub scheduled_at: Option>, pub cron_expression: Option, pub timezone: String, pub max_retries: i32, pub retry_delay_seconds: i32, } #[derive(Debug, Clone, Serialize, Deserialize)] pub enum ScheduleType { Immediate, Scheduled, Recurring, OnDemand, } impl Default for TaskSchedule { fn default() -> Self { TaskSchedule { schedule_type: ScheduleType::Immediate, scheduled_at: None, cron_expression: None, timezone: "UTC".to_string(), max_retries: 3, retry_delay_seconds: 60, } } } use crate::basic::keywords::safety_layer::SimulationResult;