agentic_evolve_mcp/tools/
evolve_pattern_store.rs1use std::sync::Arc;
4use tokio::sync::Mutex;
5
6use serde::Deserialize;
7use serde_json::{json, Value};
8
9use agentic_evolve_core::types::pattern::{
10 FunctionSignature, Language, ParamSignature, PatternVariable, Visibility,
11};
12
13use crate::session::SessionManager;
14use crate::types::{McpError, McpResult, ToolCallResult, ToolDefinition};
15
16#[derive(Debug, Deserialize)]
17struct StoreParams {
18 name: String,
19 domain: String,
20 language: String,
21 template: String,
22 #[serde(default)]
23 function_name: Option<String>,
24 #[serde(default)]
25 params: Vec<ParamInput>,
26 #[serde(default)]
27 return_type: Option<String>,
28 #[serde(default)]
29 is_async: bool,
30 #[serde(default)]
31 variables: Vec<VariableInput>,
32 #[serde(default = "default_confidence")]
33 confidence: f64,
34 #[serde(default)]
35 tags: Vec<String>,
36}
37
38#[derive(Debug, Deserialize)]
39struct ParamInput {
40 name: String,
41 #[serde(rename = "type", default = "default_type")]
42 param_type: String,
43 #[serde(default)]
44 is_optional: bool,
45}
46
47#[derive(Debug, Deserialize)]
48struct VariableInput {
49 name: String,
50 #[serde(rename = "type", default = "default_type")]
51 var_type: String,
52 #[serde(default)]
53 pattern: Option<String>,
54 #[serde(default)]
55 default: Option<String>,
56}
57
58fn default_confidence() -> f64 {
59 0.8
60}
61
62fn default_type() -> String {
63 "Any".to_string()
64}
65
66pub fn definition() -> ToolDefinition {
68 ToolDefinition {
69 name: "evolve_pattern_store".to_string(),
70 description: Some("Store a new pattern in the library".to_string()),
71 input_schema: json!({
72 "type": "object",
73 "properties": {
74 "name": {
75 "type": "string",
76 "description": "Human-readable pattern name"
77 },
78 "domain": {
79 "type": "string",
80 "description": "Domain or category (e.g. 'web', 'cli', 'data')"
81 },
82 "language": {
83 "type": "string",
84 "description": "Programming language (rust, python, typescript, etc.)"
85 },
86 "template": {
87 "type": "string",
88 "description": "The code template with {{variable}} placeholders"
89 },
90 "function_name": {
91 "type": "string",
92 "description": "Function name for the pattern signature"
93 },
94 "params": {
95 "type": "array",
96 "items": {
97 "type": "object",
98 "properties": {
99 "name": { "type": "string" },
100 "type": { "type": "string" },
101 "is_optional": { "type": "boolean" }
102 },
103 "required": ["name"]
104 },
105 "description": "Function parameters"
106 },
107 "return_type": {
108 "type": "string",
109 "description": "Return type of the function"
110 },
111 "is_async": {
112 "type": "boolean",
113 "description": "Whether the function is async"
114 },
115 "variables": {
116 "type": "array",
117 "items": {
118 "type": "object",
119 "properties": {
120 "name": { "type": "string" },
121 "type": { "type": "string" },
122 "pattern": { "type": "string" },
123 "default": { "type": "string" }
124 },
125 "required": ["name"]
126 },
127 "description": "Template variable definitions"
128 },
129 "confidence": {
130 "type": "number",
131 "minimum": 0.0,
132 "maximum": 1.0,
133 "default": 0.8,
134 "description": "Initial confidence level (0.0 to 1.0)"
135 },
136 "tags": {
137 "type": "array",
138 "items": { "type": "string" },
139 "description": "Tags for categorization"
140 }
141 },
142 "required": ["name", "domain", "language", "template"]
143 }),
144 }
145}
146
147pub async fn execute(
149 args: Value,
150 session: &Arc<Mutex<SessionManager>>,
151) -> McpResult<ToolCallResult> {
152 let params: StoreParams =
153 serde_json::from_value(args).map_err(|e| McpError::InvalidParams(e.to_string()))?;
154
155 if !(0.0..=1.0).contains(¶ms.confidence) {
156 return Err(McpError::InvalidParams(format!(
157 "confidence must be between 0.0 and 1.0, got {}",
158 params.confidence
159 )));
160 }
161
162 let language = Language::from_name(¶ms.language);
163 let fn_name = params.function_name.unwrap_or_else(|| params.name.clone());
164
165 let sig_params: Vec<ParamSignature> = params
166 .params
167 .into_iter()
168 .map(|p| ParamSignature {
169 name: p.name,
170 param_type: p.param_type,
171 is_optional: p.is_optional,
172 })
173 .collect();
174
175 let signature = FunctionSignature {
176 name: fn_name,
177 params: sig_params,
178 return_type: params.return_type,
179 language: language.clone(),
180 is_async: params.is_async,
181 visibility: Visibility::Public,
182 };
183
184 let variables: Vec<PatternVariable> = params
185 .variables
186 .into_iter()
187 .map(|v| PatternVariable {
188 name: v.name,
189 var_type: v.var_type,
190 pattern: v.pattern,
191 default: v.default,
192 })
193 .collect();
194
195 let mut session = session.lock().await;
196 let pattern = session
197 .store_pattern(
198 ¶ms.name,
199 ¶ms.domain,
200 language,
201 signature,
202 ¶ms.template,
203 variables,
204 params.confidence,
205 params.tags,
206 )
207 .map_err(|e| McpError::AgenticEvolve(e.to_string()))?;
208
209 Ok(ToolCallResult::json(&json!({
210 "pattern_id": pattern.id.as_str(),
211 "name": pattern.name,
212 "domain": pattern.domain,
213 "language": pattern.language.as_str(),
214 "version": pattern.version,
215 "confidence": pattern.confidence
216 })))
217}