Skip to main content

ToolExecutor

Trait ToolExecutor 

Source
pub trait ToolExecutor: Send + Sync {
    // Required methods
    fn execute<'life0, 'life1, 'async_trait>(
        &'life0 self,
        call: &'life1 ToolCall,
    ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn list_tools(&self) -> Vec<ToolSchema>;

    // Provided methods
    fn execute_with_context<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        call: &'life1 ToolCall,
        _ctx: ToolExecutionContext<'life2>,
    ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait { ... }
    fn tool_mutability(&self, tool_name: &str) -> ToolMutability { ... }
    fn call_mutability(&self, call: &ToolCall) -> ToolMutability { ... }
    fn tool_concurrency_safe(&self, tool_name: &str) -> bool { ... }
    fn call_concurrency_safe(&self, call: &ToolCall) -> bool { ... }
}
Expand description

Trait for tool execution backends

This trait defines the interface for executing tool calls and listing available tools. Implementations can wrap tool registries, provide mock tools for testing, or implement custom execution logic.

§Example

use bamboo_agent::agent::core::tools::executor::ToolExecutor;

struct MyExecutor {
    tools: HashMap<String, Box<dyn Tool>>,
}

#[async_trait]
impl ToolExecutor for MyExecutor {
    async fn execute(&self, call: &ToolCall) -> Result<ToolResult> {
        let tool = self.tools.get(&call.function.name)
            .ok_or_else(|| ToolError::NotFound(call.function.name.clone()))?;
        let args = parse_tool_args(&call.function.arguments)?;
        tool.execute(args).await
    }

    fn list_tools(&self) -> Vec<ToolSchema> {
        self.tools.values().map(|t| t.schema()).collect()
    }
}

Required Methods§

Source

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, call: &'life1 ToolCall, ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Executes a tool call

§Arguments
  • call - The tool call to execute (contains tool name and arguments)
§Returns

The tool execution result or an error

Source

fn list_tools(&self) -> Vec<ToolSchema>

Lists all available tools and their schemas

Returns schemas for all tools that can be executed via this executor

Provided Methods§

Source

fn execute_with_context<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, call: &'life1 ToolCall, _ctx: ToolExecutionContext<'life2>, ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Executes a tool call with streaming-capable context.

Default implementation falls back to execute() for executors that don’t support streaming (e.g. remote MCP tools).

Source

fn tool_mutability(&self, tool_name: &str) -> ToolMutability

Returns mutability metadata for a tool name when available. Executors that can inspect concrete tools should override this.

Source

fn call_mutability(&self, call: &ToolCall) -> ToolMutability

Returns mutability metadata for a specific tool call when available. Defaults to name-based classification.

Source

fn tool_concurrency_safe(&self, tool_name: &str) -> bool

Returns whether a tool can safely execute in parallel with other read-only tools. Executors that can inspect concrete tools should override this. Fallback keeps current behavior for known read-only tools.

Source

fn call_concurrency_safe(&self, call: &ToolCall) -> bool

Returns whether a specific tool call can safely run in parallel. Defaults to the tool-name level classification.

Implementations on Foreign Types§

Source§

impl ToolExecutor for BuiltinToolExecutor

Source§

fn execute<'life0, 'life1, 'async_trait>( &'life0 self, call: &'life1 ToolCall, ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, BuiltinToolExecutor: 'async_trait,

Source§

fn execute_with_context<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, call: &'life1 ToolCall, ctx: ToolExecutionContext<'life2>, ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, BuiltinToolExecutor: 'async_trait,

Source§

fn list_tools(&self) -> Vec<ToolSchema>

Source§

fn tool_mutability(&self, tool_name: &str) -> ToolMutability

Source§

fn call_mutability(&self, call: &ToolCall) -> ToolMutability

Source§

fn tool_concurrency_safe(&self, tool_name: &str) -> bool

Source§

fn call_concurrency_safe(&self, call: &ToolCall) -> bool

Implementors§