use super::{
AgentPool, AgenticVerificationSystem, MeshTopology, SystemHealth, SystemMetrics, Topology,
};
use crate::agents::{BasicVerificationAgent, VerificationAgent};
use crate::consensus::{ConsensusConfig, ConsensusEngine};
use crate::error::{Error, Result};
use std::sync::Arc;
use tokio::sync::RwLock;
use uuid::Uuid;
pub struct SystemBuilder {
pool_size: usize,
consensus_threshold: f64,
consensus_timeout_ms: u64,
max_pool_size: usize,
}
impl SystemBuilder {
pub fn new() -> Self {
Self {
pool_size: 5,
consensus_threshold: 0.67,
consensus_timeout_ms: 100,
max_pool_size: 100,
}
}
pub fn pool_size(mut self, size: usize) -> Self {
self.pool_size = size;
self
}
pub fn consensus_threshold(mut self, threshold: f64) -> Self {
self.consensus_threshold = threshold;
self
}
pub fn consensus_timeout_ms(mut self, timeout_ms: u64) -> Self {
self.consensus_timeout_ms = timeout_ms;
self
}
pub fn max_pool_size(mut self, max_size: usize) -> Self {
self.max_pool_size = max_size;
self
}
pub async fn build(self) -> Result<AgenticVerificationSystem> {
if self.pool_size < 3 {
return Err(Error::config("Pool size must be at least 3 for BFT consensus"));
}
if self.pool_size > self.max_pool_size {
return Err(Error::config(format!(
"Pool size {} exceeds maximum {}",
self.pool_size, self.max_pool_size
)));
}
if !(0.0..=1.0).contains(&self.consensus_threshold) {
return Err(Error::config("Consensus threshold must be between 0.0 and 1.0"));
}
let consensus_config = ConsensusConfig::new(
self.consensus_threshold,
self.consensus_timeout_ms,
)?;
let mut pool = AgentPool::new(self.max_pool_size);
for _ in 0..self.pool_size {
let agent = BasicVerificationAgent::new()?;
pool.add_agent(Arc::new(agent) as Arc<dyn VerificationAgent>)
.await?;
}
let topology: Arc<dyn Topology + Send + Sync> = Arc::new(MeshTopology::new());
let consensus_engine = ConsensusEngine::new(consensus_config);
let metrics = SystemMetrics::new();
let health = SystemHealth::new();
Ok(AgenticVerificationSystem {
id: Uuid::new_v4(),
pool: Arc::new(RwLock::new(pool)),
topology,
consensus_engine: Arc::new(consensus_engine),
metrics: Arc::new(RwLock::new(metrics)),
health: Arc::new(RwLock::new(health)),
})
}
}
impl Default for SystemBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_builder_default() {
let system = SystemBuilder::new().build().await.unwrap();
assert_eq!(system.pool_size().await, 5);
}
#[tokio::test]
async fn test_builder_custom_pool_size() {
let system = SystemBuilder::new()
.pool_size(10)
.build()
.await
.unwrap();
assert_eq!(system.pool_size().await, 10);
}
#[tokio::test]
async fn test_builder_invalid_pool_size() {
let result = SystemBuilder::new().pool_size(1).build().await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_builder_custom_threshold() {
let system = SystemBuilder::new()
.consensus_threshold(0.75)
.pool_size(4)
.build()
.await
.unwrap();
assert_eq!(system.pool_size().await, 4);
}
#[tokio::test]
async fn test_builder_invalid_threshold() {
let result = SystemBuilder::new()
.consensus_threshold(1.5)
.build()
.await;
assert!(result.is_err());
}
}