codetether_agent/search/
dispatch.rs1use anyhow::Result;
6use serde_json::{Value, json};
7
8use crate::tool::{Tool, ToolResult, file, memory, search, webfetch, websearch};
9
10use super::types::{Backend, BackendChoice};
11
12pub async fn run_choice(choice: &BackendChoice, query: &str) -> Result<ToolResult> {
17 let args = enrich_args(choice, query);
18 match choice.backend {
19 Backend::Grep => search::GrepTool::new().execute(args).await,
20 Backend::Glob => file::GlobTool::new().execute(args).await,
21 Backend::Websearch => websearch::WebSearchTool::new().execute(args).await,
22 Backend::Webfetch => webfetch::WebFetchTool::new().execute(args).await,
23 Backend::Memory => memory::MemoryTool::new().execute(args).await,
24 Backend::Rlm => Ok(ToolResult::error(
25 "rlm backend requires a provider; wire RlmTool before requesting semantic search",
26 )),
27 }
28}
29
30fn enrich_args(choice: &BackendChoice, query: &str) -> Value {
31 let mut args = choice.args.clone();
32 if !args.is_object() {
33 args = Value::Object(Default::default());
34 }
35 let obj = args.as_object_mut().expect("args normalized above");
36 match choice.backend {
37 Backend::Grep if obj.get("pattern").is_none() => {
38 obj.insert("pattern".into(), json!(query));
39 }
40 Backend::Glob if obj.get("pattern").is_none() => {
41 obj.insert("pattern".into(), json!(query));
42 }
43 Backend::Websearch if obj.get("query").is_none() => {
44 obj.insert("query".into(), json!(query));
45 }
46 Backend::Memory if obj.get("query").is_none() => {
47 obj.insert("action".into(), json!("search"));
48 obj.insert("query".into(), json!(query));
49 }
50 _ => {}
51 }
52 args
53}