use async_trait::async_trait; use crate::domain::CapabilityPolicy; #[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 topic_id: Option, pub message_id: Option, pub message_seq: Option, /// 子代理标识,用于标注消息来源 pub subagent_description: Option, /// 当前嵌套深度(0 = 主 agent,1 = 子 agent,2 = 孙 agent...) pub nesting_depth: u32, /// 当前智能体自身的任务 ID(主 agent 为 None,子/孙 agent 为 Some(uuid)) pub task_id: Option, /// 父任务 ID(仅子/孙智能体有值,用于构建任务层级) pub parent_task_id: Option, /// 当前工具调用的 ID(由 agent_loop 在执行前注入,用于精确关联 TaskStarted 事件) pub tool_call_id: Option, /// 父智能体(主 agent 所选专家或上级子代理)的 capability 策略快照。 /// TaskTool 据此强制校验子代理加载(白/黑名单),与 spawn/resume 安全范式一致。 /// 以数据形式传递,避免 task 模块反向依赖 experts 模块。 pub parent_capability: 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 } }