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::constants::QUICK_ACTION_MAX_TOKENS;
8use crate::event::AgentEvent;
9use crate::prompt::PromptProfile;
10use crate::providers::Provider;
11use crate::skills::Skill;
12use crate::tools::Tool;
13use crate::tools::toolproxy::{ProxyToolExecutor, ProxyToolDef};
14
15use super::types::{Agent, AgentBuilder};
16
17impl AgentBuilder {
18    pub fn new(provider: Box<dyn Provider>) -> Self {
19        Self {
20            provider,
21            model_name: "unknown".to_string(),
22            tools: Vec::new(),
23            system_prompt: "You are a helpful AI coding assistant.".to_string(),
24            max_tokens: QUICK_ACTION_MAX_TOKENS,
25            think: false,
26            approve_mode: ApproveMode::Ask,
27            event_tx: None,
28            skills: Vec::new(),
29            profile: PromptProfile::Default,
30            project_overview: None,
31            memory_summary: None,
32            project_path: None,
33            proxy_tool_defs: Vec::new(),
34            proxy_executor: None,
35            mcp_registry: None,
36            pending_input_rx: None,
37        }
38    }
39
40    pub fn system_prompt(mut self, prompt: impl Into<String>) -> Self {
41        self.system_prompt = prompt.into();
42        self
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    pub fn think(mut self, enabled: bool) -> Self {
56        self.think = enabled;
57        self
58    }
59
60    pub fn approve_mode(mut self, mode: ApproveMode) -> Self {
61        self.approve_mode = mode;
62        self
63    }
64
65    pub fn tool(mut self, tool: Arc<dyn Tool>) -> Self {
66        self.tools.push(tool);
67        self
68    }
69
70    /// Add multiple tools
71    pub fn tools(mut self, tools: Vec<Box<dyn Tool>>) -> Self {
72        self.tools.extend(tools.into_iter().map(Arc::from));
73        self
74    }
75
76    /// Add multiple tools with provider support
77    pub fn tools_with_provider(mut self, tools: Vec<Box<dyn Tool>>) -> Self {
78        self.tools.extend(tools.into_iter().map(Arc::from));
79        self
80    }
81
82    /// Set external event sender for streaming events
83    pub fn event_tx(mut self, tx: tokio::sync::mpsc::Sender<AgentEvent>) -> Self {
84        self.event_tx = Some(tx);
85        self
86    }
87
88    /// Add skills
89    pub fn skills(mut self, skills: Vec<Skill>) -> Self {
90        self.skills = skills;
91        self
92    }
93
94    /// Set prompt profile
95    pub fn profile(mut self, profile: PromptProfile) -> Self {
96        self.profile = profile;
97        self
98    }
99
100    /// Set project overview
101    pub fn overview(mut self, overview: impl Into<String>) -> Self {
102        self.project_overview = Some(overview.into());
103        self
104    }
105
106    /// Set memory summary
107    pub fn memory(mut self, summary: impl Into<String>) -> Self {
108        self.memory_summary = Some(summary.into());
109        self
110    }
111
112    /// Set project path (for dynamic tool injection like CodeGraph)
113    pub fn project_path(mut self, path: PathBuf) -> Self {
114        self.project_path = Some(path);
115        self
116    }
117
118    /// 设置代理工具执行器
119    ///
120    /// # Example
121    /// ```ignore
122    /// use std::sync::Arc;
123    /// use serde_json::json;
124    /// use matrixcode_core::tools::toolproxy::{ProxyToolExecutor, ProxyToolDef};
125    ///
126    /// let executor = Arc::new(MyProxyExecutor);
127    /// let tool_def = ProxyToolDef::new("image_search", "搜索图片", json!({...}))
128    ///     .with_priority(true);
129    ///
130    /// builder.proxy_executor(executor, vec![tool_def])
131    /// ```
132    pub fn proxy_executor(mut self, executor: Arc<dyn ProxyToolExecutor>, tool_defs: Vec<ProxyToolDef>) -> Self {
133        self.proxy_executor = Some(executor);
134        self.proxy_tool_defs = tool_defs;
135        self
136    }
137
138    pub fn build(self) -> Agent {
139        Agent::new(self)
140    }
141
142    /// 设置 MCP 工具注册表
143    ///
144    /// # Example
145    /// ```ignore
146    /// use std::sync::Arc;
147    /// use matrixcode_core::mcp::McpToolRegistry;
148    ///
149    /// let registry = Arc::new(tokio::sync::RwLock::new(McpToolRegistry::new()));
150    /// builder.mcp_registry(registry)
151    /// ```
152    pub fn mcp_registry(mut self, registry: Arc<tokio::sync::RwLock<crate::mcp::McpToolRegistry>>) -> Self {
153        self.mcp_registry = Some(registry);
154        self
155    }
156
157    /// 设置实时追加消息接收器
158    ///
159    /// 允许在 Agent 处理过程中接收新消息,实现实时追加功能。
160    ///
161    /// # Example
162    /// ```ignore
163    /// let (pending_tx, pending_rx) = tokio::sync::mpsc::channel::<String>(100);
164    /// builder.pending_input_rx(pending_rx)
165    /// ```
166    pub fn pending_input_rx(mut self, rx: tokio::sync::mpsc::Receiver<String>) -> Self {
167        self.pending_input_rx = Some(rx);
168        self
169    }
170}