use rho_providers::{model::ReasoningCapabilities, reasoning::ReasoningLevel};
use crate::{
agent::{internal_agent_reasoning_capabilities, ADVISOR_AGENT_ID},
tools::advisor::advisor_effective_reasoning,
};
use super::{
advisor_command::AdvisorRuntime, App, ComposerMode, PickerBadge, PickerBadgeTone, PickerItem,
UiPicker,
};
pub(super) fn offered_reasoning_levels(
capabilities: &ReasoningCapabilities,
) -> Option<&[ReasoningLevel]> {
capabilities.levels().filter(|levels| levels.len() > 1)
}
fn advisor_reasoning_picker(levels: &[ReasoningLevel], current: ReasoningLevel) -> UiPicker {
let items = levels
.iter()
.map(|level| PickerItem {
badge: (*level == current).then(|| PickerBadge {
text: "selected".into(),
tone: PickerBadgeTone::Selected,
}),
..PickerItem::new(level.to_string(), level.to_string())
})
.collect();
let mut picker =
UiPicker::advisor_reasoning(format!("select reasoning for {ADVISOR_AGENT_ID}"), items);
picker.selected = levels
.iter()
.position(|level| *level == current)
.unwrap_or(0);
picker
}
impl App {
pub(super) fn open_advisor_reasoning_picker(&mut self) -> bool {
let Some(selection) = self.info.runtime.internal_agents.get(ADVISOR_AGENT_ID) else {
return false;
};
let capabilities = internal_agent_reasoning_capabilities(selection);
let Some(levels) = offered_reasoning_levels(&capabilities) else {
return false;
};
let picker = advisor_reasoning_picker(levels, advisor_effective_reasoning(selection));
self.input_ui.set_composer(ComposerMode::Picker(picker));
true
}
pub(super) async fn commit_advisor_reasoning(
&mut self,
value: &str,
agent: &mut impl AdvisorRuntime,
) -> anyhow::Result<()> {
let Ok(reasoning) = value.parse::<ReasoningLevel>() else {
return Ok(());
};
self.apply_advisor_reasoning(reasoning, agent).await
}
pub(super) async fn apply_advisor_reasoning(
&mut self,
reasoning: ReasoningLevel,
agent: &mut impl AdvisorRuntime,
) -> anyhow::Result<()> {
self.set_advisor_reasoning(reasoning)?;
if self.info.runtime.advisor_mode {
self.sync_advisor_runtime(agent).await;
}
Ok(())
}
pub(super) fn report_advisor_reasoning_unchanged(&mut self) {
let status = match self.info.runtime.internal_agents.get(ADVISOR_AGENT_ID) {
Some(selection) => format!(
"advisor reasoning unchanged: {}",
advisor_effective_reasoning(selection)
),
None => "advisor reasoning unchanged".into(),
};
self.set_status(status);
}
}
#[cfg(test)]
#[path = "advisor_reasoning_tests.rs"]
mod tests;