/ crates / bot / src / actor.rs
actor.rs
  1  /// Bot actor trait and types
  2  ///
  3  /// Defines the core Bot trait that all bot implementations must follow.
  4  /// Uses async trait for lifecycle methods: setup, execute, teardown.
  5  
  6  use crate::{ExecutionContext, Identity, Wallet, Result};
  7  use async_trait::async_trait;
  8  use serde::{Deserialize, Serialize};
  9  use std::sync::Arc;
 10  use parking_lot::RwLock;
 11  
 12  /// Context provided to bots during their lifecycle
 13  #[derive(Debug, Clone)]
 14  pub struct BotContext {
 15      pub execution: ExecutionContext,
 16      pub identity: Identity,
 17      pub wallet: Arc<RwLock<Wallet>>,
 18  }
 19  
 20  impl BotContext {
 21      pub fn new(execution: ExecutionContext, identity: Identity, wallet: Wallet) -> Self {
 22          Self {
 23              execution,
 24              identity,
 25              wallet: Arc::new(RwLock::new(wallet)),
 26          }
 27      }
 28  }
 29  
 30  /// Result of a behavior execution
 31  #[derive(Debug, Clone, Serialize, Deserialize)]
 32  pub struct BehaviorResult {
 33      /// Whether the behavior succeeded
 34      pub success: bool,
 35  
 36      /// Human-readable message
 37      pub message: String,
 38  
 39      /// Structured data (e.g., transaction hashes, block numbers)
 40      pub data: serde_json::Value,
 41  
 42      /// Performance metrics
 43      pub metrics: BehaviorMetrics,
 44  }
 45  
 46  #[derive(Debug, Clone, Serialize, Deserialize)]
 47  pub struct BehaviorMetrics {
 48      /// Duration in milliseconds
 49      pub duration_ms: u64,
 50  
 51      /// Number of operations performed
 52      pub operations_count: u64,
 53  
 54      /// Number of errors encountered
 55      pub errors_count: u64,
 56  }
 57  
 58  impl BehaviorResult {
 59      pub fn success(message: impl Into<String>) -> Self {
 60          Self {
 61              success: true,
 62              message: message.into(),
 63              data: serde_json::Value::Null,
 64              metrics: BehaviorMetrics {
 65                  duration_ms: 0,
 66                  operations_count: 1,
 67                  errors_count: 0,
 68              },
 69          }
 70      }
 71  
 72      pub fn error(message: impl Into<String>) -> Self {
 73          Self {
 74              success: false,
 75              message: message.into(),
 76              data: serde_json::Value::Null,
 77              metrics: BehaviorMetrics {
 78                  duration_ms: 0,
 79                  operations_count: 0,
 80                  errors_count: 1,
 81              },
 82          }
 83      }
 84  
 85      pub fn with_data(mut self, data: serde_json::Value) -> Self {
 86          self.data = data;
 87          self
 88      }
 89  
 90      pub fn with_metrics(mut self, metrics: BehaviorMetrics) -> Self {
 91          self.metrics = metrics;
 92          self
 93      }
 94  }
 95  
 96  /// Core Bot trait that all bot implementations must follow
 97  ///
 98  /// Bots have a three-phase lifecycle:
 99  /// 1. setup() - Initialize state, register with network
100  /// 2. execute_behavior() - Perform the bot's intended actions
101  /// 3. teardown() - Clean up resources, unregister
102  #[async_trait]
103  pub trait Bot: Send + Sync {
104      /// Initialize the bot
105      ///
106      /// This is called once when the bot is spawned. Use this to:
107      /// - Establish network connections
108      /// - Register with services
109      /// - Load initial state
110      ///
111      /// # Errors
112      /// Returns an error if initialization fails
113      async fn setup(&mut self, context: &BotContext) -> Result<()>;
114  
115      /// Execute a behavior pattern
116      ///
117      /// This is the main action method. It executes a specific behavior
118      /// pattern identified by behavior_id.
119      ///
120      /// # Arguments
121      /// - `behavior_id`: Identifier of the behavior to execute
122      ///
123      /// # Errors
124      /// Returns an error if behavior execution fails
125      async fn execute_behavior(&mut self, behavior_id: &str) -> Result<BehaviorResult>;
126  
127      /// Clean up the bot
128      ///
129      /// This is called when the bot is stopped. Use this to:
130      /// - Close network connections
131      /// - Unregister from services
132      /// - Flush pending operations
133      ///
134      /// # Errors
135      /// Returns an error if teardown fails
136      async fn teardown(&mut self) -> Result<()>;
137  
138      /// Get the bot's unique identifier
139      fn id(&self) -> &str;
140  
141      /// Get the bot's role
142      fn role(&self) -> &str;
143  
144      /// Get the bot's current state
145      fn state(&self) -> String {
146          "running".to_string()
147      }
148  }
149  
150  /// A builder for creating bot instances
151  pub struct BotBuilder {
152      bot_id: String,
153      role: String,
154      execution_context: ExecutionContext,
155  }
156  
157  impl BotBuilder {
158      pub fn new(bot_id: String, role: String, execution_context: ExecutionContext) -> Self {
159          Self {
160              bot_id,
161              role,
162              execution_context,
163          }
164      }
165  
166      pub fn build_context(self, identity: Identity, wallet: Wallet) -> BotContext {
167          BotContext::new(self.execution_context, identity, wallet)
168      }
169  }