magi-code 0.77.1

Repository-aware CLI coding agent for terminal work
Documentation
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::time::Duration;

use super::helpers::is_false;

use crate::thinking::ThinkingLevel;

#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct ProviderStreamSettings {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub semantic_progress_timeout_seconds: Option<u64>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub subagent_semantic_progress_timeout_seconds: Option<u64>,
}

pub const DEFAULT_PROVIDER_STREAM_SEMANTIC_PROGRESS_TIMEOUT_SECONDS: u64 = 60;
pub const DEFAULT_SUBAGENT_STREAM_SEMANTIC_PROGRESS_TIMEOUT_SECONDS: u64 = 120;
pub const MAX_PROVIDER_STREAM_SEMANTIC_PROGRESS_TIMEOUT_SECONDS: u64 = 600;

impl ProviderStreamSettings {
    pub(crate) fn is_default(&self) -> bool {
        self == &Self::default()
    }

    pub(crate) fn semantic_progress_timeout(&self) -> Duration {
        Duration::from_secs(
            self.semantic_progress_timeout_seconds
                .unwrap_or(DEFAULT_PROVIDER_STREAM_SEMANTIC_PROGRESS_TIMEOUT_SECONDS),
        )
    }

    pub(crate) fn subagent_semantic_progress_timeout(&self) -> Duration {
        Duration::from_secs(
            self.subagent_semantic_progress_timeout_seconds
                .unwrap_or(DEFAULT_SUBAGENT_STREAM_SEMANTIC_PROGRESS_TIMEOUT_SECONDS),
        )
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct TtsrSettings {
    #[serde(default, skip_serializing_if = "is_false")]
    pub enabled: bool,
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub rules: Vec<TtsrRuleSetting>,
}

impl TtsrSettings {
    pub(crate) fn is_default(&self) -> bool {
        self == &Self::default()
    }
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct TtsrRuleSetting {
    pub pattern: String,
    pub reminder: String,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
pub struct SelectedModelSettings {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub provider: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub model: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub thinking_level: Option<ThinkingLevel>,
    #[serde(default, flatten)]
    pub(crate) extra: std::collections::BTreeMap<String, serde_json::Value>,
}

impl SelectedModelSettings {
    pub(crate) fn is_default(&self) -> bool {
        self == &Self::default()
    }
}