MCPcopy Create free account
hub / github.com/AI45Lab/Code / execute

Method execute

core/src/tools/builtin/web_search.rs:190–402  ·  view source on GitHub ↗
(&self, args: &serde_json::Value, ctx: &ToolContext)

Source from the content-addressed store, hash-verified

188 }
189
190 async fn execute(&self, args: &serde_json::Value, ctx: &ToolContext) -> Result<ToolOutput> {
191 // Validate: return error on unknown fields to catch misconfiguration like `engine` vs `engines`
192 if let Some(obj) = args.as_object() {
193 let valid_fields = ["query", "engines", "limit", "timeout", "proxy", "format"];
194 for key in obj.keys() {
195 if !valid_fields.contains(&key.as_str()) {
196 return Ok(ToolOutput::error(format!(
197 "web_search: unknown parameter '{}' - did you mean 'engines'? \
198 Use 'engines' (plural) as the field name, not 'engine' (singular)",
199 key
200 )));
201 }
202 }
203 }
204
205 let query_str = match args.get("query").and_then(|v| v.as_str()) {
206 Some(q) => q,
207 None => return Ok(ToolOutput::error("query parameter is required")),
208 };
209
210 if query_str.trim().is_empty() {
211 return Ok(ToolOutput::error("query must not be empty"));
212 }
213
214 // Get configuration from context or use defaults
215 let config = ctx.search_config.as_ref();
216 let headless_config = config.and_then(|c| c.headless.as_ref());
217
218 let default_timeout = config.map(|c| c.timeout).unwrap_or(10);
219 let default_engines: Vec<&str> = if let Some(cfg) = config {
220 // Build default engines list from enabled engines in config
221 cfg.engines
222 .iter()
223 .filter(|(_, engine_cfg)| engine_cfg.enabled)
224 .map(|(name, _)| name.as_str())
225 .collect()
226 } else {
227 vec!["ddg", "wiki"]
228 };
229
230 let engines: Vec<&str> = args
231 .get("engines")
232 .and_then(|v| {
233 if let Some(arr) = v.as_array() {
234 Some(arr.iter().filter_map(|v| v.as_str()).collect::<Vec<_>>())
235 } else {
236 // Handle comma-separated string like "baidu,ddg" or single engine like "baidu"
237 v.as_str().map(|s| {
238 s.split(',')
239 .map(str::trim)
240 .filter(|s| !s.is_empty())
241 .collect()
242 })
243 }
244 })
245 .unwrap_or_else(|| default_engines.clone());
246
247 let limit = args

Calls 11

add_http_engineFunction · 0.85
add_headless_engineFunction · 0.85
parse_proxy_urlFunction · 0.85
containsMethod · 0.80
get_or_init_poolMethod · 0.80
set_timeoutMethod · 0.80
as_strMethod · 0.45
getMethod · 0.45
is_emptyMethod · 0.45
cloneMethod · 0.45
searchMethod · 0.45