Tool

Trait Tool 

Source
pub trait Tool: Send + Sync {
    // Required methods
    fn descriptor(&self) -> ToolDescriptor;
    fn execute<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        args: Value,
        ctx: &'life1 ToolCallContext<'life2>,
    ) -> Pin<Box<dyn Future<Output = Result<ToolResult, ToolError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;

    // Provided methods
    fn validate_args(&self, args: &Value) -> Result<(), ToolError> { ... }
    fn execute_effect<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        args: Value,
        _ctx: &'life1 ToolCallContext<'life2>,
    ) -> Pin<Box<dyn Future<Output = Result<ToolExecutionEffect, ToolError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait { ... }
}
Expand description

Tool trait for implementing agent tools.

§Example

use tirea::contracts::runtime::tool_call::{Tool, ToolDescriptor, ToolExecutionEffect, ToolResult};
use tirea::contracts::runtime::state::AnyStateAction;
use tirea::contracts::ToolCallContext;
use tirea_state::State;

#[derive(State)]
struct MyToolState {
    pub count: i64,
}

enum MyToolAction {
    Increment,
}

struct CounterTool;

#[async_trait]
impl Tool for CounterTool {
    fn descriptor(&self) -> ToolDescriptor {
        ToolDescriptor::new("counter", "Counter", "Increment a counter")
    }

    async fn execute(
        &self,
        args: Value,
        ctx: &ToolCallContext<'_>,
    ) -> Result<ToolResult, ToolError> {
        let current = ctx
            .snapshot_of::<MyToolState>()
            .map(|state| state.count)
            .unwrap_or(0);

        Ok(ToolExecutionEffect::from(
            ToolResult::success("counter", json!({"count": current + 1}))
        ).with_action(
            AnyStateAction::new::<MyToolState>(MyToolAction::Increment)
        ))
    }
}

Required Methods§

Source

fn descriptor(&self) -> ToolDescriptor

Get the tool descriptor.

Source

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

Execute the tool.

§Arguments
  • args: Tool arguments as JSON value
  • ctx: Execution context for state access (framework extracts patch after execution). ctx.idempotency_key() is the current tool_call_id. Tools should use it as the idempotency key for side effects.
§Returns

Tool result or error

Provided Methods§

Source

fn validate_args(&self, args: &Value) -> Result<(), ToolError>

Validate tool arguments against the descriptor’s JSON Schema before execution.

The default implementation uses validate_against_schema with descriptor().parameters. Override to customise or skip validation.

Source

fn execute_effect<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, args: Value, _ctx: &'life1 ToolCallContext<'life2>, ) -> Pin<Box<dyn Future<Output = Result<ToolExecutionEffect, ToolError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Execute tool and return structured effects.

The default implementation delegates to Tool::execute and wraps the result without converting any context writes into state actions.

Tools that mutate persisted state should override this method and emit explicit typed actions via AnyStateAction::new....

Implementors§

Source§

impl<T: TypedTool> Tool for T