synwire_core/runnables/
as_tool.rs1use crate::BoxFuture;
4use crate::error::SynwireError;
5use crate::runnables::config::RunnableConfig;
6use crate::runnables::core::RunnableCore;
7use crate::tools::ToolSchema;
8use serde_json::Value;
9
10pub struct RunnableTool {
15 inner: Box<dyn RunnableCore>,
16 schema: ToolSchema,
17}
18
19impl RunnableTool {
20 pub fn new(inner: Box<dyn RunnableCore>, schema: ToolSchema) -> Self {
22 Self { inner, schema }
23 }
24
25 pub const fn schema(&self) -> &ToolSchema {
27 &self.schema
28 }
29}
30
31impl RunnableCore for RunnableTool {
32 fn invoke<'a>(
33 &'a self,
34 input: Value,
35 config: Option<&'a RunnableConfig>,
36 ) -> BoxFuture<'a, Result<Value, SynwireError>> {
37 self.inner.invoke(input, config)
38 }
39
40 fn name(&self) -> &str {
41 &self.schema.name
42 }
43}
44
45#[cfg(test)]
46#[allow(clippy::unwrap_used)]
47mod tests {
48 use super::*;
49 use crate::runnables::passthrough::RunnablePassthrough;
50
51 #[tokio::test]
52 async fn test_runnable_tool_delegates() {
53 let schema = ToolSchema {
54 name: "my_tool".into(),
55 description: "A test tool".into(),
56 parameters: serde_json::json!({"type": "object"}),
57 };
58 let tool = RunnableTool::new(Box::new(RunnablePassthrough), schema);
59
60 assert_eq!(tool.name(), "my_tool");
61 assert_eq!(tool.schema().description, "A test tool");
62
63 let result = tool.invoke(Value::from(42), None).await.unwrap();
64 assert_eq!(result, Value::from(42));
65 }
66}