Skip to main content

ToolPolicy

Trait ToolPolicy 

Source
pub trait ToolPolicy: Send + Sync {
    // Required method
    fn evaluate_approval<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        tool_name: &'life1 str,
        args: &'life2 Value,
    ) -> Pin<Box<dyn Future<Output = Option<ApprovalRequest>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;

    // Provided methods
    fn before_call(
        &self,
        tool_name: &str,
        args: &Value,
        ctx: &ToolContext,
    ) -> AgentResult<()> { ... }
    fn after_call(
        &self,
        tool_name: &str,
        args: &Value,
        result: &ToolOutput,
        ctx: &ToolContext,
    ) -> AgentResult<()> { ... }
}
Expand description

Policy-based control over tool execution.

Implement this trait to customise how tools are approved, monitored, and validated during an agent run. The pipeline calls each hook at a specific point in the tool lifecycle:

evaluate_approval  →  before_call  →  (tool executes)  →  after_call

§Example: auto-approve read-only tools

struct ReadOnlyPolicy;

#[async_trait]
impl ToolPolicy for ReadOnlyPolicy {
    async fn evaluate_approval(&self, tool_name: &str, _args: &Value) -> Option<ApprovalRequest> {
        if tool_name == "read_file" || tool_name == "search" {
            None  // auto-approve — no prompt for user
        } else {
            Some(ApprovalRequest { message: format!("Allow {}?", tool_name) })
        }
    }
}

All hooks have default no-op implementations, so you only need to override the ones you care about.

Required Methods§

Source

fn evaluate_approval<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, tool_name: &'life1 str, args: &'life2 Value, ) -> Pin<Box<dyn Future<Output = Option<ApprovalRequest>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Called before every tool call.

Return None to auto-approve (skip the approval handler entirely). Return Some(ApprovalRequest) to defer to the configured ApprovalHandler.

This is the primary hook for implementing permission guards — for example, auto-approving read-only operations while prompting for destructive ones.

Provided Methods§

Source

fn before_call( &self, tool_name: &str, args: &Value, ctx: &ToolContext, ) -> AgentResult<()>

Called immediately before a tool executes, after approval has been granted (or auto-approved).

Use this for:

  • Input validation (reject malformed arguments before the tool runs).
  • Auditing / logging the raw call.
  • Rate-limiting or quota enforcement.

Return an Err to cancel the tool call before execution. The error message is surfaced to the LLM so it can correct its approach.

Source

fn after_call( &self, tool_name: &str, args: &Value, result: &ToolOutput, ctx: &ToolContext, ) -> AgentResult<()>

Called immediately after a tool executes, before the result is returned to the LLM.

Use this for:

  • Output scrubbing / redaction (strip secrets from tool results).
  • Truncation or formatting of large outputs.
  • Recording metrics or audit trails.

The result is the raw ToolOutput produced by the tool. You can inspect it but not modify it through this hook — if you need to transform the output, use a middleware instead.

Return an Err to reject the result. The error message is surfaced to the LLM.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§