magi-code 0.96.1

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

#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct StoredFastObservation {
    pub(crate) run_order: Option<u64>,
    pub(crate) accept_sequence: u64,
    pub(crate) request_sequence: u64,
    pub(crate) requested_service_tier: String,
    pub(crate) outcome: crate::fast::FastOutcome,
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub(crate) enum FastDisplayState {
    #[default]
    Off,
    Unavailable,
    WillRequest,
    Confirmed,
    Different(String),
    Unconfirmed,
}

impl StoredFastObservation {
    pub(crate) fn to_fast_observation(&self) -> crate::fast::FastObservation {
        crate::fast::FastObservation {
            requested_service_tier: self.requested_service_tier.clone(),
            outcome: self.outcome.clone(),
            request_sequence: self.request_sequence,
            run_order: self.run_order,
        }
    }
}

impl FastDisplayState {
    pub(crate) fn resolve(
        enabled: bool,
        capability: &crate::fast::FastRequestState,
        observation: Option<&crate::fast::FastObservation>,
    ) -> Self {
        if !enabled {
            return Self::Off;
        }
        if capability
            .service_tier()
            .is_none_or(|service_tier| service_tier.trim().is_empty())
        {
            return Self::Unavailable;
        }
        let observation = observation.filter(|observation| {
            crate::fast::fast_observation_matches_request(observation, capability)
        });
        match observation.map(|observation| &observation.outcome) {
            Some(crate::fast::FastOutcome::Confirmed) => Self::Confirmed,
            Some(crate::fast::FastOutcome::Different(service_tier)) => {
                Self::Different(crate::fast::display_service_tier(service_tier))
            }
            Some(crate::fast::FastOutcome::Unconfirmed) => Self::Unconfirmed,
            Some(crate::fast::FastOutcome::NotRequested) | None => Self::WillRequest,
        }
    }
}

impl MissionControlState {
    pub(crate) fn refresh_fast_mode_state(
        &mut self,
        enabled: bool,
        capability: &crate::fast::FastRequestState,
    ) {
        let capable = capability
            .service_tier()
            .is_some_and(|service_tier| !service_tier.trim().is_empty());
        self.fast_mode_enabled = enabled;
        self.fast_mode_request_state = capability.clone();
        self.fast_mode_capable = capable;
        self.fast_mode_effective = enabled && capable;
    }

    pub(crate) fn set_fast_mode_enabled(&mut self, enabled: bool) {
        self.fast_mode_enabled = enabled;
        self.fast_mode_effective = enabled && self.fast_mode_capable;
    }

    pub(crate) fn selected_fast_observation(&self) -> Option<&StoredFastObservation> {
        let key = crate::fast::canonical_fast_observation_key(&self.provider, &self.model);
        self.fast_observations.get(&key)
    }

    pub(crate) fn fast_display_state(
        &self,
        enabled: bool,
        capability: &crate::fast::FastRequestState,
    ) -> FastDisplayState {
        let observation = self
            .selected_fast_observation()
            .map(StoredFastObservation::to_fast_observation);
        FastDisplayState::resolve(enabled, capability, observation.as_ref())
    }

    pub(crate) fn accept_fast_observation(
        &mut self,
        provider_id: &str,
        model: &str,
        requested_service_tier: &str,
        outcome: &crate::fast::FastOutcome,
        request_sequence: u64,
        run_order: Option<u64>,
    ) -> bool {
        // Child request sequences can collide; the parent assigns the arrival order.
        self.fast_observation_accept_sequence =
            self.fast_observation_accept_sequence.saturating_add(1);
        let accept_sequence = self.fast_observation_accept_sequence;
        let key = crate::fast::canonical_fast_observation_key(provider_id, model);
        let candidate_order = crate::fast::FastObservationOrder {
            run_order,
            accept_sequence,
        };
        let current_order =
            self.fast_observations
                .get(&key)
                .map(|stored| crate::fast::FastObservationOrder {
                    run_order: stored.run_order,
                    accept_sequence: stored.accept_sequence,
                });
        if crate::fast::compare_fast_observation_order(current_order, candidate_order)
            != std::cmp::Ordering::Greater
        {
            return false;
        }

        let observation = crate::fast::FastObservation {
            run_order,
            request_sequence,
            requested_service_tier: requested_service_tier.to_string(),
            outcome: outcome.clone(),
        };
        self.fast_observations.insert(
            key,
            StoredFastObservation {
                run_order,
                accept_sequence,
                request_sequence,
                requested_service_tier: requested_service_tier.to_string(),
                outcome: outcome.clone(),
            },
        );
        if let Some(warning) =
            crate::fast::fast_observation_warning(provider_id, model, &observation)
        {
            let warning = crate::output::sanitize_display_text(&warning);
            self.status = warning.clone();
            if self
                .fast_warning_keys
                .insert(crate::fast::canonical_fast_warning_key(
                    provider_id,
                    model,
                    &observation,
                ))
            {
                self.record_fast_warning_transcript(&warning);
            }
        }
        true
    }

    pub(crate) fn clear_fast_observations(&mut self) {
        self.fast_observations.clear();
        self.fast_warning_keys.clear();
    }

    pub(crate) fn fast_mode_rainbow_active(&self) -> bool {
        self.fast_mode_enabled
            && self.fast_mode_effective
            && self.color_enabled
            && !self.reduced_motion
            && self.provider_ready
            && (!self.provider.trim().is_empty() || !self.model.trim().is_empty())
    }
    pub(crate) fn advance_fast_mode_rainbow_phase(&mut self) -> bool {
        if !self.fast_mode_rainbow_active() {
            return false;
        }
        let palette_len = self.theme.fast_mode_rainbow_len();
        if palette_len == 0 {
            return false;
        }
        self.fast_mode_rainbow_phase = self.fast_mode_rainbow_phase.wrapping_add(1) % palette_len;
        true
    }
}