brainwires_cognition/prompting/
techniques.rs1use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
11pub enum TechniqueCategory {
12 RoleAssignment,
14 EmotionalStimulus,
16 Reasoning,
18 Others,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
24pub enum PromptingTechnique {
25 RolePlaying,
27
28 EmotionPrompting,
30 StressPrompting,
32
33 ChainOfThought,
35 LogicOfThought,
37 LeastToMost,
39 ThreadOfThought,
41 PlanAndSolve,
43 SkeletonOfThought,
45 ScratchpadPrompting,
47
48 DecomposedPrompting,
50 IgnoreIrrelevantConditions,
52 HighlightedCoT,
54 SkillsInContext,
56 AutomaticInformationFiltering,
58}
59
60impl PromptingTechnique {
61 pub fn parse_id(s: &str) -> Result<Self, &'static str> {
63 match s.to_lowercase().as_str() {
64 "role_playing" | "roleplaying" => Ok(Self::RolePlaying),
65 "emotion_prompting" | "emotionprompting" => Ok(Self::EmotionPrompting),
66 "stress_prompting" | "stressprompting" => Ok(Self::StressPrompting),
67 "chain_of_thought" | "chainofthought" | "cot" => Ok(Self::ChainOfThought),
68 "logic_of_thought" | "logicofthought" | "lot" => Ok(Self::LogicOfThought),
69 "least_to_most" | "leasttomost" => Ok(Self::LeastToMost),
70 "thread_of_thought" | "threadofthought" | "tot" => Ok(Self::ThreadOfThought),
71 "plan_and_solve" | "planandsolve" => Ok(Self::PlanAndSolve),
72 "skeleton_of_thought" | "skeletonofthought" | "sot" => Ok(Self::SkeletonOfThought),
73 "scratchpad_prompting" | "scratchpadprompting" | "scratchpad" => {
74 Ok(Self::ScratchpadPrompting)
75 }
76 "decomposed_prompting" | "decomposedprompting" => Ok(Self::DecomposedPrompting),
77 "ignore_irrelevant_conditions" | "ignoreirrelevantconditions" => {
78 Ok(Self::IgnoreIrrelevantConditions)
79 }
80 "highlighted_cot" | "highlightedcot" => Ok(Self::HighlightedCoT),
81 "skills_in_context" | "skillsincontext" => Ok(Self::SkillsInContext),
82 "automatic_information_filtering" | "automaticinformationfiltering" => {
83 Ok(Self::AutomaticInformationFiltering)
84 }
85 _ => Err("Unknown technique"),
86 }
87 }
88
89 pub fn to_str(&self) -> &'static str {
91 match self {
92 Self::RolePlaying => "role_playing",
93 Self::EmotionPrompting => "emotion_prompting",
94 Self::StressPrompting => "stress_prompting",
95 Self::ChainOfThought => "chain_of_thought",
96 Self::LogicOfThought => "logic_of_thought",
97 Self::LeastToMost => "least_to_most",
98 Self::ThreadOfThought => "thread_of_thought",
99 Self::PlanAndSolve => "plan_and_solve",
100 Self::SkeletonOfThought => "skeleton_of_thought",
101 Self::ScratchpadPrompting => "scratchpad_prompting",
102 Self::DecomposedPrompting => "decomposed_prompting",
103 Self::IgnoreIrrelevantConditions => "ignore_irrelevant_conditions",
104 Self::HighlightedCoT => "highlighted_cot",
105 Self::SkillsInContext => "skills_in_context",
106 Self::AutomaticInformationFiltering => "automatic_information_filtering",
107 }
108 }
109}
110
111#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
113pub enum ComplexityLevel {
114 Simple,
116 Moderate,
118 Advanced,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
124pub enum TaskCharacteristic {
125 MultiStepReasoning,
127 NumericalCalculation,
129 LogicalDeduction,
131 CreativeGeneration,
133 LongContextSummarization,
135 SpatialReasoning,
137 VisualUnderstanding,
139 CodeGeneration,
141 AlgorithmicProblem,
143}
144
145#[derive(Debug, Clone)]
147pub struct TechniqueMetadata {
148 pub technique: PromptingTechnique,
150 pub category: TechniqueCategory,
152 pub name: String,
154 pub description: String,
156 pub template: String,
158 pub best_for: Vec<TaskCharacteristic>,
160
161 pub min_seal_quality: f32,
164 pub complexity_level: ComplexityLevel,
166 pub bks_promotion_eligible: bool,
168}
169
170impl TechniqueMetadata {
171 #[allow(clippy::too_many_arguments)]
173 pub fn new(
174 technique: PromptingTechnique,
175 category: TechniqueCategory,
176 name: impl Into<String>,
177 description: impl Into<String>,
178 template: impl Into<String>,
179 best_for: Vec<TaskCharacteristic>,
180 min_seal_quality: f32,
181 complexity_level: ComplexityLevel,
182 bks_promotion_eligible: bool,
183 ) -> Self {
184 Self {
185 technique,
186 category,
187 name: name.into(),
188 description: description.into(),
189 template: template.into(),
190 best_for,
191 min_seal_quality,
192 complexity_level,
193 bks_promotion_eligible,
194 }
195 }
196}
197
198#[cfg(test)]
199mod tests {
200 use super::*;
201
202 #[test]
203 fn test_technique_enum_all_variants() {
204 let techniques = vec![
206 PromptingTechnique::RolePlaying,
207 PromptingTechnique::EmotionPrompting,
208 PromptingTechnique::StressPrompting,
209 PromptingTechnique::ChainOfThought,
210 PromptingTechnique::LogicOfThought,
211 PromptingTechnique::LeastToMost,
212 PromptingTechnique::ThreadOfThought,
213 PromptingTechnique::PlanAndSolve,
214 PromptingTechnique::SkeletonOfThought,
215 PromptingTechnique::ScratchpadPrompting,
216 PromptingTechnique::DecomposedPrompting,
217 PromptingTechnique::IgnoreIrrelevantConditions,
218 PromptingTechnique::HighlightedCoT,
219 PromptingTechnique::SkillsInContext,
220 PromptingTechnique::AutomaticInformationFiltering,
221 ];
222 assert_eq!(techniques.len(), 15);
223 }
224
225 #[test]
226 fn test_technique_category_variants() {
227 let categories = vec![
228 TechniqueCategory::RoleAssignment,
229 TechniqueCategory::EmotionalStimulus,
230 TechniqueCategory::Reasoning,
231 TechniqueCategory::Others,
232 ];
233 assert_eq!(categories.len(), 4);
234 }
235
236 #[test]
237 fn test_complexity_level_ordering() {
238 let simple = ComplexityLevel::Simple;
240 let moderate = ComplexityLevel::Moderate;
241 let advanced = ComplexityLevel::Advanced;
242
243 assert_eq!(simple, ComplexityLevel::Simple);
245 assert_eq!(moderate, ComplexityLevel::Moderate);
246 assert_eq!(advanced, ComplexityLevel::Advanced);
247 }
248
249 #[test]
250 fn test_technique_string_conversion() {
251 let technique = PromptingTechnique::ChainOfThought;
253 let serialized = serde_json::to_string(&technique).unwrap();
254 let deserialized: PromptingTechnique = serde_json::from_str(&serialized).unwrap();
255 assert_eq!(technique, deserialized);
256 }
257
258 #[test]
259 fn test_technique_metadata_creation() {
260 let metadata = TechniqueMetadata::new(
261 PromptingTechnique::ChainOfThought,
262 TechniqueCategory::Reasoning,
263 "Chain-of-Thought",
264 "Step-by-step reasoning",
265 "Think step by step",
266 vec![TaskCharacteristic::MultiStepReasoning],
267 0.0,
268 ComplexityLevel::Simple,
269 true,
270 );
271
272 assert_eq!(metadata.technique, PromptingTechnique::ChainOfThought);
273 assert_eq!(metadata.category, TechniqueCategory::Reasoning);
274 assert_eq!(metadata.name, "Chain-of-Thought");
275 assert_eq!(metadata.min_seal_quality, 0.0);
276 assert_eq!(metadata.complexity_level, ComplexityLevel::Simple);
277 assert!(metadata.bks_promotion_eligible);
278 }
279
280 #[test]
281 fn test_task_characteristic_variants() {
282 let characteristics = vec![
283 TaskCharacteristic::MultiStepReasoning,
284 TaskCharacteristic::NumericalCalculation,
285 TaskCharacteristic::LogicalDeduction,
286 TaskCharacteristic::CreativeGeneration,
287 TaskCharacteristic::LongContextSummarization,
288 TaskCharacteristic::SpatialReasoning,
289 TaskCharacteristic::VisualUnderstanding,
290 ];
291 assert_eq!(characteristics.len(), 7);
292 }
293}