magi-code 0.96.1

Repository-aware CLI coding agent for terminal work
Documentation
use super::*;

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct ModelPickerState {
    pub(crate) entries: Vec<crate::model_catalog::ModelCatalogEntry>,
    pub(crate) selected: usize,
    pub(crate) current_model_id: String,
    pub(crate) notice: Option<String>,
}

impl ModelPickerState {
    pub(in crate::tui::state) fn clamp(&mut self) {
        let item_count = self.entries.len();
        clamp_picker_selection(&mut self.selected, item_count);
    }
}

impl MissionControlState {
    pub(crate) fn open_model_picker(
        &mut self,
        entries: Vec<crate::model_catalog::ModelCatalogEntry>,
        disabled_ids: std::collections::BTreeSet<String>,
        notice: Option<String>,
        _visible_rows: usize,
    ) {
        let current_model_id = format!("{}/{}", self.provider, self.model);
        let entries = entries
            .into_iter()
            .filter(|entry| !disabled_ids.contains(&entry.id))
            .collect::<Vec<_>>();
        let selected = entries
            .iter()
            .position(|entry| entry.id == current_model_id)
            .unwrap_or(0);
        let mut picker = ModelPickerState {
            entries,
            selected,
            current_model_id,
            notice,
        };
        picker.clamp();
        self.modals.model_picker = Some(picker);
        self.set_scroll_offset(&self.scroll_views.model_picker, 0);
        self.hide_autocomplete();
    }

    pub(crate) fn close_model_picker(&mut self) -> bool {
        self.modals.model_picker.take().is_some()
    }

    pub(crate) fn model_picker_up(&mut self, visible_rows: usize) -> bool {
        self.move_model_picker(false, visible_rows)
    }

    pub(crate) fn model_picker_down(&mut self, visible_rows: usize) -> bool {
        self.move_model_picker(true, visible_rows)
    }

    pub(super) fn move_model_picker(&mut self, down: bool, visible_rows: usize) -> bool {
        let before_offset = self.scroll_offset(&self.scroll_views.model_picker);
        let (before_selected, selected, offset) = {
            let Some(picker) = self.modals.model_picker.as_mut() else {
                return false;
            };
            let before_selected = picker.selected;
            let (selected, offset) = picker_selection_after_move(
                picker.selected,
                picker.entries.len(),
                1,
                down,
                visible_rows,
                before_offset,
            );
            picker.selected = selected;
            (before_selected, selected, offset)
        };
        self.set_scroll_offset(&self.scroll_views.model_picker, offset);
        before_selected != selected
            || before_offset != self.scroll_offset(&self.scroll_views.model_picker)
    }

    pub(crate) fn selected_model_picker_id(&self) -> Option<String> {
        self.modals
            .model_picker
            .as_ref()
            .and_then(|picker| picker.entries.get(picker.selected))
            .map(|entry| entry.id.clone())
    }
}