ai_agents_reasoning/
mode.rs1use 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}