1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct Skill {
6 pub id: String,
7 pub name: String,
8 pub description: String,
9 pub triggers: Vec<String>,
10 pub instructions: String,
11 pub capabilities: Vec<String>,
12 pub resources: Vec<SkillResource>,
13 pub path: PathBuf,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct SkillResource {
18 pub name: String,
19 pub path: PathBuf,
20 pub resource_type: ResourceType,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
24pub enum ResourceType {
25 Script,
26 Reference,
27 Asset,
28 Config,
29}
30
31impl Skill {
32 pub fn new(
33 id: String,
34 name: String,
35 description: String,
36 instructions: String,
37 path: PathBuf,
38 ) -> Self {
39 Self {
40 id,
41 name,
42 description,
43 triggers: Vec::new(),
44 instructions,
45 capabilities: Vec::new(),
46 resources: Vec::new(),
47 path,
48 }
49 }
50
51 pub fn with_triggers(mut self, triggers: Vec<String>) -> Self {
52 self.triggers = triggers;
53 self
54 }
55
56 pub fn with_capabilities(mut self, capabilities: Vec<String>) -> Self {
57 self.capabilities = capabilities;
58 self
59 }
60
61 pub fn with_resources(mut self, resources: Vec<SkillResource>) -> Self {
62 self.resources = resources;
63 self
64 }
65
66 pub fn search_text(&self) -> String {
67 let mut parts = vec![
68 self.name.clone(),
69 self.description.clone(),
70 self.instructions.clone(),
71 ];
72 parts.extend(self.triggers.clone());
73 parts.extend(self.capabilities.clone());
74 parts.join(" ")
75 }
76}
77
78#[derive(Debug, Clone, Serialize, Deserialize)]
79pub struct DiscoveredSkill {
80 pub skill: Skill,
81 pub score: f64,
82 pub match_type: MatchType,
83}
84
85#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
86pub enum MatchType {
87 Semantic,
88 Keyword,
89 Hybrid,
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct AgentContext {
94 pub current_dir: PathBuf,
95 pub files: Vec<PathBuf>,
96 pub env_vars: std::collections::HashMap<String, String>,
97 pub history: Vec<String>,
98}
99
100impl Default for AgentContext {
101 fn default() -> Self {
102 Self {
103 current_dir: std::env::current_dir().unwrap_or_default(),
104 files: Vec::new(),
105 env_vars: std::env::vars().collect(),
106 history: Vec::new(),
107 }
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize)]
112pub struct SkillQuery {
113 pub task: String,
114 pub context: AgentContext,
115 pub limit: usize,
116 pub threshold: f64,
117}
118
119impl Default for SkillQuery {
120 fn default() -> Self {
121 Self {
122 task: String::new(),
123 context: AgentContext::default(),
124 limit: 5,
125 threshold: 0.1,
126 }
127 }
128}
129
130#[derive(Debug, Clone, Serialize, Deserialize)]
131pub struct SkillResult {
132 pub skill_id: String,
133 pub success: bool,
134 pub output: String,
135 pub error: Option<String>,
136 pub execution_time_ms: u64,
137}
138
139#[derive(Debug, Clone, Serialize, Deserialize)]
140pub struct Config {
141 pub skills_dir: PathBuf,
142 pub embedding_model: String,
143 pub ollama_url: String,
144 pub vector_dim: usize,
145 pub db_path: PathBuf,
146}
147
148impl Default for Config {
149 fn default() -> Self {
150 Self {
151 skills_dir: PathBuf::from("./skills"),
152 embedding_model: "nomic-embed-text".to_string(),
153 ollama_url: "http://localhost:11434".to_string(),
154 vector_dim: 768,
155 db_path: PathBuf::from("./skill-agent.db"),
156 }
157 }
158}