#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(super) enum DeepseekEffortTier {
Off,
Low,
High,
Max,
}
impl DeepseekEffortTier {
pub(super) fn chat_reasoning_effort(self) -> Option<&'static str> {
match self {
Self::Off => None,
Self::Low => Some("low"),
Self::High => Some("high"),
Self::Max => Some("max"),
}
}
pub(super) fn chat_thinking_enabled(self) -> bool {
!matches!(self, Self::Off)
}
pub(super) fn responses_effort(self) -> &'static str {
match self {
Self::Off => "none",
Self::Low => "low",
Self::High => "high",
Self::Max => "max",
}
}
}
pub(super) const DEEPSEEK_EFFORT_ALIASES: &[(&str, DeepseekEffortTier)] = &[
("off", DeepseekEffortTier::Off),
("disabled", DeepseekEffortTier::Off),
("none", DeepseekEffortTier::Off),
("false", DeepseekEffortTier::Off),
("minimal", DeepseekEffortTier::Low),
("low", DeepseekEffortTier::Low),
("medium", DeepseekEffortTier::High),
("mid", DeepseekEffortTier::High),
("high", DeepseekEffortTier::High),
("", DeepseekEffortTier::High),
("xhigh", DeepseekEffortTier::Max),
("max", DeepseekEffortTier::Max),
("maximum", DeepseekEffortTier::Max),
("highest", DeepseekEffortTier::Max),
("ultra", DeepseekEffortTier::Max),
("ultracode", DeepseekEffortTier::Max),
];
pub(super) const DEEPSEEK_DEFAULT_EFFORT_TIER: DeepseekEffortTier = DeepseekEffortTier::High;
pub(super) fn deepseek_effort_tier(raw: &str) -> Option<DeepseekEffortTier> {
let normalized = raw.trim().to_ascii_lowercase();
DEEPSEEK_EFFORT_ALIASES
.iter()
.find(|(alias, _)| *alias == normalized)
.map(|(_, tier)| *tier)
}
pub(super) fn deepseek_effort_tier_or_default(raw: &str) -> DeepseekEffortTier {
deepseek_effort_tier(raw).unwrap_or(DEEPSEEK_DEFAULT_EFFORT_TIER)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn aliases_are_unique_and_normalized() {
for (index, (alias, _)) in DEEPSEEK_EFFORT_ALIASES.iter().enumerate() {
assert_eq!(
*alias,
alias.trim().to_ascii_lowercase(),
"alias {alias:?} must be stored pre-normalized"
);
assert!(
!DEEPSEEK_EFFORT_ALIASES[..index]
.iter()
.any(|(seen, _)| seen == alias),
"duplicate alias {alias:?}"
);
}
}
#[test]
fn lookup_is_case_and_whitespace_insensitive() {
assert_eq!(
deepseek_effort_tier(" MAX "),
Some(DeepseekEffortTier::Max)
);
assert_eq!(deepseek_effort_tier("auto"), None);
assert_eq!(
deepseek_effort_tier_or_default("auto"),
DeepseekEffortTier::High
);
}
#[test]
fn ultra_and_legacy_ultracode_alias_resolve_to_max() {
assert_eq!(deepseek_effort_tier("ultra"), Some(DeepseekEffortTier::Max));
assert_eq!(
deepseek_effort_tier("ultracode"),
Some(DeepseekEffortTier::Max)
);
assert_eq!(
deepseek_effort_tier_or_default("ultra").responses_effort(),
"max"
);
}
#[test]
fn every_tier_has_both_wire_spellings() {
for tier in [
DeepseekEffortTier::Off,
DeepseekEffortTier::Low,
DeepseekEffortTier::High,
DeepseekEffortTier::Max,
] {
let responses = tier.responses_effort();
assert!(!responses.is_empty(), "{tier:?} needs a Responses label");
match tier {
DeepseekEffortTier::Off => {
assert_eq!(tier.chat_reasoning_effort(), None);
assert!(!tier.chat_thinking_enabled());
}
_ => {
assert_eq!(tier.chat_reasoning_effort(), Some(responses));
assert!(tier.chat_thinking_enabled());
}
}
}
}
}