use serde::{Deserialize, Serialize};
use super::llm::default_true;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManagerConfig {
#[serde(default)]
pub process_every_tick: bool,
#[serde(default = "default_process_interval_ticks")]
pub process_interval_ticks: u64,
#[serde(default = "default_true")]
pub immediate_on_escalation: bool,
#[serde(default = "default_confidence_threshold")]
pub confidence_threshold: f64,
}
fn default_process_interval_ticks() -> u64 {
5
}
fn default_confidence_threshold() -> f64 {
0.3
}
impl Default for ManagerConfig {
fn default() -> Self {
Self {
process_every_tick: false,
process_interval_ticks: default_process_interval_ticks(),
immediate_on_escalation: default_true(),
confidence_threshold: default_confidence_threshold(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BatchProcessorConfig {
#[serde(default = "default_true")]
pub parallel: bool,
#[serde(default = "default_max_concurrency")]
pub max_concurrency: usize,
}
fn default_max_concurrency() -> usize {
4
}
impl Default for BatchProcessorConfig {
fn default() -> Self {
Self {
parallel: true,
max_concurrency: default_max_concurrency(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManagerTemplate {
#[serde(default)]
pub id: Option<String>,
#[serde(default)]
pub id_pattern: Option<String>,
#[serde(default = "default_manager_count")]
pub count: usize,
#[serde(default)]
pub role: String,
#[serde(default)]
pub activation: ManagerActivationConfig,
#[serde(default)]
pub config: serde_json::Value,
}
fn default_manager_count() -> usize {
1
}
impl ManagerTemplate {
pub fn generate_ids(&self) -> Vec<String> {
if let Some(ref pattern) = self.id_pattern {
(0..self.count)
.map(|i| pattern.replace("{i}", &i.to_string()))
.collect()
} else if let Some(ref id) = self.id {
vec![id.clone()]
} else {
vec!["manager_0".to_string()]
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum ManagerActivationConfig {
Interval {
#[serde(default = "default_activation_interval")]
interval: u64,
},
Event {
#[serde(default)]
triggers: Vec<String>,
},
Hybrid {
#[serde(default = "default_activation_interval")]
interval: u64,
#[serde(default)]
triggers: Vec<String>,
},
}
fn default_activation_interval() -> u64 {
10
}
impl Default for ManagerActivationConfig {
fn default() -> Self {
Self::Interval {
interval: default_activation_interval(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_manager_config_default() {
let config = ManagerConfig::default();
assert!(!config.process_every_tick);
assert_eq!(config.process_interval_ticks, 5);
assert!(config.immediate_on_escalation);
assert!((config.confidence_threshold - 0.3).abs() < 0.001);
}
#[test]
fn test_manager_config_deserialize_toml() {
let toml_str = r#"
process_every_tick = true
process_interval_ticks = 10
immediate_on_escalation = false
confidence_threshold = 0.5
"#;
let config: ManagerConfig = toml::from_str(toml_str).unwrap();
assert!(config.process_every_tick);
assert_eq!(config.process_interval_ticks, 10);
assert!(!config.immediate_on_escalation);
assert!((config.confidence_threshold - 0.5).abs() < 0.001);
}
#[test]
fn test_batch_processor_config_default() {
let config = BatchProcessorConfig::default();
assert!(config.parallel);
assert_eq!(config.max_concurrency, 4);
}
#[test]
fn test_batch_processor_config_deserialize_toml() {
let toml_str = r#"
parallel = false
max_concurrency = 8
"#;
let config: BatchProcessorConfig = toml::from_str(toml_str).unwrap();
assert!(!config.parallel);
assert_eq!(config.max_concurrency, 8);
}
#[test]
fn test_manager_template_generate_ids() {
let template = ManagerTemplate {
id: Some("my_manager".to_string()),
id_pattern: None,
count: 1,
role: "llm_batch".to_string(),
activation: ManagerActivationConfig::default(),
config: serde_json::Value::Null,
};
assert_eq!(template.generate_ids(), vec!["my_manager"]);
let template = ManagerTemplate {
id: None,
id_pattern: Some("manager_{i}".to_string()),
count: 3,
role: "llm_batch".to_string(),
activation: ManagerActivationConfig::default(),
config: serde_json::Value::Null,
};
assert_eq!(
template.generate_ids(),
vec!["manager_0", "manager_1", "manager_2"]
);
}
#[test]
fn test_manager_activation_config_default() {
let config = ManagerActivationConfig::default();
match config {
ManagerActivationConfig::Interval { interval } => {
assert_eq!(interval, 10);
}
_ => panic!("Expected Interval variant"),
}
}
}