use agent_client_protocol::{
schema::v1::{
SessionConfigOption, SessionConfigOptionCategory, SessionConfigSelectOption,
SetSessionConfigOptionRequest,
},
Error as AcpError,
};
use rho_providers::providers::fast_mode::{supports_fast_mode, GROK_4_7};
use rho_sdk::model::ServiceTier;
use super::{config_options::CurrentModel, host_features::Toggles};
pub(super) const FAST_MODE_ID: &str = "fast_mode";
const ON: &str = "on";
const OFF: &str = "off";
pub(super) fn config_options(
current: &CurrentModel,
service_tier: Option<ServiceTier>,
toggles: Toggles,
) -> Vec<SessionConfigOption> {
if !supports_fast_mode(¤t.provider, ¤t.model, ¤t.auth) {
return Vec::new();
}
let fast = is_fast(service_tier);
let option = match toggles {
Toggles::Boolean => SessionConfigOption::boolean(FAST_MODE_ID, "Fast mode", fast),
Toggles::Select => SessionConfigOption::select(
FAST_MODE_ID,
"Fast mode",
if fast { ON } else { OFF },
vec![
SessionConfigSelectOption::new(OFF, "Normal"),
SessionConfigSelectOption::new(ON, "Fast"),
],
),
};
vec![option
.description("Faster responses at a higher credit rate.")
.category(SessionConfigOptionCategory::ModelConfig)]
}
pub(super) fn parse_fast_mode_request(
request: &SetSessionConfigOptionRequest,
toggles: Toggles,
) -> Result<bool, AcpError> {
match toggles {
Toggles::Boolean => request
.value
.as_bool()
.ok_or_else(|| AcpError::invalid_params().data("fast_mode requires a boolean value")),
Toggles::Select => match request.value.as_value_id().map(|id| id.0.as_ref()) {
Some(ON) => Ok(true),
Some(OFF) => Ok(false),
Some(other) => {
Err(AcpError::invalid_params().data(format!("unknown fast_mode '{other}'")))
}
None => Err(AcpError::invalid_params().data("fast_mode requires a select value id")),
},
}
}
pub(super) fn apply_fast_mode(
session: &rho_sdk::Session,
current: &CurrentModel,
enabled: bool,
) -> Result<(), AcpError> {
if enabled && !supports_fast_mode(¤t.provider, ¤t.model, ¤t.auth) {
let message = if current.provider == "xai" && current.model == GROK_4_7 {
"fast mode for xai/grok-4.7 requires SpaceXAI OAuth".to_string()
} else {
format!(
"fast mode is not available for {}/{}",
current.provider, current.model
)
};
return Err(AcpError::invalid_params().data(message));
}
if enabled == is_fast(session.service_tier()) {
return Ok(());
}
session
.set_service_tier(enabled.then_some(ServiceTier::Priority))
.map_err(|error| super::agent::session_apply_error(session, error))
}
fn is_fast(service_tier: Option<ServiceTier>) -> bool {
service_tier == Some(ServiceTier::Priority)
}
#[cfg(test)]
#[path = "fast_mode_tests.rs"]
mod tests;