agents_runtime/agent/
config.rs

1//! Configuration structs and types for Deep Agents
2//!
3//! This module contains all the configuration structures used to build Deep Agents,
4//! including parameter structs that mirror the Python SDK API.
5
6use crate::middleware::{AgentMiddleware, HitlPolicy};
7use agents_core::agent::PlannerHandle;
8use agents_core::persistence::Checkpointer;
9use agents_core::tools::ToolBox;
10use std::collections::{HashMap, HashSet};
11use std::sync::Arc;
12
13/// Parameters for create_deep_agent() that mirror the Python API exactly
14///
15/// This struct matches the Python function signature:
16/// ```python
17/// def create_deep_agent(
18///     tools: Sequence[Union[BaseTool, Callable, dict[str, Any]]] = [],
19///     instructions: str = "",
20///     middleware: Optional[list[AgentMiddleware]] = None,
21///     model: Optional[Union[str, LanguageModelLike]] = None,
22///     subagents: Optional[list[SubAgent | CustomSubAgent]] = None,
23///     context_schema: Optional[Type[Any]] = None,
24///     checkpointer: Optional[Checkpointer] = None,
25///     tool_configs: Optional[dict[str, bool | ToolConfig]] = None,
26/// )
27/// ```
28#[derive(Default)]
29pub struct CreateDeepAgentParams {
30    pub tools: Vec<ToolBox>,
31    pub instructions: String,
32    pub middleware: Vec<Arc<dyn AgentMiddleware>>,
33    pub model: Option<Arc<dyn agents_core::llm::LanguageModel>>,
34    pub subagents: Vec<SubAgentConfig>,
35    pub context_schema: Option<String>,
36    pub checkpointer: Option<Arc<dyn Checkpointer>>,
37    pub tool_configs: HashMap<String, HitlPolicy>,
38}
39
40/// Configuration for building a deep agent instance.
41///
42/// This is the internal configuration used by the builder and runtime.
43pub struct DeepAgentConfig {
44    pub instructions: String,
45    pub planner: Arc<dyn PlannerHandle>,
46    pub tools: Vec<ToolBox>,
47    pub subagent_configs: Vec<SubAgentConfig>,
48    pub summarization: Option<SummarizationConfig>,
49    pub tool_interrupts: HashMap<String, HitlPolicy>,
50    pub builtin_tools: Option<HashSet<String>>,
51    pub auto_general_purpose: bool,
52    pub enable_prompt_caching: bool,
53    pub checkpointer: Option<Arc<dyn Checkpointer>>,
54    pub event_dispatcher: Option<Arc<agents_core::events::EventDispatcher>>,
55}
56
57impl DeepAgentConfig {
58    pub fn new(instructions: impl Into<String>, planner: Arc<dyn PlannerHandle>) -> Self {
59        Self {
60            instructions: instructions.into(),
61            planner,
62            tools: Vec::new(),
63            subagent_configs: Vec::new(),
64            summarization: None,
65            tool_interrupts: HashMap::new(),
66            builtin_tools: None,
67            auto_general_purpose: true,
68            enable_prompt_caching: false,
69            checkpointer: None,
70            event_dispatcher: None,
71        }
72    }
73
74    pub fn with_tool(mut self, tool: ToolBox) -> Self {
75        self.tools.push(tool);
76        self
77    }
78
79    /// Add a sub-agent configuration
80    pub fn with_subagent_config(mut self, config: SubAgentConfig) -> Self {
81        self.subagent_configs.push(config);
82        self
83    }
84
85    /// Add multiple sub-agent configurations
86    pub fn with_subagent_configs<I>(mut self, configs: I) -> Self
87    where
88        I: IntoIterator<Item = SubAgentConfig>,
89    {
90        self.subagent_configs.extend(configs);
91        self
92    }
93
94    pub fn with_summarization(mut self, config: SummarizationConfig) -> Self {
95        self.summarization = Some(config);
96        self
97    }
98
99    pub fn with_tool_interrupt(mut self, tool_name: impl Into<String>, policy: HitlPolicy) -> Self {
100        self.tool_interrupts.insert(tool_name.into(), policy);
101        self
102    }
103
104    /// Limit which built-in tools are exposed. When omitted, all built-ins are available.
105    /// Built-ins: write_todos, ls, read_file, write_file, edit_file.
106    /// The `task` tool (for subagents) is always available when subagents are registered.
107    pub fn with_builtin_tools<I, S>(mut self, names: I) -> Self
108    where
109        I: IntoIterator<Item = S>,
110        S: Into<String>,
111    {
112        let set: HashSet<String> = names.into_iter().map(|s| s.into()).collect();
113        self.builtin_tools = Some(set);
114        self
115    }
116
117    /// Enable or disable automatic registration of a "general-purpose" subagent.
118    /// Enabled by default; set to false to opt out.
119    pub fn with_auto_general_purpose(mut self, enabled: bool) -> Self {
120        self.auto_general_purpose = enabled;
121        self
122    }
123
124    /// Enable or disable Anthropic prompt caching middleware.
125    /// Disabled by default; set to true to enable caching for better performance.
126    pub fn with_prompt_caching(mut self, enabled: bool) -> Self {
127        self.enable_prompt_caching = enabled;
128        self
129    }
130
131    /// Set the checkpointer for persisting agent state between runs.
132    pub fn with_checkpointer(mut self, checkpointer: Arc<dyn Checkpointer>) -> Self {
133        self.checkpointer = Some(checkpointer);
134        self
135    }
136
137    /// Add an event broadcaster to the agent's event dispatcher.
138    pub fn with_event_broadcaster(
139        mut self,
140        broadcaster: Arc<dyn agents_core::events::EventBroadcaster>,
141    ) -> Self {
142        if self.event_dispatcher.is_none() {
143            self.event_dispatcher = Some(Arc::new(agents_core::events::EventDispatcher::new()));
144        }
145        if let Some(dispatcher) = Arc::get_mut(self.event_dispatcher.as_mut().unwrap()) {
146            dispatcher.add_broadcaster(broadcaster);
147        }
148        self
149    }
150
151    /// Set the event dispatcher directly.
152    pub fn with_event_dispatcher(
153        mut self,
154        dispatcher: Arc<agents_core::events::EventDispatcher>,
155    ) -> Self {
156        self.event_dispatcher = Some(dispatcher);
157        self
158    }
159}
160
161/// Configuration for creating and registering a subagent using a simple, Python-like shape.
162///
163/// Configuration for a sub-agent - a full AI agent with its own LLM, tools, and memory.
164///
165/// A sub-agent is just like the main agent: it has its own system instructions,
166/// tools, LLM, and can maintain its own conversation history. The main agent
167/// delegates tasks to sub-agents via the `task` tool.
168///
169/// ## Required Fields:
170/// - `name`: Unique identifier for this sub-agent
171/// - `description`: What this sub-agent specializes in (shown to main agent)
172/// - `instructions`: System prompt for this sub-agent
173///
174/// ## Optional Fields:
175/// - `model`: LLM to use (defaults to parent agent's model if not specified)
176/// - `tools`: Tools available to this sub-agent (defaults to empty)
177/// - `builtin_tools`: Built-in tools to enable (filesystem, todos, etc.)
178/// - `enable_prompt_caching`: Whether to cache prompts for efficiency
179pub struct SubAgentConfig {
180    // Required fields
181    pub name: String,
182    pub description: String,
183    pub instructions: String,
184
185    // Optional fields - agent configuration
186    pub model: Option<Arc<dyn agents_core::llm::LanguageModel>>,
187    pub tools: Option<Vec<ToolBox>>,
188    pub builtin_tools: Option<HashSet<String>>,
189    pub enable_prompt_caching: bool,
190}
191
192impl SubAgentConfig {
193    /// Create a new sub-agent configuration with required fields only
194    pub fn new(
195        name: impl Into<String>,
196        description: impl Into<String>,
197        instructions: impl Into<String>,
198    ) -> Self {
199        Self {
200            name: name.into(),
201            description: description.into(),
202            instructions: instructions.into(),
203            model: None,
204            tools: None,
205            builtin_tools: None,
206            enable_prompt_caching: false,
207        }
208    }
209
210    /// Set the LLM model for this sub-agent
211    pub fn with_model(mut self, model: Arc<dyn agents_core::llm::LanguageModel>) -> Self {
212        self.model = Some(model);
213        self
214    }
215
216    /// Set the tools for this sub-agent
217    pub fn with_tools(mut self, tools: Vec<ToolBox>) -> Self {
218        self.tools = Some(tools);
219        self
220    }
221
222    /// Enable specific built-in tools (filesystem, todos, etc.)
223    pub fn with_builtin_tools(mut self, tools: HashSet<String>) -> Self {
224        self.builtin_tools = Some(tools);
225        self
226    }
227
228    /// Enable prompt caching for this sub-agent
229    pub fn with_prompt_caching(mut self, enabled: bool) -> Self {
230        self.enable_prompt_caching = enabled;
231        self
232    }
233}
234
235impl IntoIterator for SubAgentConfig {
236    type Item = SubAgentConfig;
237    type IntoIter = std::iter::Once<SubAgentConfig>;
238
239    fn into_iter(self) -> Self::IntoIter {
240        std::iter::once(self)
241    }
242}
243
244/// Configuration for summarization middleware
245#[derive(Clone)]
246pub struct SummarizationConfig {
247    pub messages_to_keep: usize,
248    pub summary_note: String,
249}