use crate::app::state::rest::AppStateRest; pub const EFFORT_LEVELS: &[&str] = &["low", "medium", "high", "xhigh", "max"]; /// Multiplier applied to the user's configured `max_tokens`, and the temperature to use, /// for each entry in `EFFORT_LEVELS` (same index). Higher effort trades a larger token /// budget for lower temperature (more deterministic, more room to reason/act). const MAX_TOKENS_MULTIPLIER: &[f32] = &[0.5, 1.0, 1.5, 2.0, 3.0]; const TEMPERATURE_OVERRIDE: &[f32] = &[0.9, 0.7, 0.5, 0.3, 0.1]; /// Maps an effort level index to the `(temperature, max_tokens)` pair that should be sent /// to the LLM, scaling the user's configured `max_tokens` by the level's multiplier. pub fn generation_params(level: usize, base_max_tokens: u32) -> (f32, u32) { let idx = level.min(EFFORT_LEVELS.len() - 1); let temperature = TEMPERATURE_OVERRIDE[idx]; let max_tokens = ((base_max_tokens as f32) * MAX_TOKENS_MULTIPLIER[idx]) as u32; (temperature, max_tokens.max(256)) } pub fn current_effort(state: &AppStateRest) -> usize { state.misc.effort_level.min(EFFORT_LEVELS.len() - 1) } pub fn current_effort_str(state: &AppStateRest) -> &'static str { let idx = current_effort(state); EFFORT_LEVELS[idx] } pub fn cycle_effort(state: &mut AppStateRest) { let current = current_effort(state); state.misc.effort_level = (current + 1) % EFFORT_LEVELS.len(); let label = current_effort_str(state); state.push_toast(crate::app::state::types::Toast::new( crate::app::state::types::ToastKind::Info, format!("Effort: {}", label), )); state.dirty = true; }