| 75 | } |
| 76 | |
| 77 | pub fn select_tools_for_prompt(tools: &[ToolDefinition], prompt: &str) -> Vec<ToolDefinition> { |
| 78 | if tools.is_empty() { |
| 79 | return Vec::new(); |
| 80 | } |
| 81 | |
| 82 | let prompt_lower = prompt.to_lowercase(); |
| 83 | let wants_web = contains_any(&prompt_lower, WEB_TERMS); |
| 84 | let wants_fetch = contains_any(&prompt_lower, FETCH_TERMS); |
| 85 | let wants_git = contains_any(&prompt_lower, GIT_TERMS); |
| 86 | let wants_batch = contains_any(&prompt_lower, BATCH_TERMS); |
| 87 | let wants_program = contains_any(&prompt_lower, PROGRAM_TERMS); |
| 88 | let wants_mcp = contains_any(&prompt_lower, MCP_TERMS); |
| 89 | |
| 90 | let core: HashSet<&str> = CORE_TOOLS.iter().copied().collect(); |
| 91 | let mut selected = Vec::new(); |
| 92 | |
| 93 | for tool in tools { |
| 94 | let name = tool.name.as_str(); |
| 95 | let name_lower = name.to_lowercase(); |
| 96 | |
| 97 | let include = core.contains(name) |
| 98 | || (name == "web_search" && wants_web) |
| 99 | || (name == "web_fetch" && (wants_web || wants_fetch)) |
| 100 | || (name == "git" && wants_git) |
| 101 | || (name == "batch" && wants_batch) |
| 102 | || (name == "program" && wants_program) |
| 103 | || should_include_mcp_tool(name, &name_lower, &prompt_lower, wants_mcp) |
| 104 | || (!is_known_special_tool(name) && !name.starts_with("mcp__")); |
| 105 | |
| 106 | if include { |
| 107 | selected.push(tool.clone()); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | selected |
| 112 | } |
| 113 | |
| 114 | fn should_include_mcp_tool( |
| 115 | name: &str, |