use async_trait::async_trait; #[derive(Debug, Clone)] pub struct ToolResult { pub success: bool, pub output: String, pub error: Option, } #[derive(Debug, Clone, Default)] pub struct ToolContext { pub channel_name: Option, pub sender_id: Option, pub chat_id: Option, pub session_id: Option, pub message_id: Option, pub message_seq: Option, } #[async_trait] pub trait Tool: Send + Sync + 'static { fn name(&self) -> &str; fn description(&self) -> &str; fn parameters_schema(&self) -> serde_json::Value; async fn execute(&self, args: serde_json::Value) -> anyhow::Result; async fn execute_with_context( &self, _context: &ToolContext, args: serde_json::Value, ) -> anyhow::Result { self.execute(args).await } /// Whether this tool is side-effect free and safe to parallelize. fn read_only(&self) -> bool { false } /// Whether this tool can run alongside other concurrency-safe tools. fn concurrency_safe(&self) -> bool { self.read_only() && !self.exclusive() } /// Whether this tool should run alone even if concurrency is enabled. fn exclusive(&self) -> bool { false } }