feat(skill-execution): implement execute_skill tool with full execution chain
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- Add ExecuteSkillTool for LLM to call skills during conversation - Implement SkillExecutor trait in Kernel for skill execution - Update AgentLoop to support tool execution with skill_executor - Add default skills_dir configuration in KernelConfig - Connect frontend skillMarketStore to backend skill_list command - Update technical documentation with Skill system architecture Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
//! Tool system for agent capabilities
|
||||
|
||||
use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
use serde_json::Value;
|
||||
use zclaw_types::{AgentId, Result};
|
||||
@@ -22,16 +23,54 @@ pub trait Tool: Send + Sync {
|
||||
async fn execute(&self, input: Value, context: &ToolContext) -> Result<Value>;
|
||||
}
|
||||
|
||||
/// Skill executor trait for runtime skill execution
|
||||
/// This allows tools to execute skills without direct dependency on zclaw-skills
|
||||
#[async_trait]
|
||||
pub trait SkillExecutor: Send + Sync {
|
||||
/// Execute a skill by ID
|
||||
async fn execute_skill(
|
||||
&self,
|
||||
skill_id: &str,
|
||||
agent_id: &str,
|
||||
session_id: &str,
|
||||
input: Value,
|
||||
) -> Result<Value>;
|
||||
}
|
||||
|
||||
/// Context provided to tool execution
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ToolContext {
|
||||
pub agent_id: AgentId,
|
||||
pub working_directory: Option<String>,
|
||||
pub session_id: Option<String>,
|
||||
pub skill_executor: Option<Arc<dyn SkillExecutor>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ToolContext {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("ToolContext")
|
||||
.field("agent_id", &self.agent_id)
|
||||
.field("working_directory", &self.working_directory)
|
||||
.field("session_id", &self.session_id)
|
||||
.field("skill_executor", &self.skill_executor.as_ref().map(|_| "SkillExecutor"))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for ToolContext {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
agent_id: self.agent_id.clone(),
|
||||
working_directory: self.working_directory.clone(),
|
||||
session_id: self.session_id.clone(),
|
||||
skill_executor: self.skill_executor.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tool registry for managing available tools
|
||||
#[derive(Clone)]
|
||||
pub struct ToolRegistry {
|
||||
tools: Vec<Box<dyn Tool>>,
|
||||
tools: Vec<Arc<dyn Tool>>,
|
||||
}
|
||||
|
||||
impl ToolRegistry {
|
||||
@@ -40,11 +79,11 @@ impl ToolRegistry {
|
||||
}
|
||||
|
||||
pub fn register(&mut self, tool: Box<dyn Tool>) {
|
||||
self.tools.push(tool);
|
||||
self.tools.push(Arc::from(tool));
|
||||
}
|
||||
|
||||
pub fn get(&self, name: &str) -> Option<&dyn Tool> {
|
||||
self.tools.iter().find(|t| t.name() == name).map(|t| t.as_ref())
|
||||
pub fn get(&self, name: &str) -> Option<Arc<dyn Tool>> {
|
||||
self.tools.iter().find(|t| t.name() == name).cloned()
|
||||
}
|
||||
|
||||
pub fn list(&self) -> Vec<&dyn Tool> {
|
||||
|
||||
Reference in New Issue
Block a user