Skip to main content

tiny_loop/
tool.rs

1mod args;
2mod closure;
3mod executor;
4
5use crate::types::{ToolCall, ToolResult};
6use async_trait::async_trait;
7use futures::future::join_all;
8
9pub use args::*;
10pub(crate) use closure::*;
11pub use executor::*;
12pub use tiny_loop_macros::tool;
13
14/// A trait for tools that can be called with JSON string arguments.
15///
16/// Users must provide the `call` method. The framework auto-provides `call_batch` to run tools in parallel.
17/// At runtime, different tool executors may call `call` or `call_batch` in different ways.
18/// Users can override `call_batch` to customize this behavior.
19#[async_trait]
20pub trait Tool {
21    /// Calls the tool with JSON arguments and returns the result.
22    async fn call(&self, args: String) -> String;
23
24    /// Calls the tool with timing measurement
25    async fn call_timed(&self, call: ToolCall) -> ToolResult {
26        let start = std::time::SystemTime::now();
27        let content = self.call(call.function.arguments).await;
28        let elapsed = start.elapsed().unwrap();
29        ToolResult {
30            tool_message: crate::types::ToolMessage {
31                tool_call_id: call.id,
32                content,
33            },
34            timestamp: start + elapsed,
35            elapsed,
36        }
37    }
38
39    /// Executes multiple tool calls in parallel. Override to customize execution behavior.
40    async fn call_batch(&self, args: Vec<ToolCall>) -> Vec<ToolResult> {
41        join_all(
42            args.into_iter()
43                .map(|call| self.call_timed(call))
44                .collect::<Vec<_>>(),
45        )
46        .await
47    }
48}