vtcode_config/core/
skills.rs1use serde::{Deserialize, Serialize};
21
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
24#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
25#[serde(rename_all = "kebab-case")]
26pub struct SkillsConfig {
27 #[serde(default = "default_render_mode")]
31 pub render_mode: SkillsRenderMode,
32
33 #[serde(default = "default_prompt_format")]
37 pub prompt_format: PromptFormat,
38
39 #[serde(default = "default_max_skills_in_prompt")]
41 pub max_skills_in_prompt: usize,
42
43 #[serde(default = "default_enable_auto_trigger")]
45 pub enable_auto_trigger: bool,
46
47 #[serde(default = "default_enable_description_matching")]
49 pub enable_description_matching: bool,
50
51 #[serde(default = "default_min_keyword_matches")]
53 pub min_keyword_matches: usize,
54}
55
56impl Default for SkillsConfig {
57 fn default() -> Self {
58 Self {
59 render_mode: default_render_mode(),
60 prompt_format: default_prompt_format(),
61 max_skills_in_prompt: default_max_skills_in_prompt(),
62 enable_auto_trigger: default_enable_auto_trigger(),
63 enable_description_matching: default_enable_description_matching(),
64 min_keyword_matches: default_min_keyword_matches(),
65 }
66 }
67}
68
69#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
71#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
72#[serde(rename_all = "lowercase")]
73pub enum SkillsRenderMode {
74 #[default]
76 Lean,
77 Full,
79}
80
81#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Default)]
83#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
84#[serde(rename_all = "lowercase")]
85pub enum PromptFormat {
86 #[default]
88 Xml,
89 Markdown,
91}
92
93fn default_render_mode() -> SkillsRenderMode {
94 SkillsRenderMode::Lean
95}
96
97fn default_prompt_format() -> PromptFormat {
98 PromptFormat::Xml
99}
100
101fn default_max_skills_in_prompt() -> usize {
102 10
103}
104
105fn default_enable_auto_trigger() -> bool {
106 true
107}
108
109fn default_enable_description_matching() -> bool {
110 true
111}
112
113fn default_min_keyword_matches() -> usize {
114 2
115}
116
117#[cfg(test)]
118mod tests {
119 use super::*;
120
121 #[test]
122 fn test_default_skills_config() {
123 let config = SkillsConfig::default();
124 assert_eq!(config.render_mode, SkillsRenderMode::Lean);
125 assert_eq!(config.prompt_format, PromptFormat::Xml);
126 assert_eq!(config.max_skills_in_prompt, 10);
127 assert!(config.enable_auto_trigger);
128 assert!(config.enable_description_matching);
129 assert_eq!(config.min_keyword_matches, 2);
130 }
131
132 #[test]
133 fn test_skills_render_mode_serde() {
134 let lean = SkillsRenderMode::Lean;
136 let lean_json = serde_json::to_string(&lean).unwrap();
137 assert_eq!(lean_json, r#""lean""#);
138
139 let full = SkillsRenderMode::Full;
140 let full_json = serde_json::to_string(&full).unwrap();
141 assert_eq!(full_json, r#""full""#);
142
143 let lean_de: SkillsRenderMode = serde_json::from_str(r#""lean""#).unwrap();
145 assert_eq!(lean_de, SkillsRenderMode::Lean);
146
147 let full_de: SkillsRenderMode = serde_json::from_str(r#""full""#).unwrap();
148 assert_eq!(full_de, SkillsRenderMode::Full);
149 }
150
151 #[test]
152 fn test_prompt_format_serde() {
153 let xml = PromptFormat::Xml;
155 let xml_json = serde_json::to_string(&xml).unwrap();
156 assert_eq!(xml_json, r#""xml""#);
157
158 let markdown = PromptFormat::Markdown;
159 let markdown_json = serde_json::to_string(&markdown).unwrap();
160 assert_eq!(markdown_json, r#""markdown""#);
161
162 let xml_de: PromptFormat = serde_json::from_str(r#""xml""#).unwrap();
164 assert_eq!(xml_de, PromptFormat::Xml);
165
166 let markdown_de: PromptFormat = serde_json::from_str(r#""markdown""#).unwrap();
167 assert_eq!(markdown_de, PromptFormat::Markdown);
168 }
169
170 #[test]
171 fn test_skills_config_serde() {
172 let config = SkillsConfig {
173 render_mode: SkillsRenderMode::Full,
174 prompt_format: PromptFormat::Markdown,
175 max_skills_in_prompt: 15,
176 enable_auto_trigger: false,
177 enable_description_matching: false,
178 min_keyword_matches: 3,
179 };
180
181 let json = serde_json::to_string_pretty(&config).unwrap();
182 let deserialized: SkillsConfig = serde_json::from_str(&json).unwrap();
183 assert_eq!(config, deserialized);
184 }
185}