ggen_core/codegen/
swarm_executor_bridge.rs1use crate::codegen::{SwarmCoordinator, SwarmSummary};
2use crate::manifest::{GenerationRule, GgenManifest};
3use ggen_utils::error::Result;
4
5pub struct SwarmExecutorBridge {
6 coordinator: SwarmCoordinator,
7 high_risk_rules: Vec<String>,
8}
9
10impl SwarmExecutorBridge {
11 pub fn new(agent_count: usize, _manifest: GgenManifest, high_risk_rules: Vec<String>) -> Self {
12 Self {
13 coordinator: SwarmCoordinator::new(agent_count),
14 high_risk_rules,
15 }
16 }
17
18 pub async fn prepare_execution(&self, rules_to_run: Vec<GenerationRule>) -> Result<()> {
19 self.coordinator.enqueue_rules(rules_to_run).await?;
20 self.coordinator.distribute_work().await?;
21 Ok(())
22 }
23
24 pub async fn get_execution_summary(&self) -> Result<SwarmSummary> {
25 self.coordinator.get_swarm_summary().await
26 }
27
28 pub async fn record_rule_completion(&self, rule_name: &str) -> Result<()> {
29 self.coordinator.record_completion(rule_name).await
30 }
31
32 pub async fn record_rule_failure(&self, rule_name: &str) -> Result<()> {
33 self.coordinator.record_failure(rule_name).await
34 }
35
36 pub fn get_agent_prioritization(&self, rule_name: &str) -> u8 {
37 if self.high_risk_rules.contains(&rule_name.to_string()) {
38 10
39 } else {
40 1
41 }
42 }
43
44 pub fn estimate_concurrent_speedup(&self, total_rules: usize) -> f64 {
45 if total_rules == 0 {
46 return 1.0;
47 }
48
49 let agent_count = 4;
50 let parallelizable_ratio = 0.7;
51
52 1.0 / (1.0 - parallelizable_ratio + (parallelizable_ratio / agent_count as f64))
53 }
54}
55
56pub struct ExecutionStrategy {
57 pub use_swarm: bool,
58 pub agent_count: usize,
59 pub prioritize_high_risk: bool,
60 pub estimated_speedup: f64,
61}
62
63pub fn determine_execution_strategy(
64 rule_count: usize, high_risk_count: usize, manifest_changed: bool,
65) -> ExecutionStrategy {
66 let use_swarm = rule_count > 10 && !manifest_changed;
67 let agent_count = if use_swarm { 4 } else { 1 };
68
69 let mut estimated_speedup = 1.0;
70 if use_swarm {
71 estimated_speedup = 1.0 / (1.0 - 0.7 + (0.7 / 4.0));
72 }
73
74 ExecutionStrategy {
75 use_swarm,
76 agent_count,
77 prioritize_high_risk: high_risk_count > 0,
78 estimated_speedup,
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85 use std::collections::BTreeMap;
86
87 fn create_test_manifest() -> GgenManifest {
88 GgenManifest {
89 project: crate::manifest::ProjectConfig {
90 name: "test".to_string(),
91 version: "1.0.0".to_string(),
92 description: None,
93 },
94 ontology: crate::manifest::OntologyConfig {
95 source: "ontology.ttl".into(),
96 imports: vec![],
97 base_iri: None,
98 prefixes: BTreeMap::new(),
99 },
100 inference: crate::manifest::InferenceConfig::default(),
101 generation: crate::manifest::GenerationConfig {
102 rules: vec![],
103 output_dir: "output".into(),
104 require_audit_trail: false,
105 determinism_salt: None,
106 max_sparql_timeout_ms: 5000,
107 },
108 validation: crate::manifest::ValidationConfig::default(),
109 }
110 }
111
112 #[test]
113 fn test_execution_strategy_small_batch() {
114 let strategy = determine_execution_strategy(3, 0, false);
115 assert!(!strategy.use_swarm);
116 assert_eq!(strategy.agent_count, 1);
117 }
118
119 #[test]
120 fn test_execution_strategy_large_batch() {
121 let strategy = determine_execution_strategy(20, 2, false);
122 assert!(strategy.use_swarm);
123 assert_eq!(strategy.agent_count, 4);
124 assert!(strategy.estimated_speedup > 1.0);
125 }
126
127 #[test]
128 fn test_execution_strategy_manifest_changed() {
129 let strategy = determine_execution_strategy(50, 5, true);
130 assert!(!strategy.use_swarm);
131 }
132
133 #[test]
134 fn test_prioritization_high_risk() {
135 let manifest = create_test_manifest();
136 let bridge = SwarmExecutorBridge::new(4, manifest, vec!["high-risk-rule".to_string()]);
137
138 let priority = bridge.get_agent_prioritization("high-risk-rule");
139 assert_eq!(priority, 10);
140 }
141
142 #[test]
143 fn test_prioritization_normal() {
144 let manifest = create_test_manifest();
145 let bridge = SwarmExecutorBridge::new(4, manifest, vec![]);
146
147 let priority = bridge.get_agent_prioritization("normal-rule");
148 assert_eq!(priority, 1);
149 }
150
151 #[test]
152 fn test_speedup_estimation() {
153 let manifest = create_test_manifest();
154 let bridge = SwarmExecutorBridge::new(4, manifest, vec![]);
155
156 let speedup = bridge.estimate_concurrent_speedup(20);
157 assert!(speedup > 1.0);
158 assert!(speedup < 4.0);
159 }
160}