1use crate::config::ToolsetConfig;
4
5pub const CORE_TOOLSET_GROUPS: &[&str] = &["runtime", "fs", "memory", "sessions", "misc"];
6
7pub fn toolset_for_tool(name: &str) -> &'static str {
8 match name {
9 "exec" => "runtime",
10 "Read" | "Write" | "Edit" => "fs",
11 "web_search" | "web_fetch" | "browser" => "web",
12 "memory_search" | "memory_get" | "session_search" | "brain_search" | "brain_query"
13 | "brain_put" | "brain_get" => "memory",
14 "list_models" | "doctor" => "sessions",
15 "message" => "messaging",
16 "skill_manager" => "skills",
17 "praefectus" => "desktop",
18 "mcp" | "create_tool" | "list_custom_tools" | "vibemania" => "advanced",
19 "generate_image" | "text_to_speech" | "speech_to_text" => "media",
20 _ => "misc",
21 }
22}
23
24pub fn expand_package(name: &str) -> Vec<&'static str> {
25 match name.trim().to_ascii_lowercase().as_str() {
26 "web" => vec!["web"],
27 "browser" => vec!["browser"],
28 "skills" => vec!["skills"],
29 "advanced" => vec!["advanced"],
30 "desktop" => vec!["desktop"],
31 "media" => vec!["media"],
32 "apollo-live" | "live" => vec!["web", "browser", "skills", "advanced", "desktop", "media"],
33 "core" | "default" => CORE_TOOLSET_GROUPS.to_vec(),
34 _ => vec![],
35 }
36}
37
38pub fn apply_package_manifest(toolsets: &mut ToolsetConfig, packages: &[String]) {
39 if packages.is_empty() {
40 return;
41 }
42 for g in CORE_TOOLSET_GROUPS {
43 let s = (*g).to_string();
44 if !toolsets.enabled.contains(&s) {
45 toolsets.enabled.push(s);
46 }
47 }
48 for pkg in packages {
49 for g in expand_package(pkg) {
50 let s = g.to_string();
51 if !toolsets.enabled.contains(&s) {
52 toolsets.enabled.push(s);
53 }
54 }
55 }
56}
57
58pub fn is_tool_enabled(name: &str, config: &ToolsetConfig) -> bool {
59 let toolset = toolset_for_tool(name);
60 let enabled = config.enabled.is_empty()
61 || config
62 .enabled
63 .iter()
64 .any(|entry| entry == name || entry == toolset);
65 let disabled = config
66 .disabled
67 .iter()
68 .any(|entry| entry == name || entry == toolset);
69 enabled && !disabled
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn toolset_filtering_allows_by_group() {
78 let cfg = ToolsetConfig {
79 enabled: vec!["memory".to_string()],
80 disabled: Vec::new(),
81 };
82 assert!(is_tool_enabled("memory_search", &cfg));
83 assert!(!is_tool_enabled("exec", &cfg));
84 }
85
86 #[test]
87 fn package_live_enables_web() {
88 let mut cfg = ToolsetConfig {
89 enabled: vec![],
90 disabled: Vec::new(),
91 };
92 apply_package_manifest(&mut cfg, &["live".to_string()]);
93 assert!(is_tool_enabled("web_search", &cfg));
94 assert!(cfg.enabled.iter().any(|e| e == "runtime"));
95 }
96}