pub trait AsyncTool<Ctx>: Send + Sync {
type Name: ToolName;
type Stage: ProgressStage;
// Required methods
fn name(&self) -> Self::Name;
fn display_name(&self) -> &'static str;
fn description(&self) -> &'static str;
fn input_schema(&self) -> Value;
fn execute(
&self,
ctx: &ToolContext<Ctx>,
input: Value,
) -> impl Future<Output = Result<ToolOutcome, Error>> + Send;
fn check_status(
&self,
ctx: &ToolContext<Ctx>,
operation_id: &str,
) -> impl Stream<Item = ToolStatus<Self::Stage>> + Send;
// Provided method
fn tier(&self) -> ToolTier { ... }
}Expand description
A tool that performs long-running async operations.
AsyncTools have two phases:
execute()- Start the operation (lightweight, returns quickly)check_status()- Stream progress until completion
The actual work should happen externally (background task, external service) and persist results to a durable store. The tool is just an orchestrator.
§Example
ⓘ
impl AsyncTool<MyCtx> for ExecutePixTransferTool {
type Name = PixToolName;
type Stage = PixTransferStage;
async fn execute(&self, ctx: &ToolContext<MyCtx>, input: Value) -> Result<ToolOutcome> {
let params = parse_input(&input)?;
let operation_id = ctx.app.pix_service.start_transfer(params).await?;
Ok(ToolOutcome::in_progress(
operation_id,
format!("PIX transfer of {} initiated", params.amount),
))
}
fn check_status(&self, ctx: &ToolContext<MyCtx>, operation_id: &str)
-> impl Stream<Item = ToolStatus<PixTransferStage>> + Send
{
async_stream::stream! {
loop {
let status = ctx.app.pix_service.get_status(operation_id).await;
match status {
PixStatus::Success { id } => {
yield ToolStatus::Completed(ToolResult::success(id));
break;
}
_ => yield ToolStatus::Progress { ... };
}
tokio::time::sleep(Duration::from_millis(500)).await;
}
}
}
}Required Associated Types§
Sourcetype Stage: ProgressStage
type Stage: ProgressStage
The type of progress stages for this tool.
Required Methods§
Sourcefn display_name(&self) -> &'static str
fn display_name(&self) -> &'static str
Human-readable display name for UI.
Sourcefn description(&self) -> &'static str
fn description(&self) -> &'static str
Human-readable description of what the tool does.
Sourcefn input_schema(&self) -> Value
fn input_schema(&self) -> Value
JSON schema for the tool’s input parameters.
Sourcefn execute(
&self,
ctx: &ToolContext<Ctx>,
input: Value,
) -> impl Future<Output = Result<ToolOutcome, Error>> + Send
fn execute( &self, ctx: &ToolContext<Ctx>, input: Value, ) -> impl Future<Output = Result<ToolOutcome, Error>> + Send
Execute the tool. Returns immediately with one of:
- Success/Failed: Operation completed synchronously
InProgress: Operation started, usecheck_status()to stream updates
§Errors
Returns an error if tool execution fails.
Sourcefn check_status(
&self,
ctx: &ToolContext<Ctx>,
operation_id: &str,
) -> impl Stream<Item = ToolStatus<Self::Stage>> + Send
fn check_status( &self, ctx: &ToolContext<Ctx>, operation_id: &str, ) -> impl Stream<Item = ToolStatus<Self::Stage>> + Send
Stream status updates for an in-progress operation. Must yield until Completed or Failed.
Provided Methods§
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".