agentic_payments/system/
builder.rs1use super::{
4 AgentPool, AgenticVerificationSystem, MeshTopology, SystemHealth, SystemMetrics, Topology,
5};
6use crate::agents::{BasicVerificationAgent, VerificationAgent};
7use crate::consensus::{ConsensusConfig, ConsensusEngine};
8use crate::error::{Error, Result};
9use std::sync::Arc;
10use tokio::sync::RwLock;
11use uuid::Uuid;
12
13pub struct SystemBuilder {
15 pool_size: usize,
16 consensus_threshold: f64,
17 consensus_timeout_ms: u64,
18 max_pool_size: usize,
19}
20
21impl SystemBuilder {
22 pub fn new() -> Self {
24 Self {
25 pool_size: 5,
26 consensus_threshold: 0.67,
27 consensus_timeout_ms: 100,
28 max_pool_size: 100,
29 }
30 }
31
32 pub fn pool_size(mut self, size: usize) -> Self {
34 self.pool_size = size;
35 self
36 }
37
38 pub fn consensus_threshold(mut self, threshold: f64) -> Self {
40 self.consensus_threshold = threshold;
41 self
42 }
43
44 pub fn consensus_timeout_ms(mut self, timeout_ms: u64) -> Self {
46 self.consensus_timeout_ms = timeout_ms;
47 self
48 }
49
50 pub fn max_pool_size(mut self, max_size: usize) -> Self {
52 self.max_pool_size = max_size;
53 self
54 }
55
56 pub async fn build(self) -> Result<AgenticVerificationSystem> {
58 if self.pool_size < 3 {
60 return Err(Error::config("Pool size must be at least 3 for BFT consensus"));
61 }
62
63 if self.pool_size > self.max_pool_size {
64 return Err(Error::config(format!(
65 "Pool size {} exceeds maximum {}",
66 self.pool_size, self.max_pool_size
67 )));
68 }
69
70 if !(0.0..=1.0).contains(&self.consensus_threshold) {
71 return Err(Error::config("Consensus threshold must be between 0.0 and 1.0"));
72 }
73
74 let consensus_config = ConsensusConfig::new(
76 self.consensus_threshold,
77 self.consensus_timeout_ms,
78 )?;
79
80 let mut pool = AgentPool::new(self.max_pool_size);
82
83 for _ in 0..self.pool_size {
85 let agent = BasicVerificationAgent::new()?;
86 pool.add_agent(Arc::new(agent) as Arc<dyn VerificationAgent>)
87 .await?;
88 }
89
90 let topology: Arc<dyn Topology + Send + Sync> = Arc::new(MeshTopology::new());
92
93 let consensus_engine = ConsensusEngine::new(consensus_config);
95
96 let metrics = SystemMetrics::new();
98 let health = SystemHealth::new();
99
100 Ok(AgenticVerificationSystem {
101 id: Uuid::new_v4(),
102 pool: Arc::new(RwLock::new(pool)),
103 topology,
104 consensus_engine: Arc::new(consensus_engine),
105 metrics: Arc::new(RwLock::new(metrics)),
106 health: Arc::new(RwLock::new(health)),
107 })
108 }
109}
110
111impl Default for SystemBuilder {
112 fn default() -> Self {
113 Self::new()
114 }
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[tokio::test]
122 async fn test_builder_default() {
123 let system = SystemBuilder::new().build().await.unwrap();
124 assert_eq!(system.pool_size().await, 5);
125 }
126
127 #[tokio::test]
128 async fn test_builder_custom_pool_size() {
129 let system = SystemBuilder::new()
130 .pool_size(10)
131 .build()
132 .await
133 .unwrap();
134 assert_eq!(system.pool_size().await, 10);
135 }
136
137 #[tokio::test]
138 async fn test_builder_invalid_pool_size() {
139 let result = SystemBuilder::new().pool_size(1).build().await;
140 assert!(result.is_err());
141 }
142
143 #[tokio::test]
144 async fn test_builder_custom_threshold() {
145 let system = SystemBuilder::new()
146 .consensus_threshold(0.75)
147 .pool_size(4)
148 .build()
149 .await
150 .unwrap();
151 assert_eq!(system.pool_size().await, 4);
152 }
153
154 #[tokio::test]
155 async fn test_builder_invalid_threshold() {
156 let result = SystemBuilder::new()
157 .consensus_threshold(1.5)
158 .build()
159 .await;
160 assert!(result.is_err());
161 }
162}