Skip to main content

evo_common/
skill.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct SkillManifest {
6    pub name: String,
7    pub version: String,
8    pub description: String,
9    pub capabilities: Vec<String>,
10    pub inputs: Vec<SkillIO>,
11    pub outputs: Vec<SkillIO>,
12    #[serde(default)]
13    pub dependencies: Vec<String>,
14    #[serde(default)]
15    pub has_code: bool,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct SkillIO {
20    pub name: String,
21    pub r#type: String,
22    #[serde(default)]
23    pub required: bool,
24    pub description: Option<String>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct SkillConfig {
29    pub endpoints: Vec<SkillEndpoint>,
30    #[serde(default)]
31    pub auth_ref: Option<String>,
32    #[serde(default)]
33    pub extra: HashMap<String, serde_json::Value>,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize)]
37pub struct SkillEndpoint {
38    pub name: String,
39    pub url: String,
40    pub method: HttpMethod,
41    #[serde(default)]
42    pub headers: HashMap<String, String>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
46#[serde(rename_all = "UPPERCASE")]
47pub enum HttpMethod {
48    Get,
49    Post,
50    Put,
51    Delete,
52    Patch,
53}
54
55impl SkillManifest {
56    pub fn from_toml(content: &str) -> Result<Self, toml::de::Error> {
57        toml::from_str(content)
58    }
59}
60
61impl SkillConfig {
62    pub fn from_toml(content: &str) -> Result<Self, toml::de::Error> {
63        toml::from_str(content)
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn parse_skill_manifest() {
73        let toml_str = r#"
74name = "web-search"
75version = "0.1.0"
76description = "Search the web for information"
77capabilities = ["search", "summarize"]
78has_code = false
79dependencies = []
80
81[[inputs]]
82name = "query"
83type = "string"
84required = true
85description = "Search query"
86
87[[outputs]]
88name = "results"
89type = "array"
90required = true
91description = "Search results"
92"#;
93        let manifest = SkillManifest::from_toml(toml_str).unwrap();
94        assert_eq!(manifest.name, "web-search");
95        assert_eq!(manifest.capabilities.len(), 2);
96        assert!(manifest.inputs[0].required);
97    }
98
99    #[test]
100    fn parse_skill_config() {
101        let toml_str = r#"
102auth_ref = "SEARCH_API_KEY"
103
104[[endpoints]]
105name = "search"
106url = "https://api.search.com/v1/search"
107method = "GET"
108
109[endpoints.headers]
110Accept = "application/json"
111"#;
112        let config = SkillConfig::from_toml(toml_str).unwrap();
113        assert_eq!(config.endpoints[0].method, HttpMethod::Get);
114        assert_eq!(config.auth_ref.unwrap(), "SEARCH_API_KEY");
115    }
116}