a3s_code_core/orchestrator/
config.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone)]
7pub struct OrchestratorConfig {
8 pub event_buffer_size: usize,
10
11 pub control_buffer_size: usize,
13
14 pub max_concurrent_subagents: usize,
16
17 pub subject_prefix: String,
19}
20
21impl Default for OrchestratorConfig {
22 fn default() -> Self {
23 Self {
24 event_buffer_size: 1000,
25 control_buffer_size: 100,
26 max_concurrent_subagents: 50,
27 subject_prefix: "agent".to_string(),
28 }
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize)]
34pub struct SubAgentConfig {
35 pub agent_type: String,
37
38 pub description: String,
40
41 pub prompt: String,
43
44 #[serde(default)]
46 pub permissive: bool,
47
48 #[serde(default)]
50 pub permissive_deny: Vec<String>,
51
52 pub max_steps: Option<usize>,
54
55 pub timeout_ms: Option<u64>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub parent_id: Option<String>,
61
62 #[serde(default)]
64 pub metadata: serde_json::Value,
65
66 #[serde(default = "default_workspace")]
68 pub workspace: String,
69
70 #[serde(default)]
72 pub agent_dirs: Vec<String>,
73
74 #[serde(default)]
76 pub skill_dirs: Vec<String>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
84 pub lane_config: Option<crate::queue::SessionQueueConfig>,
85}
86
87#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct SubAgentInfo {
90 pub id: String,
92
93 pub agent_type: String,
95
96 pub description: String,
98
99 pub state: String,
101
102 pub parent_id: Option<String>,
104
105 pub created_at: u64,
107
108 pub updated_at: u64,
110
111 pub current_activity: Option<SubAgentActivity>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize)]
117#[serde(tag = "type", rename_all = "snake_case")]
118pub enum SubAgentActivity {
119 Idle,
121
122 CallingTool {
124 tool_name: String,
125 args: serde_json::Value,
126 },
127
128 RequestingLlm { message_count: usize },
130
131 WaitingForControl { reason: String },
133}
134
135impl SubAgentConfig {
136 pub fn new(agent_type: impl Into<String>, prompt: impl Into<String>) -> Self {
138 Self {
139 agent_type: agent_type.into(),
140 description: String::new(),
141 prompt: prompt.into(),
142 permissive: false,
143 permissive_deny: Vec::new(),
144 max_steps: None,
145 timeout_ms: None,
146 parent_id: None,
147 metadata: serde_json::Value::Null,
148 workspace: default_workspace(),
149 agent_dirs: Vec::new(),
150 skill_dirs: Vec::new(),
151 lane_config: None,
152 }
153 }
154
155 pub fn with_description(mut self, description: impl Into<String>) -> Self {
157 self.description = description.into();
158 self
159 }
160
161 pub fn with_permissive(mut self, permissive: bool) -> Self {
163 self.permissive = permissive;
164 self
165 }
166
167 pub fn with_permissive_deny(mut self, deny_rules: Vec<String>) -> Self {
169 self.permissive_deny = deny_rules;
170 self
171 }
172
173 pub fn with_max_steps(mut self, max_steps: usize) -> Self {
175 self.max_steps = Some(max_steps);
176 self
177 }
178
179 pub fn with_timeout_ms(mut self, timeout_ms: u64) -> Self {
181 self.timeout_ms = Some(timeout_ms);
182 self
183 }
184
185 pub fn with_parent_id(mut self, parent_id: impl Into<String>) -> Self {
187 self.parent_id = Some(parent_id.into());
188 self
189 }
190
191 pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
193 self.metadata = metadata;
194 self
195 }
196
197 pub fn with_workspace(mut self, workspace: impl Into<String>) -> Self {
199 self.workspace = workspace.into();
200 self
201 }
202
203 pub fn with_agent_dirs(mut self, dirs: Vec<String>) -> Self {
205 self.agent_dirs = dirs;
206 self
207 }
208
209 pub fn with_skill_dirs(mut self, dirs: Vec<String>) -> Self {
211 self.skill_dirs = dirs;
212 self
213 }
214
215 pub fn with_lane_config(mut self, config: crate::queue::SessionQueueConfig) -> Self {
217 self.lane_config = Some(config);
218 self
219 }
220}
221
222fn default_workspace() -> String {
223 ".".to_string()
224}
225
226#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct AgentSlot {
234 pub agent_type: String,
236
237 #[serde(skip_serializing_if = "Option::is_none")]
239 pub role: Option<crate::agent_teams::TeamRole>,
240
241 pub description: String,
243
244 pub prompt: String,
246
247 #[serde(default)]
249 pub permissive: bool,
250
251 #[serde(default)]
253 pub permissive_deny: Vec<String>,
254
255 pub max_steps: Option<usize>,
257
258 pub timeout_ms: Option<u64>,
260
261 #[serde(skip_serializing_if = "Option::is_none")]
263 pub parent_id: Option<String>,
264
265 #[serde(default)]
267 pub metadata: serde_json::Value,
268
269 #[serde(default = "default_workspace")]
271 pub workspace: String,
272
273 #[serde(default)]
275 pub agent_dirs: Vec<String>,
276
277 #[serde(default)]
279 pub skill_dirs: Vec<String>,
280
281 #[serde(skip_serializing_if = "Option::is_none")]
283 pub lane_config: Option<crate::queue::SessionQueueConfig>,
284}
285
286impl AgentSlot {
287 pub fn new(agent_type: impl Into<String>, prompt: impl Into<String>) -> Self {
289 Self {
290 agent_type: agent_type.into(),
291 role: None,
292 description: String::new(),
293 prompt: prompt.into(),
294 permissive: false,
295 permissive_deny: Vec::new(),
296 max_steps: None,
297 timeout_ms: None,
298 parent_id: None,
299 metadata: serde_json::Value::Null,
300 workspace: default_workspace(),
301 agent_dirs: Vec::new(),
302 skill_dirs: Vec::new(),
303 lane_config: None,
304 }
305 }
306
307 pub fn with_role(mut self, role: crate::agent_teams::TeamRole) -> Self {
309 self.role = Some(role);
310 self
311 }
312
313 pub fn with_description(mut self, description: impl Into<String>) -> Self {
315 self.description = description.into();
316 self
317 }
318
319 pub fn with_permissive(mut self, permissive: bool) -> Self {
321 self.permissive = permissive;
322 self
323 }
324
325 pub fn with_permissive_deny(mut self, deny_rules: Vec<String>) -> Self {
327 self.permissive_deny = deny_rules;
328 self
329 }
330
331 pub fn with_max_steps(mut self, max_steps: usize) -> Self {
333 self.max_steps = Some(max_steps);
334 self
335 }
336
337 pub fn with_timeout_ms(mut self, timeout_ms: u64) -> Self {
339 self.timeout_ms = Some(timeout_ms);
340 self
341 }
342
343 pub fn with_parent_id(mut self, parent_id: impl Into<String>) -> Self {
345 self.parent_id = Some(parent_id.into());
346 self
347 }
348
349 pub fn with_metadata(mut self, metadata: serde_json::Value) -> Self {
351 self.metadata = metadata;
352 self
353 }
354
355 pub fn with_workspace(mut self, workspace: impl Into<String>) -> Self {
357 self.workspace = workspace.into();
358 self
359 }
360
361 pub fn with_agent_dirs(mut self, dirs: Vec<String>) -> Self {
363 self.agent_dirs = dirs;
364 self
365 }
366
367 pub fn with_skill_dirs(mut self, dirs: Vec<String>) -> Self {
369 self.skill_dirs = dirs;
370 self
371 }
372
373 pub fn with_lane_config(mut self, config: crate::queue::SessionQueueConfig) -> Self {
375 self.lane_config = Some(config);
376 self
377 }
378}
379
380impl From<SubAgentConfig> for AgentSlot {
381 fn from(c: SubAgentConfig) -> Self {
382 Self {
383 agent_type: c.agent_type,
384 role: None,
385 description: c.description,
386 prompt: c.prompt,
387 permissive: c.permissive,
388 permissive_deny: c.permissive_deny,
389 max_steps: c.max_steps,
390 timeout_ms: c.timeout_ms,
391 parent_id: c.parent_id,
392 metadata: c.metadata,
393 workspace: c.workspace,
394 agent_dirs: c.agent_dirs,
395 skill_dirs: c.skill_dirs,
396 lane_config: c.lane_config,
397 }
398 }
399}
400
401impl From<AgentSlot> for SubAgentConfig {
402 fn from(s: AgentSlot) -> Self {
403 Self {
404 agent_type: s.agent_type,
405 description: s.description,
406 prompt: s.prompt,
407 permissive: s.permissive,
408 permissive_deny: s.permissive_deny,
409 max_steps: s.max_steps,
410 timeout_ms: s.timeout_ms,
411 parent_id: s.parent_id,
412 metadata: s.metadata,
413 workspace: s.workspace,
414 agent_dirs: s.agent_dirs,
415 skill_dirs: s.skill_dirs,
416 lane_config: s.lane_config,
417 }
418 }
419}