bamboo_server/handlers/skill/
types.rs1use bamboo_engine::SkillDefinition;
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Serialize)]
6pub(super) struct SkillListResponse {
7 pub(super) skills: Vec<SkillDefinition>,
8 pub(super) total: usize,
9}
10
11#[derive(Deserialize)]
12pub struct ListSkillsQuery {
13 pub(super) search: Option<String>,
14 pub(super) refresh: Option<bool>,
15 pub(super) include_disabled: Option<bool>,
16}
17
18#[derive(Serialize)]
19pub(super) struct AvailableToolsResponse {
20 pub(super) tools: Vec<String>,
21}
22
23#[derive(Serialize)]
24pub(super) struct FilteredToolsResponse {
25 pub(super) tools: Vec<OpenAiTool>,
26}
27
28#[derive(Serialize)]
29pub(super) struct OpenAiTool {
30 #[serde(rename = "type")]
31 pub(super) tool_type: String,
32 pub(super) function: OpenAiFunction,
33}
34
35#[derive(Serialize)]
36pub(super) struct OpenAiFunction {
37 pub(super) name: String,
38 pub(super) description: String,
39 pub(super) parameters: Value,
40}
41
42#[derive(Serialize)]
43pub(super) struct AvailableWorkflowsResponse {
44 pub(super) workflows: Vec<String>,
45}
46
47#[derive(Deserialize)]
48pub struct FilteredToolsQuery {
49 pub(super) session_id: Option<String>,
50 pub(super) chat_id: Option<String>,
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn test_skill_list_response_serialization() {
59 let response = SkillListResponse {
60 skills: vec![],
61 total: 0,
62 };
63
64 let json = serde_json::to_string(&response).unwrap();
65 assert!(json.contains("\"skills\":[]"));
66 assert!(json.contains("\"total\":0"));
67 }
68
69 #[test]
70 fn test_list_skills_query_deserialization() {
71 let json = r#"{"search":"test"}"#;
72 let query: ListSkillsQuery = serde_json::from_str(json).unwrap();
73
74 assert_eq!(query.search, Some("test".to_string()));
75 assert_eq!(query.refresh, None);
76 }
77
78 #[test]
79 fn test_list_skills_query_with_refresh() {
80 let json = r#"{"search":"workflow","refresh":true}"#;
81 let query: ListSkillsQuery = serde_json::from_str(json).unwrap();
82
83 assert_eq!(query.search, Some("workflow".to_string()));
84 assert_eq!(query.refresh, Some(true));
85 assert_eq!(query.include_disabled, None);
86 }
87
88 #[test]
89 fn test_list_skills_query_with_include_disabled() {
90 let json = r#"{"search":"workflow","refresh":true,"include_disabled":true}"#;
91 let query: ListSkillsQuery = serde_json::from_str(json).unwrap();
92
93 assert_eq!(query.search, Some("workflow".to_string()));
94 assert_eq!(query.refresh, Some(true));
95 assert_eq!(query.include_disabled, Some(true));
96 }
97
98 #[test]
99 fn test_list_skills_query_empty() {
100 let json = r#"{}"#;
101 let query: ListSkillsQuery = serde_json::from_str(json).unwrap();
102
103 assert_eq!(query.search, None);
104 assert_eq!(query.refresh, None);
105 }
106
107 #[test]
108 fn test_available_tools_response_serialization() {
109 let response = AvailableToolsResponse {
110 tools: vec!["bash".to_string(), "read".to_string()],
111 };
112
113 let json = serde_json::to_string(&response).unwrap();
114 assert!(json.contains("bash"));
115 assert!(json.contains("read"));
116 }
117
118 #[test]
119 fn test_available_tools_response_empty() {
120 let response = AvailableToolsResponse { tools: vec![] };
121
122 let json = serde_json::to_string(&response).unwrap();
123 assert!(json.contains("\"tools\":[]"));
124 }
125
126 #[test]
127 fn test_open_ai_tool_serialization() {
128 let tool = OpenAiTool {
129 tool_type: "function".to_string(),
130 function: OpenAiFunction {
131 name: "read_file".to_string(),
132 description: "Read file contents".to_string(),
133 parameters: serde_json::json!({"type":"object"}),
134 },
135 };
136
137 let json = serde_json::to_string(&tool).unwrap();
138 assert!(json.contains("\"type\":\"function\""));
139 assert!(json.contains("read_file"));
140 assert!(json.contains("Read file contents"));
141 }
142
143 #[test]
144 fn test_open_ai_function_serialization() {
145 let func = OpenAiFunction {
146 name: "bash".to_string(),
147 description: "Execute bash command".to_string(),
148 parameters: serde_json::json!({
149 "type": "object",
150 "properties": {
151 "command": {"type": "string"}
152 }
153 }),
154 };
155
156 let json = serde_json::to_string(&func).unwrap();
157 assert!(json.contains("bash"));
158 assert!(json.contains("command"));
159 }
160
161 #[test]
162 fn test_available_workflows_response() {
163 let response = AvailableWorkflowsResponse {
164 workflows: vec!["deploy".to_string(), "test".to_string()],
165 };
166
167 let json = serde_json::to_string(&response).unwrap();
168 assert!(json.contains("deploy"));
169 assert!(json.contains("test"));
170 }
171
172 #[test]
173 fn test_filtered_tools_query_with_session() {
174 let json = r#"{"session_id":"sess-123"}"#;
175 let query: FilteredToolsQuery = serde_json::from_str(json).unwrap();
176
177 assert_eq!(query.session_id, Some("sess-123".to_string()));
178 assert_eq!(query.chat_id, None);
179 }
180
181 #[test]
182 fn test_filtered_tools_query_with_chat() {
183 let json = r#"{"chat_id":"chat-456"}"#;
184 let query: FilteredToolsQuery = serde_json::from_str(json).unwrap();
185
186 assert_eq!(query.session_id, None);
187 assert_eq!(query.chat_id, Some("chat-456".to_string()));
188 }
189
190 #[test]
191 fn test_filtered_tools_query_both() {
192 let json = r#"{"session_id":"sess-123","chat_id":"chat-456"}"#;
193 let query: FilteredToolsQuery = serde_json::from_str(json).unwrap();
194
195 assert_eq!(query.session_id, Some("sess-123".to_string()));
196 assert_eq!(query.chat_id, Some("chat-456".to_string()));
197 }
198
199 #[test]
200 fn test_filtered_tools_query_empty() {
201 let json = r#"{}"#;
202 let query: FilteredToolsQuery = serde_json::from_str(json).unwrap();
203
204 assert_eq!(query.session_id, None);
205 assert_eq!(query.chat_id, None);
206 }
207
208 #[test]
209 fn test_filtered_tools_response_serialization() {
210 let response = FilteredToolsResponse { tools: vec![] };
211
212 let json = serde_json::to_string(&response).unwrap();
213 assert!(json.contains("\"tools\":[]"));
214 }
215}