use std::collections::{BTreeMap, BTreeSet};
use serde_json::{json, Map, Value};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Effort {
None,
Minimal,
Low,
Medium,
High,
XHigh,
Max,
}
pub const KNOWN_REASONING_EFFORTS: [Effort; 7] = [
Effort::None,
Effort::Minimal,
Effort::Low,
Effort::Medium,
Effort::High,
Effort::XHigh,
Effort::Max,
];
pub const OPENAI_EFFORT_TRIPLE: [Effort; 3] = [Effort::Low, Effort::Medium, Effort::High];
pub const GRADED_EFFORT_LADDER: [Effort; 4] =
[Effort::Low, Effort::Medium, Effort::High, Effort::XHigh];
impl Effort {
pub fn scale(self) -> f32 {
match self {
Effort::None => 0.0,
Effort::Minimal => 0.1,
Effort::Low => 0.2,
Effort::Medium => 0.7,
Effort::High => 0.9,
Effort::XHigh => 0.99,
Effort::Max => 0.99,
}
}
pub fn as_str(self) -> &'static str {
match self {
Effort::None => "none",
Effort::Minimal => "minimal",
Effort::Low => "low",
Effort::Medium => "medium",
Effort::High => "high",
Effort::XHigh => "xhigh",
Effort::Max => "max",
}
}
pub fn parse(value: &str) -> Option<Effort> {
KNOWN_REASONING_EFFORTS
.iter()
.copied()
.find(|e| e.as_str() == value)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct EffortProfile {
pub supported: BTreeSet<Effort>,
pub default: Option<Effort>,
pub consumes_effort: bool,
pub validates: bool,
pub strength_dialect: bool,
}
impl EffortProfile {
pub fn inert() -> Self {
EffortProfile {
supported: BTreeSet::new(),
default: None,
consumes_effort: false,
validates: false,
strength_dialect: false,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ThinkingProfile {
pub efforts: EffortProfile,
pub toggleable: bool,
pub has_adaptive: bool,
pub default_state: ThinkingState,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThinkingState {
On,
Off,
Adaptive,
}
pub fn thinking_off_kwargs() -> Map<String, Value> {
let mut m = Map::new();
m.insert("enable_thinking".into(), json!(false));
m.insert("thinking_mode".into(), json!("disabled"));
m
}
pub fn thinking_on_kwargs() -> Map<String, Value> {
let mut m = Map::new();
m.insert("enable_thinking".into(), json!(true));
m.insert("thinking_mode".into(), json!("enabled"));
m
}
pub fn thinking_adaptive_kwargs() -> Map<String, Value> {
let mut m = Map::new();
m.insert("thinking_mode".into(), json!("adaptive"));
m
}
pub fn effective_efforts(profile: &EffortProfile) -> BTreeSet<Effort> {
if !profile.consumes_effort {
return BTreeSet::new();
}
let all: BTreeSet<Effort> = KNOWN_REASONING_EFFORTS.iter().copied().collect();
if profile.validates || profile.supported != all {
return profile.supported.clone();
}
let ladder: &[Effort] = if profile.strength_dialect {
&GRADED_EFFORT_LADDER
} else {
&OPENAI_EFFORT_TRIPLE
};
let mut vocab: BTreeSet<Effort> = ladder
.iter()
.copied()
.filter(|e| profile.supported.contains(e))
.collect();
if let Some(default) = profile.default {
vocab.insert(default);
}
vocab
}
const MAX_QUANTIZE_DISTANCE: f32 = 0.15;
pub fn quantize_effort(value: &str, profile: &EffortProfile) -> Option<Effort> {
let supported = effective_efforts(profile);
if supported.is_empty() {
return None;
}
let asked = Effort::parse(value)?;
if supported.contains(&asked) {
return Some(asked);
}
let position = asked.scale();
let mut ranked: Vec<Effort> = supported
.iter()
.copied()
.filter(|e| *e != Effort::Max)
.collect();
ranked.sort_by(|a, b| {
let da = (a.scale() - position).abs();
let db = (b.scale() - position).abs();
da.total_cmp(&db)
.then_with(|| b.scale().total_cmp(&a.scale()))
});
match ranked.first() {
Some(best) if (best.scale() - position).abs() <= MAX_QUANTIZE_DISTANCE => Some(*best),
_ => None,
}
}
fn probe_tools() -> Vec<Value> {
vec![json!({
"type": "function",
"function": {
"name": "noop",
"description": "No-op probe tool.",
"parameters": {"type": "object", "properties": {}},
},
})]
}
type ProbeRound<'a> = (Map<String, Value>, Option<&'a [Value]>);
pub fn probe_effort_profile<E>(
mut render: impl FnMut(&Map<String, Value>, Option<&[Value]>) -> Result<String, E>,
) -> EffortProfile {
let tools = probe_tools();
let rounds: [ProbeRound; 3] = [
(Map::new(), None),
(Map::new(), Some(tools.as_slice())),
(
{
let mut m = Map::new();
m.insert("enable_thinking".into(), json!(true));
m
},
None,
),
];
let mut rejected: BTreeSet<Effort> = BTreeSet::new();
let mut diverged: BTreeSet<Effort> = BTreeSet::new();
let mut matches_baseline: Vec<(Effort, bool)> =
KNOWN_REASONING_EFFORTS.iter().map(|e| (*e, true)).collect();
let mut ran_rounds = 0usize;
for (base_kwargs, round_tools) in rounds.iter() {
let baseline = match render(base_kwargs, *round_tools) {
Ok(text) => text,
Err(_) => continue,
};
ran_rounds += 1;
for effort in KNOWN_REASONING_EFFORTS {
let mut kwargs = base_kwargs.clone();
kwargs.insert("reasoning_effort".into(), json!(effort.as_str()));
match render(&kwargs, *round_tools) {
Err(_) => {
rejected.insert(effort);
set_match(&mut matches_baseline, effort, false);
}
Ok(rendering) => {
if rendering != baseline {
diverged.insert(effort);
set_match(&mut matches_baseline, effort, false);
}
}
}
}
}
if ran_rounds == 0 {
return EffortProfile::inert();
}
let strength_dialect = match (render(&Map::new(), None), {
let mut m = Map::new();
m.insert("reasoning_strength".into(), json!("low"));
render(&m, None)
}) {
(Ok(baseline), Ok(moved)) => moved != baseline,
_ => false,
};
let supported: BTreeSet<Effort> = KNOWN_REASONING_EFFORTS
.iter()
.copied()
.filter(|e| !rejected.contains(e))
.collect();
let consumes = !rejected.is_empty() || !diverged.is_empty();
let mut default = None;
if consumes {
default = supported
.iter()
.copied()
.filter(|e| matches(&matches_baseline, *e))
.max_by(|a, b| a.scale().total_cmp(&b.scale()));
}
EffortProfile {
supported,
default,
consumes_effort: consumes,
validates: !rejected.is_empty(),
strength_dialect,
}
}
pub fn probe_thinking_profile<E>(
mut render: impl FnMut(&Map<String, Value>, Option<&[Value]>) -> Result<String, E>,
efforts: EffortProfile,
) -> ThinkingProfile {
let inert = |efforts: EffortProfile| ThinkingProfile {
efforts,
toggleable: false,
has_adaptive: false,
default_state: ThinkingState::On,
};
let (baseline, off, on) = match (
render(&Map::new(), None),
render(&thinking_off_kwargs(), None),
render(&thinking_on_kwargs(), None),
) {
(Ok(baseline), Ok(off), Ok(on)) => (baseline, off, on),
_ => return inert(efforts),
};
let toggleable = off != on;
let mut has_adaptive = false;
let mut adaptive: Option<String> = None;
if toggleable {
match render(&thinking_adaptive_kwargs(), None) {
Ok(text) => {
has_adaptive = text != off && text != on;
adaptive = Some(text);
}
Err(_) => has_adaptive = false,
}
}
let mut default_state = ThinkingState::On;
if toggleable {
if baseline == off {
default_state = ThinkingState::Off;
} else if has_adaptive && adaptive.as_deref() == Some(baseline.as_str()) {
default_state = ThinkingState::Adaptive;
}
}
ThinkingProfile {
efforts,
toggleable,
has_adaptive,
default_state,
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ThinkingMode {
Chat,
Thinking,
}
impl ThinkingMode {
pub fn as_str(self) -> &'static str {
match self {
ThinkingMode::Chat => "chat",
ThinkingMode::Thinking => "thinking",
}
}
}
pub fn resolve_thinking_mode(
chat_template_kwargs: Option<&Map<String, Value>>,
tools: Option<&[Value]>,
) -> ThinkingMode {
let empty = Map::new();
let ctk = chat_template_kwargs.unwrap_or(&empty);
let mut mode = match ctk.get("thinking_mode").and_then(|v| v.as_str()) {
Some("thinking") => ThinkingMode::Thinking,
_ => ThinkingMode::Chat,
};
let truthy = |key: &str| match ctk.get(key) {
Some(Value::Bool(b)) => *b,
Some(Value::String(s)) => !s.is_empty(),
Some(Value::Number(n)) => n.as_f64().map(|f| f != 0.0).unwrap_or(false),
_ => false,
};
if tools.is_some_and(|t| !t.is_empty()) || truthy("enable_thinking") || truthy("thinking") {
mode = ThinkingMode::Thinking;
}
mode
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EffortMapping {
Unchanged,
Mapped(Effort),
Dropped,
}
pub fn sanitize_effort(
chat_template_kwargs: &mut Map<String, Value>,
profile: &EffortProfile,
) -> EffortMapping {
let raw = match chat_template_kwargs.get("reasoning_effort") {
Some(value) => value.clone(),
None => return EffortMapping::Unchanged,
};
let asked = raw.as_str().unwrap_or("");
let mapped = quantize_effort(asked, profile);
match mapped {
Some(effort) if effort.as_str() == asked => EffortMapping::Unchanged,
Some(effort) => {
chat_template_kwargs.insert("reasoning_effort".into(), json!(effort.as_str()));
EffortMapping::Mapped(effort)
}
None => {
chat_template_kwargs.remove("reasoning_effort");
EffortMapping::Dropped
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ThinkGears {
pub supported: Vec<String>,
pub default: Option<String>,
pub kwargs: BTreeMap<String, Map<String, Value>>,
}
impl ThinkGears {
pub fn is_empty(&self) -> bool {
self.supported.is_empty()
}
pub fn kwargs_for(&self, gear: &str) -> Option<&Map<String, Value>> {
self.kwargs.get(gear)
}
}
pub fn derive_think_gears(profile: &ThinkingProfile, parser_configured: bool) -> ThinkGears {
let mut supported: Vec<String> = Vec::new();
let mut kwargs: BTreeMap<String, Map<String, Value>> = BTreeMap::new();
let mut offer = |gear: &str, k: Map<String, Value>, list: &mut Vec<String>| {
list.push(gear.to_string());
kwargs.insert(gear.to_string(), k);
};
if profile.toggleable {
offer("off", thinking_off_kwargs(), &mut supported);
}
if profile.has_adaptive {
offer("adaptive", thinking_adaptive_kwargs(), &mut supported);
}
let efforts = effective_efforts(&profile.efforts);
if !efforts.is_empty() {
for effort in efforts.iter().copied() {
let mut k = if profile.toggleable {
thinking_on_kwargs()
} else {
Map::new()
};
k.insert("reasoning_effort".into(), json!(effort.as_str()));
offer(effort.as_str(), k, &mut supported);
}
} else if profile.toggleable {
offer("on", thinking_on_kwargs(), &mut supported);
} else if parser_configured {
offer("on", Map::new(), &mut supported);
}
let has = |gear: &str| supported.iter().any(|g| g == gear);
let default = match profile.default_state {
ThinkingState::Off if has("off") => Some("off".to_string()),
ThinkingState::Adaptive if has("adaptive") => Some("adaptive".to_string()),
_ => None,
}
.or_else(|| {
if efforts.is_empty() {
return None;
}
profile
.efforts
.default
.map(|e| e.as_str().to_string())
.filter(|e| has(e))
.or_else(|| has("medium").then(|| "medium".to_string()))
})
.or_else(|| has("on").then(|| "on".to_string()))
.or_else(|| supported.last().cloned());
ThinkGears {
default: default.filter(|_| !supported.is_empty()),
supported,
kwargs,
}
}
pub fn broadcast_effort_spellings(chat_template_kwargs: &mut Map<String, Value>) {
if let Some(effort) = chat_template_kwargs.get("reasoning_effort").cloned() {
chat_template_kwargs
.entry("reasoning_strength".to_string())
.or_insert(effort);
}
}
fn set_match(table: &mut [(Effort, bool)], effort: Effort, value: bool) {
if let Some(slot) = table.iter_mut().find(|(e, _)| *e == effort) {
slot.1 = value;
}
}
fn matches(table: &[(Effort, bool)], effort: Effort) -> bool {
table
.iter()
.find(|(e, _)| *e == effort)
.map(|(_, v)| *v)
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;
fn profile(supported: &[Effort], default: Option<Effort>) -> EffortProfile {
EffortProfile {
supported: supported.iter().copied().collect(),
default,
consumes_effort: true,
validates: true,
strength_dialect: false,
}
}
#[test]
fn in_vocabulary_values_pass_through() {
let p = profile(&[Effort::Low, Effort::Medium, Effort::High], None);
assert_eq!(quantize_effort("medium", &p), Some(Effort::Medium));
}
#[test]
fn unknown_names_and_inert_templates_send_nothing() {
let p = profile(&[Effort::Low, Effort::High], None);
assert_eq!(quantize_effort("turbo", &p), None);
assert_eq!(quantize_effort("high", &EffortProfile::inert()), None);
}
#[test]
fn medium_does_not_escalate_to_a_far_high() {
let p = profile(&[Effort::None, Effort::High], None);
assert_eq!(quantize_effort("medium", &p), None);
}
#[test]
fn high_reaches_xhigh() {
let p = profile(&[Effort::Low, Effort::XHigh], None);
assert_eq!(quantize_effort("high", &p), Some(Effort::XHigh));
}
#[test]
fn max_is_never_entered_by_rounding() {
let p = profile(&[Effort::Low, Effort::Max], None);
assert_eq!(quantize_effort("high", &p), None);
assert_eq!(quantize_effort("max", &p), Some(Effort::Max));
}
#[test]
fn unvalidated_grader_is_capped_to_its_ladder() {
let all: BTreeSet<Effort> = KNOWN_REASONING_EFFORTS.iter().copied().collect();
let p = EffortProfile {
supported: all.clone(),
default: None,
consumes_effort: true,
validates: false,
strength_dialect: false,
};
assert_eq!(
effective_efforts(&p),
OPENAI_EFFORT_TRIPLE.iter().copied().collect()
);
assert_eq!(quantize_effort("minimal", &p), Some(Effort::Low));
let strength = EffortProfile {
strength_dialect: true,
..p
};
assert_eq!(
effective_efforts(&strength),
GRADED_EFFORT_LADDER.iter().copied().collect()
);
assert_eq!(quantize_effort("max", &strength), Some(Effort::XHigh));
}
#[test]
fn probed_default_is_always_offered() {
let all: BTreeSet<Effort> = KNOWN_REASONING_EFFORTS.iter().copied().collect();
let p = EffortProfile {
supported: all,
default: Some(Effort::None),
consumes_effort: true,
validates: false,
strength_dialect: false,
};
assert!(effective_efforts(&p).contains(&Effort::None));
}
#[test]
fn a_template_that_ignores_effort_is_served_no_vocabulary() {
let p = probe_effort_profile(|_kwargs, _tools| Ok::<_, ()>("same".to_string()));
assert!(!p.consumes_effort);
assert!(effective_efforts(&p).is_empty());
assert_eq!(quantize_effort("high", &p), None);
}
#[test]
fn a_template_that_rejects_every_shape_is_inert() {
let p = probe_effort_profile(|_kwargs, _tools| Err::<String, _>(()));
assert_eq!(p, EffortProfile::inert());
}
#[test]
fn probe_learns_a_validated_vocabulary() {
let p = probe_effort_profile(|kwargs, _tools| {
match kwargs.get("reasoning_effort").and_then(|v| v.as_str()) {
None => Ok("base".to_string()),
Some(name) if OPENAI_EFFORT_TRIPLE.iter().any(|e| e.as_str() == name) => {
Ok(format!("base+{name}"))
}
Some(_) => Err(()),
}
});
assert!(p.consumes_effort);
assert!(p.validates);
assert_eq!(
p.supported,
OPENAI_EFFORT_TRIPLE
.iter()
.copied()
.collect::<BTreeSet<_>>()
);
assert_eq!(p.default, None);
}
#[test]
fn probe_finds_the_highest_baseline_matching_default() {
let p = probe_effort_profile(|kwargs, _tools| {
match kwargs.get("reasoning_effort").and_then(|v| v.as_str()) {
Some("low") | Some("medium") => Ok("base".to_string()),
Some("high") => Ok("hard".to_string()),
Some(_) => Err(()),
None => Ok("base".to_string()),
}
});
assert_eq!(p.default, Some(Effort::Medium));
}
#[test]
fn thinking_probe_reads_the_toggle_and_its_default() {
let p = probe_thinking_profile(
|kwargs, _tools| {
let enabled = kwargs.get("enable_thinking").and_then(|v| v.as_bool());
let mode = kwargs.get("thinking_mode").and_then(|v| v.as_str());
Ok::<_, ()>(match (enabled, mode) {
(Some(false), _) => "off".to_string(),
(Some(true), _) => "on".to_string(),
(None, Some("adaptive")) => "adaptive".to_string(),
_ => "off".to_string(),
})
},
EffortProfile::inert(),
);
assert!(p.toggleable);
assert!(p.has_adaptive);
assert_eq!(p.default_state, ThinkingState::Off);
}
#[test]
fn tools_or_an_explicit_opt_in_turn_thinking_on() {
let tools = probe_tools();
assert_eq!(
resolve_thinking_mode(None, Some(&tools)),
ThinkingMode::Thinking
);
let mut ctk = Map::new();
ctk.insert("enable_thinking".into(), json!(true));
assert_eq!(
resolve_thinking_mode(Some(&ctk), None),
ThinkingMode::Thinking
);
assert_eq!(resolve_thinking_mode(None, None), ThinkingMode::Chat);
assert_eq!(resolve_thinking_mode(None, Some(&[])), ThinkingMode::Chat);
}
#[test]
fn an_unknown_thinking_mode_falls_back_to_chat() {
let mut ctk = Map::new();
ctk.insert("thinking_mode".into(), json!("ultra"));
assert_eq!(resolve_thinking_mode(Some(&ctk), None), ThinkingMode::Chat);
ctk.insert("thinking_mode".into(), json!("thinking"));
assert_eq!(
resolve_thinking_mode(Some(&ctk), None),
ThinkingMode::Thinking
);
}
#[test]
fn sanitizing_quantizes_in_place_and_drops_what_cannot_map() {
let p = profile(&[Effort::Low, Effort::XHigh], None);
let mut ctk = Map::new();
ctk.insert("reasoning_effort".into(), json!("high"));
assert_eq!(
sanitize_effort(&mut ctk, &p),
EffortMapping::Mapped(Effort::XHigh)
);
assert_eq!(ctk["reasoning_effort"], json!("xhigh"));
ctk.insert("reasoning_effort".into(), json!("low"));
assert_eq!(sanitize_effort(&mut ctk, &p), EffortMapping::Unchanged);
ctk.insert("reasoning_effort".into(), json!("medium"));
assert_eq!(sanitize_effort(&mut ctk, &p), EffortMapping::Dropped);
assert!(!ctk.contains_key("reasoning_effort"));
let mut bare = Map::new();
assert_eq!(sanitize_effort(&mut bare, &p), EffortMapping::Unchanged);
assert!(bare.is_empty());
}
#[test]
fn the_effort_is_broadcast_but_an_explicit_spelling_wins() {
let mut ctk = Map::new();
ctk.insert("reasoning_effort".into(), json!("high"));
broadcast_effort_spellings(&mut ctk);
assert_eq!(ctk["reasoning_strength"], json!("high"));
let mut explicit = Map::new();
explicit.insert("reasoning_effort".into(), json!("high"));
explicit.insert("reasoning_strength".into(), json!("low"));
broadcast_effort_spellings(&mut explicit);
assert_eq!(explicit["reasoning_strength"], json!("low"));
}
#[test]
fn a_template_with_no_toggle_defaults_to_on() {
let p = probe_thinking_profile(
|_kwargs, _tools| Ok::<_, ()>("same".to_string()),
EffortProfile::inert(),
);
assert!(!p.toggleable);
assert_eq!(p.default_state, ThinkingState::On);
}
fn thinking_profile(
toggleable: bool,
has_adaptive: bool,
default_state: ThinkingState,
efforts: EffortProfile,
) -> ThinkingProfile {
ThinkingProfile {
efforts,
toggleable,
has_adaptive,
default_state,
}
}
#[test]
fn gears_are_built_least_thinking_first() {
let gears = derive_think_gears(
&thinking_profile(
true,
true,
ThinkingState::Off,
profile(&[Effort::Low, Effort::Medium, Effort::High], None),
),
false,
);
assert_eq!(
gears.supported,
["off", "adaptive", "low", "medium", "high"]
);
assert_eq!(gears.default.as_deref(), Some("off"));
}
#[test]
fn a_toggle_with_no_ladder_offers_a_bare_on() {
let gears = derive_think_gears(
&thinking_profile(true, false, ThinkingState::On, EffortProfile::inert()),
false,
);
assert_eq!(gears.supported, ["off", "on"]);
assert_eq!(gears.default.as_deref(), Some("on"));
}
#[test]
fn a_checkpoint_that_grades_nothing_advertises_nothing() {
let gears = derive_think_gears(
&thinking_profile(false, false, ThinkingState::On, EffortProfile::inert()),
false,
);
assert!(gears.is_empty());
assert_eq!(gears.default, None);
}
#[test]
fn the_probed_effort_default_wins_when_the_bare_render_is_thinking() {
let gears = derive_think_gears(
&thinking_profile(
false,
false,
ThinkingState::On,
profile(
&[Effort::Low, Effort::Medium, Effort::High],
Some(Effort::High),
),
),
false,
);
assert_eq!(gears.supported, ["low", "medium", "high"]);
assert_eq!(gears.default.as_deref(), Some("high"));
}
#[test]
fn a_ladder_with_no_stated_default_falls_back_to_medium_then_to_its_top() {
let with_medium = derive_think_gears(
&thinking_profile(
false,
false,
ThinkingState::On,
profile(&[Effort::Low, Effort::Medium, Effort::High], None),
),
false,
);
assert_eq!(with_medium.default.as_deref(), Some("medium"));
let without = derive_think_gears(
&thinking_profile(
false,
false,
ThinkingState::On,
profile(&[Effort::Low, Effort::XHigh], None),
),
false,
);
assert_eq!(without.default.as_deref(), Some("xhigh"));
}
#[test]
fn every_advertised_gear_carries_the_kwargs_that_select_it() {
let gears = derive_think_gears(
&thinking_profile(
true,
true,
ThinkingState::Off,
profile(&[Effort::Low, Effort::High], None),
),
false,
);
assert_eq!(gears.supported, ["off", "adaptive", "low", "high"]);
for gear in &gears.supported {
assert!(gears.kwargs_for(gear).is_some(), "{gear} has no kwargs");
}
assert_eq!(
gears.kwargs_for("off").unwrap()["enable_thinking"],
json!(false)
);
let high = gears.kwargs_for("high").unwrap();
assert_eq!(high["reasoning_effort"], json!("high"));
assert_eq!(high["enable_thinking"], json!(true));
}
#[test]
fn a_gear_on_an_untoggleable_template_carries_only_the_effort() {
let gears = derive_think_gears(
&thinking_profile(
false,
false,
ThinkingState::On,
profile(&[Effort::Low, Effort::High], None),
),
false,
);
let low = gears.kwargs_for("low").unwrap();
assert_eq!(low.len(), 1);
assert_eq!(low["reasoning_effort"], json!("low"));
}
#[test]
fn an_always_thinking_family_with_no_knob_still_advertises_its_state() {
let profile = thinking_profile(false, false, ThinkingState::On, EffortProfile::inert());
let unparsed = derive_think_gears(&profile, false);
assert!(unparsed.is_empty(), "nothing reasons and nothing is parsed");
let parsed = derive_think_gears(&profile, true);
assert_eq!(parsed.supported, ["on"]);
assert_eq!(parsed.default.as_deref(), Some("on"));
assert!(parsed.kwargs_for("on").unwrap().is_empty());
}
#[test]
fn the_default_is_always_a_member_of_the_advertised_list() {
let gears = derive_think_gears(
&thinking_profile(
false,
false,
ThinkingState::Adaptive,
profile(&[Effort::Low, Effort::Medium], None),
),
false,
);
assert!(!gears.supported.contains(&"adaptive".to_string()));
assert_eq!(gears.default.as_deref(), Some("medium"));
assert!(gears
.default
.as_ref()
.is_some_and(|d| gears.supported.contains(d)));
}
}