use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; // ─── Agent ─────────────────────────────────────────────────────── #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] #[serde(rename_all = "kebab-case")] pub enum AgentType { OpenClaw, ClaudeCode, CodexCli, Hermes, Acp, Shell, Other(String), } impl AgentType { pub fn as_str(&self) -> &str { match self { Self::OpenClaw => "openclaw", Self::ClaudeCode => "claude-code", Self::CodexCli => "codex-cli", Self::Hermes => "hermes", Self::Acp => "acp", Self::Shell => "shell", Self::Other(value) => value.as_str(), } } pub fn from_str(value: &str) -> Self { match value { "openclaw" => Self::OpenClaw, "claude-code" => Self::ClaudeCode, "codex-cli" => Self::CodexCli, "hermes" => Self::Hermes, "acp" => Self::Acp, "shell" => Self::Shell, other => Self::Other(other.to_string()), } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum AgentStatus { Online, Offline, Draining, } impl AgentStatus { pub fn as_str(&self) -> &'static str { match self { Self::Online => "online", Self::Offline => "offline", Self::Draining => "draining", } } pub fn from_str(value: &str) -> Self { match value { "online" => Self::Online, "offline" => Self::Offline, "draining" => Self::Draining, _ => Self::Offline, } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Agent { pub agent_id: String, pub agent_type: AgentType, pub hostname: String, pub capabilities: Vec, pub max_concurrency: u32, pub current_tasks: u32, pub status: AgentStatus, pub last_heartbeat_at: DateTime, pub registered_at: DateTime, pub metadata: HashMap, } // ─── Task ──────────────────────────────────────────────────────── #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum TaskStatus { Created, Assigned, Running, Completed, Failed, AgentLost, Cancelled, } impl TaskStatus { pub fn as_str(&self) -> &'static str { match self { Self::Created => "created", Self::Assigned => "assigned", Self::Running => "running", Self::Completed => "completed", Self::Failed => "failed", Self::AgentLost => "agent_lost", Self::Cancelled => "cancelled", } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)] #[serde(rename_all = "lowercase")] pub enum Priority { Low, Normal, High, Urgent, } impl Priority { pub fn order(&self) -> u8 { match self { Self::Urgent => 0, Self::High => 1, Self::Normal => 2, Self::Low => 3, } } pub fn as_str(&self) -> &'static str { match self { Self::Low => "low", Self::Normal => "normal", Self::High => "high", Self::Urgent => "urgent", } } } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Task { pub task_id: String, pub source: String, pub task_type: String, pub priority: Priority, pub status: TaskStatus, pub assigned_agent_id: Option, pub requirements: String, pub labels: Vec, pub created_at: DateTime, pub assigned_at: Option>, pub started_at: Option>, pub completed_at: Option>, pub retry_count: u32, pub max_retries: u32, pub timeout_seconds: u64, } // ─── Receipt ───────────────────────────────────────────────────── #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ReceiptStatus { Completed, Failed, Partial, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ArtifactType { Pr, Commit, File, Comment, Url, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Artifact { pub artifact_type: ArtifactType, pub url: Option, pub path: Option, pub description: Option, } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct Receipt { pub task_id: String, pub agent_id: String, pub status: ReceiptStatus, pub duration_seconds: u64, pub summary: String, pub artifacts: Vec, pub error: Option, } // ─── TaskEvent (event sourcing) ────────────────────────────────── #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct TaskEvent { pub event_id: String, pub task_id: String, pub event_type: String, pub agent_id: Option, pub timestamp: DateTime, pub payload: serde_json::Value, }