Skip to main content

walrus_core/agent/
config.rs

1//! Agent configuration.
2//!
3//! [`AgentConfig`] is a serializable struct holding all agent parameters.
4//! Used by [`super::AgentBuilder`] to construct an [`super::Agent`].
5
6use crate::model::ToolChoice;
7use compact_str::CompactString;
8use serde::{Deserialize, Serialize};
9
10/// Default maximum iterations for agent execution.
11const DEFAULT_MAX_ITERATIONS: usize = 16;
12
13/// Serializable agent configuration.
14///
15/// Contains all parameters for an agent: identity, system prompt, model,
16/// iteration limits, heartbeat, and delegation scope. Used both as the
17/// TOML deserialization target and the runtime agent definition.
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct AgentConfig {
20    /// Agent identifier. Derived from TOML key, not stored in TOML.
21    #[serde(skip)]
22    pub name: CompactString,
23    /// Human-readable description.
24    #[serde(default)]
25    pub description: CompactString,
26    /// System prompt sent before each LLM request. Loaded from .md file.
27    #[serde(skip)]
28    pub system_prompt: String,
29    /// Model to use from the registry. None = registry's active/default.
30    #[serde(default)]
31    pub model: Option<CompactString>,
32    /// Maximum iterations before stopping.
33    #[serde(default = "default_max_iterations")]
34    pub max_iterations: usize,
35    /// Controls which tool the model calls.
36    #[serde(skip)]
37    pub tool_choice: ToolChoice,
38    /// Whether to enable thinking/reasoning mode.
39    #[serde(default)]
40    pub thinking: bool,
41    /// Heartbeat configuration. Interval 0 (the default) means no heartbeat.
42    #[serde(default)]
43    pub heartbeat: HeartbeatConfig,
44    /// Agents this agent can delegate to via spawn_task. Empty = no delegation.
45    #[serde(default)]
46    pub members: Vec<String>,
47    /// Skill names this agent can access. Empty = all skills (walrus default).
48    #[serde(default)]
49    pub skills: Vec<String>,
50    /// MCP server names this agent can access. Empty = all MCPs (walrus default).
51    #[serde(default)]
52    pub mcps: Vec<String>,
53    /// Computed tool whitelist. Empty = all tools. Not serialized.
54    #[serde(skip)]
55    pub tools: Vec<CompactString>,
56}
57
58fn default_max_iterations() -> usize {
59    DEFAULT_MAX_ITERATIONS
60}
61
62impl Default for AgentConfig {
63    fn default() -> Self {
64        Self {
65            name: CompactString::default(),
66            description: CompactString::default(),
67            system_prompt: String::new(),
68            model: None,
69            max_iterations: DEFAULT_MAX_ITERATIONS,
70            tool_choice: ToolChoice::Auto,
71            thinking: false,
72            heartbeat: HeartbeatConfig::default(),
73            members: Vec::new(),
74            skills: Vec::new(),
75            mcps: Vec::new(),
76            tools: Vec::new(),
77        }
78    }
79}
80
81impl AgentConfig {
82    /// Create a new config with the given name and defaults for everything else.
83    pub fn new(name: impl Into<CompactString>) -> Self {
84        Self {
85            name: name.into(),
86            ..Default::default()
87        }
88    }
89
90    /// Set the system prompt.
91    pub fn system_prompt(mut self, prompt: impl Into<String>) -> Self {
92        self.system_prompt = prompt.into();
93        self
94    }
95
96    /// Set the description.
97    pub fn description(mut self, desc: impl Into<CompactString>) -> Self {
98        self.description = desc.into();
99        self
100    }
101
102    /// Set the model to use from the registry.
103    pub fn model(mut self, name: impl Into<CompactString>) -> Self {
104        self.model = Some(name.into());
105        self
106    }
107
108    /// Enable or disable thinking/reasoning mode.
109    pub fn thinking(mut self, enabled: bool) -> Self {
110        self.thinking = enabled;
111        self
112    }
113}
114
115/// Heartbeat timer configuration. Interval 0 = disabled.
116#[derive(Debug, Clone, Serialize, Deserialize, Default)]
117pub struct HeartbeatConfig {
118    /// Interval in minutes (0 = disabled).
119    #[serde(default)]
120    pub interval: u64,
121    /// System prompt for heartbeat-triggered agent runs.
122    #[serde(default)]
123    pub prompt: String,
124}