Skip to main content

matrixcode_core/agent/
builder.rs

1//! Agent builder implementation.
2
3use std::path::PathBuf;
4use std::sync::Arc;
5
6use crate::approval::ApproveMode;
7use crate::compress::CompressionConfig;
8use crate::constants::QUICK_ACTION_MAX_TOKENS;
9use crate::event::AgentEvent;
10use crate::prompt::PromptProfile;
11use crate::providers::Provider;
12use crate::skills::Skill;
13use crate::tools::Tool;
14use crate::tools::code_quality_hook::VerificationStrategy;
15use crate::tools::toolproxy::{ProxyToolDef, ProxyToolExecutor};
16
17use super::types::{Agent, AgentBuilder};
18
19impl AgentBuilder {
20    pub fn new(provider: Box<dyn Provider>) -> Self {
21        Self {
22            provider,
23            model_name: "unknown".to_string(),
24            tools: Vec::new(),
25            max_tokens: QUICK_ACTION_MAX_TOKENS,
26            context_size_override: None,
27            think: false,
28            compression_config: CompressionConfig::default(),
29            verify_strategy: VerificationStrategy::default(),
30            profile: PromptProfile::Default,
31            skills: Vec::new(),
32            project_overview: None,
33            memory_summary: None,
34            project_path: None,
35            event_tx: None,
36            pending_input_rx: None,
37            approve_mode: ApproveMode::Auto,
38            proxy_tool_defs: Vec::new(),
39            proxy_executor: None,
40            mcp_registry: None,
41            lsp_registry: None,
42        }
43    }
44
45    pub fn model_name(mut self, name: impl Into<String>) -> Self {
46        self.model_name = name.into();
47        self
48    }
49
50    pub fn max_tokens(mut self, tokens: u32) -> Self {
51        self.max_tokens = tokens;
52        self
53    }
54
55    /// Override provider-inferred context window size.
56    pub fn context_size(mut self, context_size: Option<u32>) -> Self {
57        self.context_size_override = context_size;
58        self
59    }
60
61    /// Set compression config
62    pub fn compression_config(mut self, config: CompressionConfig) -> Self {
63        self.compression_config = config;
64        self
65    }
66
67    pub fn think(mut self, enabled: bool) -> Self {
68        self.think = enabled;
69        self
70    }
71
72    /// Set code verification strategy for write operations.
73    ///
74    /// Controls whether and when code quality checks run on edit/write/multi_edit.
75    /// - `None`: No verification
76    /// - `Post`: Verify after write (default)
77    /// - `Pre`: Verify before write, block if errors
78    /// - `PreQuick`: Quick syntax check before, full check after
79    pub fn verify_strategy(mut self, strategy: VerificationStrategy) -> Self {
80        self.verify_strategy = strategy;
81        self
82    }
83
84    pub fn approve_mode(mut self, mode: ApproveMode) -> Self {
85        self.approve_mode = mode;
86        self
87    }
88
89    pub fn tool(mut self, tool: Arc<dyn Tool>) -> Self {
90        self.tools.push(tool);
91        self
92    }
93
94    /// Add multiple tools
95    pub fn tools(mut self, tools: Vec<Box<dyn Tool>>) -> Self {
96        self.tools.extend(tools.into_iter().map(Arc::from));
97        self
98    }
99
100    /// Add multiple tools with provider support
101    pub fn tools_with_provider(mut self, tools: Vec<Box<dyn Tool>>) -> Self {
102        self.tools.extend(tools.into_iter().map(Arc::from));
103        self
104    }
105
106    /// Set external event sender for streaming events
107    pub fn event_tx(mut self, tx: tokio::sync::mpsc::Sender<AgentEvent>) -> Self {
108        self.event_tx = Some(tx);
109        self
110    }
111
112    /// Add skills
113    pub fn skills(mut self, skills: Vec<Skill>) -> Self {
114        self.skills = skills;
115        self
116    }
117
118    /// Set prompt profile
119    pub fn profile(mut self, profile: PromptProfile) -> Self {
120        self.profile = profile;
121        self
122    }
123
124    /// Set project overview
125    pub fn overview(mut self, overview: impl Into<String>) -> Self {
126        self.project_overview = Some(overview.into());
127        self
128    }
129
130    /// Set memory summary
131    pub fn memory(mut self, summary: impl Into<String>) -> Self {
132        self.memory_summary = Some(summary.into());
133        self
134    }
135
136    /// Set system prompt directly (overrides auto-generated prompt).
137    /// Use with caution - this bypasses the normal prompt building process.
138    pub fn system_prompt(mut self, prompt: String) -> Self {
139        // Store as project_overview to be used in prompt building
140        // This is a workaround since system_prompt is built from context
141        self.project_overview = Some(prompt);
142        self
143    }
144
145    /// Set project path (for dynamic tool injection like CodeGraph)
146    pub fn project_path(mut self, path: PathBuf) -> Self {
147        self.project_path = Some(path);
148        self
149    }
150
151    /// 设置代理工具执行器
152    ///
153    /// # Example
154    /// ```ignore
155    /// use std::sync::Arc;
156    /// use serde_json::json;
157    /// use matrixcode_core::tools::toolproxy::{ProxyToolExecutor, ProxyToolDef};
158    ///
159    /// let executor = Arc::new(MyProxyExecutor);
160    /// let tool_def = ProxyToolDef::new("image_search", "搜索图片", json!({...}))
161    ///     .with_priority(true);
162    ///
163    /// builder.proxy_executor(executor, vec![tool_def])
164    /// ```
165    pub fn proxy_executor(
166        mut self,
167        executor: Arc<dyn ProxyToolExecutor>,
168        tool_defs: Vec<ProxyToolDef>,
169    ) -> Self {
170        self.proxy_executor = Some(executor);
171        self.proxy_tool_defs = tool_defs;
172        self
173    }
174
175    pub fn build(self) -> Agent {
176        Agent::new(self)
177    }
178
179    /// 设置 MCP 工具注册表
180    ///
181    /// # Example
182    /// ```ignore
183    /// use std::sync::Arc;
184    /// use matrixcode_core::mcp::McpToolRegistry;
185    ///
186    /// let registry = Arc::new(tokio::sync::RwLock::new(McpToolRegistry::new()));
187    /// builder.mcp_registry(registry)
188    /// ```
189    pub fn mcp_registry(
190        mut self,
191        registry: Arc<tokio::sync::RwLock<crate::mcp::McpToolRegistry>>,
192    ) -> Self {
193        self.mcp_registry = Some(registry);
194        self
195    }
196
197    /// 设置 LSP 客户端注册表
198    ///
199    /// # Example
200    /// ```ignore
201    /// use std::sync::Arc;
202    /// use matrixcode_core::lsp::LspClientRegistry;
203    ///
204    /// let registry = Arc::new(LspClientRegistry::new());
205    /// // 启动 LSP 服务器
206    /// registry.register(&config, &project_root).await?;
207    /// builder.lsp_registry(registry)
208    /// ```
209    pub fn lsp_registry(mut self, registry: Arc<crate::lsp::LspClientRegistry>) -> Self {
210        self.lsp_registry = Some(registry);
211        self
212    }
213
214    /// 设置实时追加消息接收器
215    ///
216    /// 允许在 Agent 处理过程中接收新消息,实现实时追加功能。
217    ///
218    /// # Example
219    /// ```ignore
220    /// let (pending_tx, pending_rx) = tokio::sync::mpsc::channel::<String>(100);
221    /// builder.pending_input_rx(pending_rx)
222    /// ```
223    pub fn pending_input_rx(mut self, rx: tokio::sync::mpsc::Receiver<String>) -> Self {
224        self.pending_input_rx = Some(rx);
225        self
226    }
227}