Skip to main content

dasein_agentic_core/distributed/
config.rs

1//! Configuration types for distributed agents.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashSet;
5
6/// Capabilities an agent can have.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
8#[serde(rename_all = "snake_case")]
9pub enum Capability {
10    /// Can generate code
11    CodeGeneration,
12    /// Can execute code
13    CodeExecution,
14    /// Can read files
15    FileRead,
16    /// Can write files
17    FileWrite,
18    /// Can make network requests
19    Network,
20    /// Can spawn child agents
21    SpawnChild,
22    /// Can delegate to other agents
23    Delegate,
24}
25
26/// Role in the distributed architecture.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
28#[serde(rename_all = "snake_case")]
29pub enum AgentRole {
30    Supervisor,
31    Executor,
32    Validator,
33}
34
35/// LLM provider configuration.
36#[derive(Debug, Clone)]
37pub struct LLMConfig {
38    pub provider: String,
39    pub model: String,
40    pub api_key: String,
41    pub temperature: f32,
42    pub max_tokens: u32,
43}
44
45impl LLMConfig {
46    /// Create Gemini config with sensible defaults.
47    /// Temperature is low (0.2) for deterministic code generation.
48    pub fn gemini(model: &str) -> Self {
49        Self {
50            provider: "gemini".into(),
51            model: model.into(),
52            api_key: std::env::var("GEMINI_API_KEY").unwrap_or_default(),
53            temperature: 0.2, // Low for reliable code generation
54            max_tokens: 8192, // Increased for larger outputs
55        }
56    }
57
58    /// Create OpenAI config with sensible defaults.
59    pub fn openai(model: &str) -> Self {
60        Self {
61            provider: "openai".into(),
62            model: model.into(),
63            api_key: std::env::var("OPENAI_API_KEY").unwrap_or_default(),
64            temperature: 0.7,
65            max_tokens: 4096,
66        }
67    }
68
69    /// Create Anthropic/Claude config with sensible defaults.
70    pub fn anthropic(model: &str) -> Self {
71        Self {
72            provider: "anthropic".into(),
73            model: model.into(),
74            api_key: std::env::var("ANTHROPIC_API_KEY").unwrap_or_default(),
75            temperature: 0.2, // Low for reliable code generation
76            max_tokens: 8192, // Claude supports large outputs
77        }
78    }
79
80    /// Set temperature.
81    #[must_use]
82    pub fn temperature(mut self, temp: f32) -> Self {
83        self.temperature = temp;
84        self
85    }
86
87    /// Set max tokens.
88    #[must_use]
89    pub fn max_tokens(mut self, tokens: u32) -> Self {
90        self.max_tokens = tokens;
91        self
92    }
93
94    /// Set API key.
95    #[must_use]
96    pub fn api_key(mut self, key: impl Into<String>) -> Self {
97        self.api_key = key.into();
98        self
99    }
100}
101
102/// Sandbox configuration.
103#[derive(Debug, Clone)]
104pub struct SandboxConfig {
105    pub sandbox_type: SandboxType,
106    pub timeout_ms: u64,
107    pub memory_limit: Option<u64>,
108    pub cpu_limit: Option<f32>,
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub enum SandboxType {
113    None,
114    Process,
115    Docker,
116}
117
118impl SandboxConfig {
119    /// No sandbox (generation only).
120    #[must_use]
121    pub fn none() -> Self {
122        Self {
123            sandbox_type: SandboxType::None,
124            timeout_ms: 0,
125            memory_limit: None,
126            cpu_limit: None,
127        }
128    }
129
130    /// Process-based sandbox (fast, less isolated).
131    #[must_use]
132    pub fn process() -> Self {
133        Self {
134            sandbox_type: SandboxType::Process,
135            timeout_ms: 30_000,
136            memory_limit: None,
137            cpu_limit: None,
138        }
139    }
140
141    /// Docker-based sandbox (slower, fully isolated).
142    #[must_use]
143    pub fn docker() -> Self {
144        Self {
145            sandbox_type: SandboxType::Docker,
146            timeout_ms: 60_000,
147            memory_limit: Some(512 * 1024 * 1024), // 512MB
148            cpu_limit: Some(1.0),
149        }
150    }
151
152    /// Set timeout.
153    #[must_use]
154    pub fn timeout_ms(mut self, ms: u64) -> Self {
155        self.timeout_ms = ms;
156        self
157    }
158
159    /// Set memory limit.
160    #[must_use]
161    pub fn memory_limit(mut self, bytes: u64) -> Self {
162        self.memory_limit = Some(bytes);
163        self
164    }
165}
166
167/// Supervisor configuration.
168#[derive(Debug, Clone)]
169pub struct SupervisorConfig {
170    pub id: String,
171    pub domain: String,
172    pub executor_count: usize,
173    pub validator_count: usize,
174    pub llm: LLMConfig,
175    pub sandbox: SandboxConfig,
176    pub capabilities: HashSet<Capability>,
177    pub allow_lending: bool,
178    pub allow_borrowing: bool,
179    pub max_borrowed: usize,
180    pub max_queue_depth: usize,
181    pub task_timeout_ms: u64,
182}
183
184impl Default for SupervisorConfig {
185    fn default() -> Self {
186        Self {
187            id: String::new(),
188            domain: "default".into(),
189            executor_count: 2,
190            validator_count: 1,
191            llm: LLMConfig::gemini("gemini-2.0-flash"),
192            sandbox: SandboxConfig::process(),
193            capabilities: HashSet::from([Capability::CodeGeneration]),
194            allow_lending: true,
195            allow_borrowing: true,
196            max_borrowed: 4,
197            max_queue_depth: 100,
198            task_timeout_ms: 60_000,
199        }
200    }
201}
202
203/// Executor configuration.
204#[derive(Debug, Clone)]
205pub struct ExecutorConfig {
206    pub id: String,
207    pub owner_supervisor: String,
208    pub llm: LLMConfig,
209    pub sandbox: SandboxConfig,
210    pub capabilities: HashSet<Capability>,
211}
212
213/// Validator configuration.
214#[derive(Debug, Clone)]
215pub struct ValidatorConfig {
216    pub id: String,
217    pub supervisor: String,
218    pub rules: Vec<String>,
219    pub max_retries: u32,
220}
221
222impl Default for ValidatorConfig {
223    fn default() -> Self {
224        Self {
225            id: String::new(),
226            supervisor: String::new(),
227            rules: vec!["output_not_empty".into()],
228            max_retries: 2,
229        }
230    }
231}