//! Execute skill tool use async_trait::async_trait; use serde_json::{json, Value}; use zclaw_types::{Result, ZclawError}; use crate::tool::{Tool, ToolContext}; pub struct ExecuteSkillTool; impl ExecuteSkillTool { pub fn new() -> Self { Self } } #[async_trait] impl Tool for ExecuteSkillTool { fn name(&self) -> &str { "execute_skill" } fn description(&self) -> &str { "Execute a skill by its ID. Skills are predefined capabilities that can be invoked with structured input." } fn input_schema(&self) -> Value { json!({ "type": "object", "properties": { "skill_id": { "type": "string", "description": "The ID of the skill to execute" }, "input": { "type": "object", "description": "The input parameters for the skill", "additionalProperties": true } }, "required": ["skill_id"] }) } async fn execute(&self, input: Value, context: &ToolContext) -> Result { let skill_id = input["skill_id"].as_str() .ok_or_else(|| ZclawError::InvalidInput("Missing 'skill_id' parameter".into()))?; let skill_input = input.get("input").cloned().unwrap_or(json!({})); // Get skill executor from context let executor = context.skill_executor.as_ref() .ok_or_else(|| ZclawError::ToolError("Skill executor not available".into()))?; // Get session_id from context or use empty string let session_id = context.session_id.as_deref().unwrap_or(""); // Execute the skill executor.execute_skill( skill_id, &context.agent_id.to_string(), session_id, skill_input, ).await } } impl Default for ExecuteSkillTool { fn default() -> Self { Self::new() } }