Skip to main content

adk_tool/toolset/
mod.rs

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
9/// A simple toolset that wraps a static list of tools with optional filtering.
10pub struct BasicToolset {
11    name: String,
12    tools: Vec<Arc<dyn Tool>>,
13    predicate: Option<ToolPredicate>,
14}
15
16impl BasicToolset {
17    /// Create a new `BasicToolset` with the given name and tools.
18    pub fn new(name: impl Into<String>, tools: Vec<Arc<dyn Tool>>) -> Self {
19        Self { name: name.into(), tools, predicate: None }
20    }
21
22    /// Set a predicate to filter which tools are returned.
23    pub fn with_predicate(mut self, predicate: ToolPredicate) -> Self {
24        self.predicate = Some(predicate);
25        self
26    }
27}
28
29#[async_trait]
30impl Toolset for BasicToolset {
31    fn name(&self) -> &str {
32        &self.name
33    }
34
35    async fn tools(&self, _ctx: Arc<dyn ReadonlyContext>) -> Result<Vec<Arc<dyn Tool>>> {
36        if let Some(predicate) = &self.predicate {
37            Ok(self.tools.iter().filter(|tool| predicate(tool.as_ref())).cloned().collect())
38        } else {
39            Ok(self.tools.clone())
40        }
41    }
42}
43
44/// Creates a predicate that allows only tools with names in the provided list.
45pub fn string_predicate(allowed_tools: Vec<String>) -> ToolPredicate {
46    let allowed_set: std::collections::HashSet<String> = allowed_tools.into_iter().collect();
47    Box::new(move |tool: &dyn Tool| allowed_set.contains(tool.name()))
48}