1use adk_core::{ReadonlyContext, Result, Tool, ToolPredicate, Toolset};
2use async_trait::async_trait;
3use std::sync::Arc;
4
5mod compose;
6
7pub use compose::{FilteredToolset, MergedToolset, PrefixedToolset};
8
9pub struct BasicToolset {
11 name: String,
12 tools: Vec<Arc<dyn Tool>>,
13 predicate: Option<ToolPredicate>,
14}
15
16impl BasicToolset {
17 pub fn new(name: impl Into<String>, tools: Vec<Arc<dyn Tool>>) -> Self {
18 Self { name: name.into(), tools, predicate: None }
19 }
20
21 pub fn with_predicate(mut self, predicate: ToolPredicate) -> Self {
22 self.predicate = Some(predicate);
23 self
24 }
25}
26
27#[async_trait]
28impl Toolset for BasicToolset {
29 fn name(&self) -> &str {
30 &self.name
31 }
32
33 async fn tools(&self, _ctx: Arc<dyn ReadonlyContext>) -> Result<Vec<Arc<dyn Tool>>> {
34 if let Some(predicate) = &self.predicate {
35 Ok(self.tools.iter().filter(|tool| predicate(tool.as_ref())).cloned().collect())
36 } else {
37 Ok(self.tools.clone())
38 }
39 }
40}
41
42pub fn string_predicate(allowed_tools: Vec<String>) -> ToolPredicate {
44 let allowed_set: std::collections::HashSet<String> = allowed_tools.into_iter().collect();
45 Box::new(move |tool: &dyn Tool| allowed_set.contains(tool.name()))
46}