use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; // ─── 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), } #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum AgentStatus { Online, Offline, Draining, } #[derive(Debug, Clone, Serialize, Deserialize)] 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: std::collections::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, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Task { pub task_id: String, pub source: String, // "forgejo:#" pub task_type: String, // "code", "review", "test", "deploy", "research" pub priority: Priority, pub status: TaskStatus, pub assigned_agent_id: Option, pub requirements: String, // Issue body 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)] pub struct Artifact { pub artifact_type: ArtifactType, pub url: Option, pub path: Option, pub description: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] 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)] 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, }