Skip to main content

stakpak_shared/models/
subagent.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::path::Path;
4
5#[derive(Debug, Clone, Deserialize, Serialize)]
6pub struct WardenConfig {
7    pub enabled: bool,
8    #[serde(default)]
9    pub volumes: Vec<String>,
10}
11
12#[derive(Debug, Clone, Deserialize, Serialize)]
13pub struct SubagentConfig {
14    pub description: String,
15    pub max_steps: usize,
16    pub allowed_tools: Vec<String>,
17    #[serde(default)]
18    pub warden: Option<WardenConfig>,
19}
20
21#[derive(Debug, Clone, Deserialize, Serialize)]
22pub struct SubagentConfigs {
23    pub subagents: HashMap<String, SubagentConfig>,
24}
25
26impl SubagentConfigs {
27    pub fn load_from_file<P: AsRef<Path>>(path: P) -> Result<Self, Box<dyn std::error::Error>> {
28        let content = std::fs::read_to_string(path)?;
29        Self::load_from_str(&content)
30    }
31
32    pub fn load_from_str(content: &str) -> Result<Self, Box<dyn std::error::Error>> {
33        let config: SubagentConfigs = toml::from_str(content)?;
34        Ok(config)
35    }
36
37    pub fn get_available_types(&self) -> Vec<String> {
38        self.subagents.keys().cloned().collect()
39    }
40
41    pub fn get_config(&self, subagent_type: &str) -> Option<&SubagentConfig> {
42        self.subagents.get(subagent_type)
43    }
44
45    pub fn format_for_context(&self) -> String {
46        if self.subagents.is_empty() {
47            "# No Subagents Available".to_string()
48        } else {
49            let subagents_text = self
50                .subagents
51                .iter()
52                .map(|(name, config)| {
53                    format!(
54                        "  - Name: {}\n    Description: {}\n    Tools: {}",
55                        name,
56                        config.description,
57                        config.allowed_tools.join(", ")
58                    )
59                })
60                .collect::<Vec<String>>()
61                .join("\n");
62
63            format!(
64                "SPACING_MARKER\n# Available Subagents:\nSPACING_MARKER\n{}",
65                subagents_text
66            )
67        }
68    }
69}