1pub mod executor;
13pub mod orchestrator;
14pub mod rate_limiter;
15pub mod subtask;
16
17pub use executor::{SwarmExecutor, run_agent_loop};
18pub use orchestrator::Orchestrator;
19pub use rate_limiter::{AdaptiveRateLimiter, RateLimitInfo, RateLimitStats};
20pub use subtask::{SubAgent, SubTask, SubTaskContext, SubTaskResult, SubTaskStatus};
21
22use anyhow::Result;
23use async_trait::async_trait;
24
25#[async_trait]
30pub trait Actor: Send + Sync {
31 fn actor_id(&self) -> &str;
33
34 fn actor_status(&self) -> ActorStatus;
36
37 async fn initialize(&mut self) -> Result<()>;
39
40 async fn shutdown(&mut self) -> Result<()>;
42}
43
44#[async_trait]
49pub trait Handler<M>: Actor {
50 type Response: Send + Sync;
52
53 async fn handle(&mut self, message: M) -> Result<Self::Response>;
55}
56
57#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum ActorStatus {
60 Initializing,
62 Ready,
64 Busy,
66 Paused,
68 ShuttingDown,
70 Stopped,
72}
73
74impl std::fmt::Display for ActorStatus {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 match self {
77 ActorStatus::Initializing => write!(f, "initializing"),
78 ActorStatus::Ready => write!(f, "ready"),
79 ActorStatus::Busy => write!(f, "busy"),
80 ActorStatus::Paused => write!(f, "paused"),
81 ActorStatus::ShuttingDown => write!(f, "shutting_down"),
82 ActorStatus::Stopped => write!(f, "stopped"),
83 }
84 }
85}
86
87#[derive(Debug, Clone)]
89pub enum SwarmMessage {
90 ExecuteTask {
92 task_id: String,
93 instruction: String,
94 },
95 Progress {
97 task_id: String,
98 progress: f32,
99 message: String,
100 },
101 TaskCompleted { task_id: String, result: String },
103 TaskFailed { task_id: String, error: String },
105 ToolRequest {
107 tool_id: String,
108 arguments: serde_json::Value,
109 },
110 ToolResponse {
112 tool_id: String,
113 result: crate::tool::ToolResult,
114 },
115}
116
117use serde::{Deserialize, Serialize};
118
119pub const MAX_SUBAGENTS: usize = 100;
121
122pub const MAX_TOOL_CALLS: usize = 1500;
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct SwarmConfig {
128 pub max_subagents: usize,
130
131 pub max_steps_per_subagent: usize,
133
134 pub max_total_steps: usize,
136
137 pub subagent_timeout_secs: u64,
139
140 pub parallel_enabled: bool,
142
143 pub critical_path_threshold: usize,
145
146 pub model: Option<String>,
148
149 pub max_concurrent_requests: usize,
151
152 pub request_delay_ms: u64,
154
155 pub worktree_enabled: bool,
157
158 pub worktree_auto_merge: bool,
160
161 pub working_dir: Option<String>,
163}
164
165impl Default for SwarmConfig {
166 fn default() -> Self {
167 Self {
168 max_subagents: MAX_SUBAGENTS,
169 max_steps_per_subagent: 100,
170 max_total_steps: MAX_TOOL_CALLS,
171 subagent_timeout_secs: 600, parallel_enabled: true,
173 critical_path_threshold: 10,
174 model: None,
175 max_concurrent_requests: 3, request_delay_ms: 1000, worktree_enabled: true, worktree_auto_merge: true, working_dir: None,
180 }
181 }
182}
183
184#[derive(Debug, Clone, Default, Serialize, Deserialize)]
186pub struct SwarmStats {
187 pub subagents_spawned: usize,
189
190 pub subagents_completed: usize,
192
193 pub subagents_failed: usize,
195
196 pub total_tool_calls: usize,
198
199 pub critical_path_length: usize,
201
202 pub execution_time_ms: u64,
204
205 pub sequential_time_estimate_ms: u64,
207
208 pub speedup_factor: f64,
210
211 pub stages: Vec<StageStats>,
213
214 pub rate_limit_stats: RateLimitStats,
216}
217
218#[derive(Debug, Clone, Default, Serialize, Deserialize)]
220pub struct StageStats {
221 pub stage: usize,
223
224 pub subagent_count: usize,
226
227 pub max_steps: usize,
229
230 pub total_steps: usize,
232
233 pub execution_time_ms: u64,
235}
236
237impl SwarmStats {
238 pub fn calculate_speedup(&mut self) {
240 if self.execution_time_ms > 0 {
241 self.speedup_factor =
242 self.sequential_time_estimate_ms as f64 / self.execution_time_ms as f64;
243 }
244 }
245
246 pub fn calculate_critical_path(&mut self) {
248 self.critical_path_length = self.stages.iter().map(|s| s.max_steps).sum();
249 }
250}
251
252#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
254#[serde(rename_all = "snake_case")]
255pub enum DecompositionStrategy {
256 Automatic,
258
259 ByDomain,
261
262 ByData,
264
265 ByStage,
267
268 None,
270}
271
272impl Default for DecompositionStrategy {
273 fn default() -> Self {
274 Self::Automatic
275 }
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize)]
280pub struct SwarmResult {
281 pub success: bool,
283
284 pub result: String,
286
287 pub subtask_results: Vec<SubTaskResult>,
289
290 pub stats: SwarmStats,
292
293 pub artifacts: Vec<SwarmArtifact>,
295
296 pub error: Option<String>,
298}
299
300#[derive(Debug, Clone, Serialize, Deserialize)]
302pub struct SwarmArtifact {
303 pub artifact_type: String,
305
306 pub name: String,
308
309 pub content: String,
311
312 pub source_subagent: Option<String>,
314
315 pub mime_type: Option<String>,
317}