use std::path::PathBuf;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
pub type TaskId = String;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskRequest {
pub description: String,
pub trigger: TaskTrigger,
pub workspace: Option<PathBuf>,
pub file_context: Option<Vec<PathBuf>>,
pub reply_to: ReplyTarget,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "camelCase")]
pub enum TaskTrigger {
UserCommand { user_id: String, channel: String },
CronJob { job_id: String },
AgentDelegation { source_agent_id: String },
ControlPanel { user_id: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "state", rename_all = "camelCase")]
pub enum TaskState {
Queued { queued_at: DateTime<Utc> },
Running {
started_at: DateTime<Utc>,
progress_percent: Option<u8>,
},
Completed {
started_at: DateTime<Utc>,
completed_at: DateTime<Utc>,
result: TaskResult,
},
Failed {
started_at: DateTime<Utc>,
failed_at: DateTime<Utc>,
error: TaskError,
},
Cancelled {
started_at: Option<DateTime<Utc>>,
cancelled_at: DateTime<Utc>,
reason: CancellationReason,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskResult {
pub output: String,
pub modified_files: Vec<FileChange>,
pub duration_ms: u64,
pub token_usage: Option<TokenUsage>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FileChange {
pub path: PathBuf,
pub change_type: FileChangeType,
pub lines_added: u32,
pub lines_removed: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum FileChangeType {
Added,
Modified,
Deleted,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TokenUsage {
pub input_tokens: u64,
pub output_tokens: u64,
pub estimated_cost_usd: f64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "category", rename_all = "camelCase")]
pub enum TaskError {
Timeout { elapsed_secs: u64, limit_secs: u64 },
CostCap { spent_usd: f64, cap_usd: f64 },
RateLimit { retry_after_secs: Option<u64> },
ExecutionError {
message: String,
partial_output: Option<String>,
},
AgentDisconnected { agent_id: String },
WorkspaceViolation {
attempted_path: PathBuf,
allowed_workspaces: Vec<PathBuf>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub enum CancellationReason {
UserRequested,
Timeout,
CostCapExceeded,
AgentDisconnected,
SystemShutdown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TaskHistoryEntry {
pub task_id: TaskId,
pub agent_id: String,
pub description: String,
pub trigger: TaskTrigger,
pub state: TaskState,
pub workspace: PathBuf,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ReplyTarget {
pub channel_type: String,
pub channel_id: String,
pub message_id: Option<String>,
}