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>> + 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>> + Send
fn execute( &self, ctx: &ToolContext<Ctx>, input: Value, ) -> impl Future<Output = Result<ToolOutcome>> + 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", so this trait is not object safe.