use crate::command::context::CommandContext; use crate::command::handler::{CommandHandler, CommandMetadata}; use crate::command::response::{CommandError, CommandResponse}; use crate::command::Command; use crate::skills::SkillRuntime; use async_trait::async_trait; use serde::{Deserialize, Serialize}; use std::sync::Arc; /// Skill 摘要信息(发送给前端) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SkillSummary { pub name: String, pub description: String, pub source: String, } pub struct ListSkillsCommandHandler { skills: Arc, } impl ListSkillsCommandHandler { pub fn new(skills: Arc) -> Self { Self { skills } } } #[async_trait] impl CommandHandler for ListSkillsCommandHandler { fn can_handle(&self, cmd: &Command) -> bool { matches!(cmd, Command::ListSkills) } fn metadata(&self) -> Option { Some(CommandMetadata { name: "list_skills", description: "列出所有技能", usage: "/list_skills", }) } async fn handle( &self, _cmd: Command, ctx: CommandContext, ) -> Result { let skill_list = self.skills.list_skills(); let summaries: Vec = skill_list .into_iter() .map(|s| SkillSummary { name: s.name, description: s.description, source: format!("{:?}", s.source).to_lowercase(), }) .collect(); let skills_json = serde_json::to_string(&summaries) .map_err(|e| CommandError::new("SERIALIZE_ERROR", e.to_string()))?; Ok(CommandResponse::success(ctx.request_id) .with_metadata("skills", &skills_json)) } }