1use std::collections::BTreeSet;
2use std::sync::Arc;
3
4use crate::metrics::MetricsCollector;
5use crate::skills::SkillManager;
6use bamboo_agent_core::composition::CompositionExecutor;
7use bamboo_agent_core::storage::AttachmentReader;
8use bamboo_agent_core::storage::Storage;
9use bamboo_agent_core::tools::ToolSchema;
10use bamboo_compression::TokenBudget;
11use bamboo_domain::ReasoningEffort;
12use bamboo_infrastructure::config::PermissionMode;
13use bamboo_infrastructure::LLMProvider;
14use bamboo_infrastructure::MemoryConfig;
15use bamboo_tools::ToolRegistry;
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
18pub enum ImageFallbackMode {
19 Placeholder,
20 Error,
21 Ocr,
22 Vision,
26}
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct ImageFallbackConfig {
30 pub mode: ImageFallbackMode,
31 pub vision_model: Option<String>,
34}
35
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub struct PromptMemoryFlags {
38 pub project_prompt_injection: bool,
39 pub relevant_recall: bool,
40 pub relevant_recall_rerank: bool,
41 pub project_first_dream: bool,
42}
43
44impl Default for PromptMemoryFlags {
45 fn default() -> Self {
46 Self {
47 project_prompt_injection: true,
48 relevant_recall: true,
49 relevant_recall_rerank: false,
50 project_first_dream: true,
51 }
52 }
53}
54
55impl From<&MemoryConfig> for PromptMemoryFlags {
56 fn from(value: &MemoryConfig) -> Self {
57 Self {
58 project_prompt_injection: value.project_prompt_injection,
59 relevant_recall: value.relevant_recall,
60 relevant_recall_rerank: value.relevant_recall_rerank,
61 project_first_dream: value.project_first_dream,
62 }
63 }
64}
65
66pub struct AgentLoopConfig {
68 pub max_rounds: usize,
69 pub system_prompt: Option<String>,
70 pub disabled_skill_ids: BTreeSet<String>,
72 pub selected_skill_ids: Option<Vec<String>>,
75 pub selected_skill_mode: Option<String>,
80 pub additional_tool_schemas: Vec<ToolSchema>,
81 pub tool_registry: Arc<ToolRegistry>,
82 pub composition_executor: Option<Arc<CompositionExecutor>>,
83 pub skill_manager: Option<Arc<SkillManager>>,
84 pub skip_initial_user_message: bool,
86 pub storage: Option<Arc<dyn Storage>>,
88 pub attachment_reader: Option<Arc<dyn AttachmentReader>>,
91 pub metrics_collector: Option<MetricsCollector>,
93 pub model_name: Option<String>,
95 pub fast_model_name: Option<String>,
100 pub background_model_name: Option<String>,
106 pub planning_model_name: Option<String>,
109 pub search_model_name: Option<String>,
112 pub compression_instructions: Option<String>,
117 pub summarization_model_name: Option<String>,
119 pub background_model_provider: Option<Arc<dyn LLMProvider>>,
124 pub provider_name: Option<String>,
126 pub reasoning_effort: Option<ReasoningEffort>,
128 pub disabled_tools: BTreeSet<String>,
130 pub token_budget: Option<TokenBudget>,
132 pub image_fallback: Option<ImageFallbackConfig>,
137 pub prompt_memory_flags: PromptMemoryFlags,
139 pub max_tool_calls_per_round: usize,
141 pub max_consecutive_failures_per_tool: usize,
143 pub strict_argument_tool_names: Vec<String>,
145 pub per_tool_timeout_secs: u64,
147 pub parallel_batch_timeout_secs: u64,
149 pub permission_mode: Option<PermissionMode>,
151 pub features_dynamic_model_routing: bool,
155}
156
157impl Default for AgentLoopConfig {
158 fn default() -> Self {
159 Self {
160 max_rounds: 200,
161 system_prompt: None,
162 disabled_skill_ids: BTreeSet::new(),
163 selected_skill_ids: None,
164 selected_skill_mode: None,
165 additional_tool_schemas: Vec::new(),
166 tool_registry: Arc::new(ToolRegistry::new()),
167 composition_executor: None,
168 skill_manager: None,
169 skip_initial_user_message: false,
170 storage: None,
171 attachment_reader: None,
172 metrics_collector: None,
173 model_name: None,
174 fast_model_name: None,
175 background_model_name: None,
176 planning_model_name: None,
177 search_model_name: None,
178 compression_instructions: None,
179 summarization_model_name: None,
180 background_model_provider: None,
181 provider_name: None,
182 reasoning_effort: None,
183 disabled_tools: BTreeSet::new(),
184 token_budget: None,
185 image_fallback: None,
186 prompt_memory_flags: PromptMemoryFlags::default(),
187 max_tool_calls_per_round: 80,
188 max_consecutive_failures_per_tool: 3,
189 strict_argument_tool_names: vec![
190 "Write".into(),
191 "Edit".into(),
192 "NotebookEdit".into(),
193 "apply_patch".into(),
194 "Bash".into(),
195 "Task".into(),
196 "SubSession".into(),
197 "scheduler".into(),
198 "sub_session_manager".into(),
199 "session_note".into(),
200 "memory_note".into(),
201 ],
202 per_tool_timeout_secs: 120,
203 parallel_batch_timeout_secs: 300,
204 permission_mode: None,
205 features_dynamic_model_routing: false,
206 }
207 }
208}
209
210#[cfg(test)]
211mod tests;