rusty_beads/types/
agent.rs

1//! Agent-related type definitions.
2
3use serde::{Deserialize, Serialize};
4use std::fmt;
5use std::str::FromStr;
6
7/// Self-reported state of an agent.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
9#[serde(rename_all = "snake_case")]
10pub enum AgentState {
11    /// Agent is not currently working.
12    #[default]
13    Idle,
14    /// Agent is starting up.
15    Spawning,
16    /// Agent is running but not on a specific task.
17    Running,
18    /// Agent is actively working on a task.
19    Working,
20    /// Agent is stuck and needs help.
21    Stuck,
22    /// Agent has completed its work.
23    Done,
24    /// Agent has been stopped.
25    Stopped,
26    /// Agent has crashed or is unreachable.
27    Dead,
28}
29
30impl AgentState {
31    /// Returns the string representation for database storage.
32    pub fn as_str(&self) -> &'static str {
33        match self {
34            AgentState::Idle => "idle",
35            AgentState::Spawning => "spawning",
36            AgentState::Running => "running",
37            AgentState::Working => "working",
38            AgentState::Stuck => "stuck",
39            AgentState::Done => "done",
40            AgentState::Stopped => "stopped",
41            AgentState::Dead => "dead",
42        }
43    }
44
45    /// Returns true if the agent is in an active state.
46    pub fn is_active(&self) -> bool {
47        matches!(
48            self,
49            AgentState::Spawning | AgentState::Running | AgentState::Working
50        )
51    }
52
53    /// Returns true if the agent is in a terminal state.
54    pub fn is_terminal(&self) -> bool {
55        matches!(self, AgentState::Done | AgentState::Stopped | AgentState::Dead)
56    }
57}
58
59impl fmt::Display for AgentState {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        write!(f, "{}", self.as_str())
62    }
63}
64
65impl FromStr for AgentState {
66    type Err = String;
67
68    fn from_str(s: &str) -> Result<Self, Self::Err> {
69        match s.to_lowercase().as_str() {
70            "idle" => Ok(AgentState::Idle),
71            "spawning" => Ok(AgentState::Spawning),
72            "running" => Ok(AgentState::Running),
73            "working" => Ok(AgentState::Working),
74            "stuck" => Ok(AgentState::Stuck),
75            "done" => Ok(AgentState::Done),
76            "stopped" => Ok(AgentState::Stopped),
77            "dead" => Ok(AgentState::Dead),
78            _ => Err(format!("unknown agent state: {}", s)),
79        }
80    }
81}
82
83/// The type of molecule (coordinated work).
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
85#[serde(rename_all = "snake_case")]
86pub enum MolType {
87    /// Coordinated multi-agent operations.
88    Swarm,
89    /// Recurring work (witness/deacon roles).
90    Patrol,
91    /// Standard work (default).
92    #[default]
93    Work,
94}
95
96impl MolType {
97    /// Returns the string representation for database storage.
98    pub fn as_str(&self) -> &'static str {
99        match self {
100            MolType::Swarm => "swarm",
101            MolType::Patrol => "patrol",
102            MolType::Work => "work",
103        }
104    }
105}
106
107impl fmt::Display for MolType {
108    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
109        write!(f, "{}", self.as_str())
110    }
111}
112
113impl FromStr for MolType {
114    type Err = String;
115
116    fn from_str(s: &str) -> Result<Self, Self::Err> {
117        match s.to_lowercase().as_str() {
118            "swarm" => Ok(MolType::Swarm),
119            "patrol" => Ok(MolType::Patrol),
120            "work" => Ok(MolType::Work),
121            _ => Err(format!("unknown molecule type: {}", s)),
122        }
123    }
124}