use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::model::AiProviderConfig;
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct AiConfig {
#[serde(default)]
pub default_provider: String,
#[serde(default)]
pub default_max_output_tokens: Option<u32>,
#[serde(default)]
pub sampling: SamplingConfig,
#[serde(default)]
pub providers: HashMap<String, AiProviderConfig>,
#[serde(default)]
pub mcp: McpConfig,
#[serde(default)]
pub history: HistoryConfig,
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub struct SamplingConfig {
#[serde(default)]
pub enable_smart_routing: bool,
#[serde(default)]
pub fallback_enabled: bool,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct McpConfig {
#[serde(default)]
pub auto_discover: bool,
#[serde(default = "default_mcp_resilience")]
pub resilience: ResilienceSettings,
}
impl Default for McpConfig {
fn default() -> Self {
Self {
auto_discover: false,
resilience: default_mcp_resilience(),
}
}
}
fn default_mcp_resilience() -> ResilienceSettings {
ResilienceSettings {
request_timeout_ms: 30_000,
connect_timeout_ms: 5_000,
..ResilienceSettings::default()
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct ResilienceSettings {
#[serde(default = "default_request_timeout")]
pub request_timeout_ms: u64,
#[serde(default = "default_resilience_connect_timeout")]
pub connect_timeout_ms: u64,
#[serde(default = "default_stream_idle_timeout")]
pub stream_idle_timeout_ms: u64,
#[serde(default = "default_retry_attempts")]
pub retry_attempts: u32,
#[serde(default = "default_retry_base_delay")]
pub retry_base_delay_ms: u64,
#[serde(default = "default_retry_max_delay")]
pub retry_max_delay_ms: u64,
#[serde(default = "default_breaker_threshold")]
pub breaker_failure_threshold: u32,
#[serde(default = "default_breaker_cooldown")]
pub breaker_open_cooldown_ms: u64,
#[serde(default = "default_half_open_probes")]
pub breaker_half_open_probes: u32,
#[serde(default = "default_max_concurrent")]
pub max_concurrent: usize,
}
impl Default for ResilienceSettings {
fn default() -> Self {
Self {
request_timeout_ms: default_request_timeout(),
connect_timeout_ms: default_resilience_connect_timeout(),
stream_idle_timeout_ms: default_stream_idle_timeout(),
retry_attempts: default_retry_attempts(),
retry_base_delay_ms: default_retry_base_delay(),
retry_max_delay_ms: default_retry_max_delay(),
breaker_failure_threshold: default_breaker_threshold(),
breaker_open_cooldown_ms: default_breaker_cooldown(),
breaker_half_open_probes: default_half_open_probes(),
max_concurrent: default_max_concurrent(),
}
}
}
const fn default_request_timeout() -> u64 {
60_000
}
const fn default_resilience_connect_timeout() -> u64 {
10_000
}
const fn default_stream_idle_timeout() -> u64 {
60_000
}
const fn default_retry_attempts() -> u32 {
3
}
const fn default_retry_base_delay() -> u64 {
200
}
const fn default_retry_max_delay() -> u64 {
10_000
}
const fn default_breaker_threshold() -> u32 {
5
}
const fn default_breaker_cooldown() -> u64 {
30_000
}
const fn default_half_open_probes() -> u32 {
1
}
const fn default_max_concurrent() -> usize {
16
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct HistoryConfig {
#[serde(default = "default_retention_days")]
pub retention_days: u32,
#[serde(default)]
pub log_tool_executions: bool,
}
impl Default for HistoryConfig {
fn default() -> Self {
Self {
retention_days: default_retention_days(),
log_tool_executions: false,
}
}
}
const fn default_retention_days() -> u32 {
30
}