Skip to main content

ai_agents_reasoning/
mode.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
4#[serde(rename_all = "snake_case")]
5pub enum ReasoningMode {
6    #[default]
7    None,
8    #[serde(alias = "cot")]
9    CoT,
10    React,
11    PlanAndExecute,
12    Auto,
13}
14
15impl ReasoningMode {
16    pub fn requires_llm_judge(&self) -> bool {
17        matches!(self, ReasoningMode::Auto)
18    }
19
20    pub fn uses_planning(&self) -> bool {
21        matches!(self, ReasoningMode::PlanAndExecute)
22    }
23
24    pub fn uses_iteration(&self) -> bool {
25        matches!(self, ReasoningMode::React | ReasoningMode::PlanAndExecute)
26    }
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
30#[serde(rename_all = "lowercase")]
31pub enum ReflectionMode {
32    #[default]
33    #[serde(alias = "false")]
34    Disabled,
35    #[serde(alias = "true")]
36    Enabled,
37    Auto,
38}
39
40impl ReflectionMode {
41    pub fn is_enabled(&self) -> bool {
42        matches!(self, ReflectionMode::Enabled)
43    }
44
45    pub fn is_auto(&self) -> bool {
46        matches!(self, ReflectionMode::Auto)
47    }
48
49    pub fn requires_evaluation(&self) -> bool {
50        !matches!(self, ReflectionMode::Disabled)
51    }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
55#[serde(rename_all = "lowercase")]
56pub enum ReasoningOutput {
57    #[default]
58    Hidden,
59    Visible,
60    Tagged,
61}
62
63impl ReasoningOutput {
64    pub fn should_include_thinking(&self) -> bool {
65        !matches!(self, ReasoningOutput::Hidden)
66    }
67
68    pub fn uses_tags(&self) -> bool {
69        matches!(self, ReasoningOutput::Tagged)
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use super::*;
76
77    #[test]
78    fn test_reasoning_mode_default() {
79        let mode: ReasoningMode = Default::default();
80        assert_eq!(mode, ReasoningMode::None);
81    }
82
83    #[test]
84    fn test_reasoning_mode_serde() {
85        let mode: ReasoningMode = serde_json::from_str(r#""cot""#).unwrap();
86        assert_eq!(mode, ReasoningMode::CoT);
87
88        let mode: ReasoningMode = serde_json::from_str(r#""plan_and_execute""#).unwrap();
89        assert_eq!(mode, ReasoningMode::PlanAndExecute);
90
91        let mode: ReasoningMode = serde_json::from_str(r#""auto""#).unwrap();
92        assert_eq!(mode, ReasoningMode::Auto);
93    }
94
95    #[test]
96    fn test_reasoning_mode_requires_llm_judge() {
97        assert!(!ReasoningMode::None.requires_llm_judge());
98        assert!(!ReasoningMode::CoT.requires_llm_judge());
99        assert!(ReasoningMode::Auto.requires_llm_judge());
100    }
101
102    #[test]
103    fn test_reasoning_mode_uses_planning() {
104        assert!(!ReasoningMode::None.uses_planning());
105        assert!(!ReasoningMode::CoT.uses_planning());
106        assert!(ReasoningMode::PlanAndExecute.uses_planning());
107    }
108
109    #[test]
110    fn test_reflection_mode_default() {
111        let mode: ReflectionMode = Default::default();
112        assert_eq!(mode, ReflectionMode::Disabled);
113    }
114
115    #[test]
116    fn test_reflection_mode_serde_aliases() {
117        let mode: ReflectionMode = serde_json::from_str(r#""true""#).unwrap();
118        assert_eq!(mode, ReflectionMode::Enabled);
119
120        let mode: ReflectionMode = serde_json::from_str(r#""false""#).unwrap();
121        assert_eq!(mode, ReflectionMode::Disabled);
122
123        let mode: ReflectionMode = serde_json::from_str(r#""enabled""#).unwrap();
124        assert_eq!(mode, ReflectionMode::Enabled);
125    }
126
127    #[test]
128    fn test_reflection_mode_methods() {
129        assert!(!ReflectionMode::Disabled.is_enabled());
130        assert!(ReflectionMode::Enabled.is_enabled());
131        assert!(!ReflectionMode::Auto.is_enabled());
132
133        assert!(ReflectionMode::Auto.is_auto());
134        assert!(!ReflectionMode::Enabled.is_auto());
135
136        assert!(!ReflectionMode::Disabled.requires_evaluation());
137        assert!(ReflectionMode::Enabled.requires_evaluation());
138        assert!(ReflectionMode::Auto.requires_evaluation());
139    }
140
141    #[test]
142    fn test_reasoning_output_default() {
143        let output: ReasoningOutput = Default::default();
144        assert_eq!(output, ReasoningOutput::Hidden);
145    }
146
147    #[test]
148    fn test_reasoning_output_methods() {
149        assert!(!ReasoningOutput::Hidden.should_include_thinking());
150        assert!(ReasoningOutput::Visible.should_include_thinking());
151        assert!(ReasoningOutput::Tagged.should_include_thinking());
152
153        assert!(!ReasoningOutput::Hidden.uses_tags());
154        assert!(!ReasoningOutput::Visible.uses_tags());
155        assert!(ReasoningOutput::Tagged.uses_tags());
156    }
157}