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