1use anyhow::Result;
2use futures::future::BoxFuture;
3use linkme::distributed_slice;
4use serde_json::Value;
5
6pub use reductool_proc_macro::aitool;
8
9pub use linkme as __linkme;
11
12pub type InvokeFuture = BoxFuture<'static, Result<Value>>;
13
14#[derive(Clone)]
15pub struct ToolDefinition {
16 pub name: &'static str,
17 pub description: &'static str,
18 pub json_schema: &'static str,
19 pub invoke: fn(Value) -> InvokeFuture,
20}
21
22#[distributed_slice]
23pub static ALL_TOOLS: [ToolDefinition] = [..];
24
25pub fn tools_to_schema() -> Value {
26 Value::Array(
27 ALL_TOOLS
28 .iter()
29 .map(|t| serde_json::from_str(t.json_schema).unwrap())
30 .collect(),
31 )
32}
33
34pub async fn dispatch_tool(name: &str, args: Value) -> Result<Value> {
35 (ALL_TOOLS
36 .iter()
37 .find(|t| t.name == name)
38 .ok_or_else(|| anyhow::anyhow!("Unknown tool: {name}"))?
39 .invoke)(args)
40 .await
41}