use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum TechniqueCategory {
RoleAssignment,
EmotionalStimulus,
Reasoning,
Others,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
pub enum PromptingTechnique {
RolePlaying,
EmotionPrompting,
StressPrompting,
ChainOfThought,
LogicOfThought,
LeastToMost,
ThreadOfThought,
PlanAndSolve,
SkeletonOfThought,
ScratchpadPrompting,
DecomposedPrompting,
IgnoreIrrelevantConditions,
HighlightedCoT,
SkillsInContext,
AutomaticInformationFiltering,
}
impl PromptingTechnique {
pub fn parse_id(s: &str) -> Result<Self, &'static str> {
match s.to_lowercase().as_str() {
"role_playing" | "roleplaying" => Ok(Self::RolePlaying),
"emotion_prompting" | "emotionprompting" => Ok(Self::EmotionPrompting),
"stress_prompting" | "stressprompting" => Ok(Self::StressPrompting),
"chain_of_thought" | "chainofthought" | "cot" => Ok(Self::ChainOfThought),
"logic_of_thought" | "logicofthought" | "lot" => Ok(Self::LogicOfThought),
"least_to_most" | "leasttomost" => Ok(Self::LeastToMost),
"thread_of_thought" | "threadofthought" | "tot" => Ok(Self::ThreadOfThought),
"plan_and_solve" | "planandsolve" => Ok(Self::PlanAndSolve),
"skeleton_of_thought" | "skeletonofthought" | "sot" => Ok(Self::SkeletonOfThought),
"scratchpad_prompting" | "scratchpadprompting" | "scratchpad" => {
Ok(Self::ScratchpadPrompting)
}
"decomposed_prompting" | "decomposedprompting" => Ok(Self::DecomposedPrompting),
"ignore_irrelevant_conditions" | "ignoreirrelevantconditions" => {
Ok(Self::IgnoreIrrelevantConditions)
}
"highlighted_cot" | "highlightedcot" => Ok(Self::HighlightedCoT),
"skills_in_context" | "skillsincontext" => Ok(Self::SkillsInContext),
"automatic_information_filtering" | "automaticinformationfiltering" => {
Ok(Self::AutomaticInformationFiltering)
}
_ => Err("Unknown technique"),
}
}
pub fn to_str(&self) -> &'static str {
match self {
Self::RolePlaying => "role_playing",
Self::EmotionPrompting => "emotion_prompting",
Self::StressPrompting => "stress_prompting",
Self::ChainOfThought => "chain_of_thought",
Self::LogicOfThought => "logic_of_thought",
Self::LeastToMost => "least_to_most",
Self::ThreadOfThought => "thread_of_thought",
Self::PlanAndSolve => "plan_and_solve",
Self::SkeletonOfThought => "skeleton_of_thought",
Self::ScratchpadPrompting => "scratchpad_prompting",
Self::DecomposedPrompting => "decomposed_prompting",
Self::IgnoreIrrelevantConditions => "ignore_irrelevant_conditions",
Self::HighlightedCoT => "highlighted_cot",
Self::SkillsInContext => "skills_in_context",
Self::AutomaticInformationFiltering => "automatic_information_filtering",
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum ComplexityLevel {
Simple,
Moderate,
Advanced,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum TaskCharacteristic {
MultiStepReasoning,
NumericalCalculation,
LogicalDeduction,
CreativeGeneration,
LongContextSummarization,
SpatialReasoning,
VisualUnderstanding,
CodeGeneration,
AlgorithmicProblem,
}
#[derive(Debug, Clone)]
pub struct TechniqueMetadata {
pub technique: PromptingTechnique,
pub category: TechniqueCategory,
pub name: String,
pub description: String,
pub template: String,
pub best_for: Vec<TaskCharacteristic>,
pub min_seal_quality: f32,
pub complexity_level: ComplexityLevel,
pub bks_promotion_eligible: bool,
}
impl TechniqueMetadata {
#[allow(clippy::too_many_arguments)]
pub fn new(
technique: PromptingTechnique,
category: TechniqueCategory,
name: impl Into<String>,
description: impl Into<String>,
template: impl Into<String>,
best_for: Vec<TaskCharacteristic>,
min_seal_quality: f32,
complexity_level: ComplexityLevel,
bks_promotion_eligible: bool,
) -> Self {
Self {
technique,
category,
name: name.into(),
description: description.into(),
template: template.into(),
best_for,
min_seal_quality,
complexity_level,
bks_promotion_eligible,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_technique_enum_all_variants() {
let techniques = vec![
PromptingTechnique::RolePlaying,
PromptingTechnique::EmotionPrompting,
PromptingTechnique::StressPrompting,
PromptingTechnique::ChainOfThought,
PromptingTechnique::LogicOfThought,
PromptingTechnique::LeastToMost,
PromptingTechnique::ThreadOfThought,
PromptingTechnique::PlanAndSolve,
PromptingTechnique::SkeletonOfThought,
PromptingTechnique::ScratchpadPrompting,
PromptingTechnique::DecomposedPrompting,
PromptingTechnique::IgnoreIrrelevantConditions,
PromptingTechnique::HighlightedCoT,
PromptingTechnique::SkillsInContext,
PromptingTechnique::AutomaticInformationFiltering,
];
assert_eq!(techniques.len(), 15);
}
#[test]
fn test_technique_category_variants() {
let categories = vec![
TechniqueCategory::RoleAssignment,
TechniqueCategory::EmotionalStimulus,
TechniqueCategory::Reasoning,
TechniqueCategory::Others,
];
assert_eq!(categories.len(), 4);
}
#[test]
fn test_complexity_level_ordering() {
let simple = ComplexityLevel::Simple;
let moderate = ComplexityLevel::Moderate;
let advanced = ComplexityLevel::Advanced;
assert_eq!(simple, ComplexityLevel::Simple);
assert_eq!(moderate, ComplexityLevel::Moderate);
assert_eq!(advanced, ComplexityLevel::Advanced);
}
#[test]
fn test_technique_string_conversion() {
let technique = PromptingTechnique::ChainOfThought;
let serialized = serde_json::to_string(&technique).unwrap();
let deserialized: PromptingTechnique = serde_json::from_str(&serialized).unwrap();
assert_eq!(technique, deserialized);
}
#[test]
fn test_technique_metadata_creation() {
let metadata = TechniqueMetadata::new(
PromptingTechnique::ChainOfThought,
TechniqueCategory::Reasoning,
"Chain-of-Thought",
"Step-by-step reasoning",
"Think step by step",
vec![TaskCharacteristic::MultiStepReasoning],
0.0,
ComplexityLevel::Simple,
true,
);
assert_eq!(metadata.technique, PromptingTechnique::ChainOfThought);
assert_eq!(metadata.category, TechniqueCategory::Reasoning);
assert_eq!(metadata.name, "Chain-of-Thought");
assert_eq!(metadata.min_seal_quality, 0.0);
assert_eq!(metadata.complexity_level, ComplexityLevel::Simple);
assert!(metadata.bks_promotion_eligible);
}
#[test]
fn test_task_characteristic_variants() {
let characteristics = vec![
TaskCharacteristic::MultiStepReasoning,
TaskCharacteristic::NumericalCalculation,
TaskCharacteristic::LogicalDeduction,
TaskCharacteristic::CreativeGeneration,
TaskCharacteristic::LongContextSummarization,
TaskCharacteristic::SpatialReasoning,
TaskCharacteristic::VisualUnderstanding,
];
assert_eq!(characteristics.len(), 7);
}
}