Skip to main content

tea_protocol/
reasoning.rs

1use std::fmt;
2use std::str::FromStr;
3
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7/// Provider-neutral reasoning effort ordered from disabled to maximum.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "snake_case")]
10pub enum ReasoningEffort {
11    /// Explicitly disable model reasoning.
12    Off,
13    /// Smallest non-zero reasoning effort.
14    Minimal,
15    /// Low reasoning effort.
16    Low,
17    /// Medium reasoning effort.
18    Medium,
19    /// High reasoning effort.
20    High,
21    /// Extended high reasoning effort, encoded as `xhigh`.
22    #[serde(rename = "xhigh")]
23    ExtraHigh,
24    /// Provider/model maximum reasoning effort, encoded as `max`.
25    #[serde(rename = "max")]
26    Maximum,
27}
28
29impl ReasoningEffort {
30    /// Every canonical level in ascending effort order.
31    pub const ALL: [Self; 7] = [
32        Self::Off,
33        Self::Minimal,
34        Self::Low,
35        Self::Medium,
36        Self::High,
37        Self::ExtraHigh,
38        Self::Maximum,
39    ];
40
41    /// Levels eligible for quick shortcut cycling.
42    pub const SHORTCUT_LEVELS: [Self; 5] = [
43        Self::Off,
44        Self::Minimal,
45        Self::Low,
46        Self::Medium,
47        Self::High,
48    ];
49
50    /// Returns the stable configuration and protocol spelling.
51    #[must_use]
52    pub const fn as_str(self) -> &'static str {
53        match self {
54            Self::Off => "off",
55            Self::Minimal => "minimal",
56            Self::Low => "low",
57            Self::Medium => "medium",
58            Self::High => "high",
59            Self::ExtraHigh => "xhigh",
60            Self::Maximum => "max",
61        }
62    }
63}
64
65impl fmt::Display for ReasoningEffort {
66    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
67        formatter.write_str(self.as_str())
68    }
69}
70
71impl FromStr for ReasoningEffort {
72    type Err = ReasoningEffortParseError;
73
74    fn from_str(value: &str) -> Result<Self, Self::Err> {
75        match value {
76            "off" => Ok(Self::Off),
77            "minimal" => Ok(Self::Minimal),
78            "low" => Ok(Self::Low),
79            "medium" => Ok(Self::Medium),
80            "high" => Ok(Self::High),
81            "xhigh" => Ok(Self::ExtraHigh),
82            "max" => Ok(Self::Maximum),
83            _ => Err(ReasoningEffortParseError),
84        }
85    }
86}
87
88/// Error returned for an unknown reasoning effort spelling.
89#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
90#[error("reasoning effort is invalid")]
91pub struct ReasoningEffortParseError;