1use crate::circuit_breaker::CircuitBreakerConfig;
9use crate::error_handling::ErrorThresholds;
10use crate::rate_limiter::RateLimiterConfig;
11use std::time::Duration;
12
13#[derive(Clone, Debug, Default)]
20pub struct ConnectionOptions {
21 pub base_url: Option<String>,
22 pub proxy: Option<String>,
23 pub api_key: Option<String>,
24 pub timeout: Option<Duration>,
25 pub disable_proxy: bool,
26}
27
28impl ConnectionOptions {
31 pub fn hydrate_with_env(mut self, provider_env_prefix: &str) -> Self {
36 if self.api_key.is_none() {
38 let specific = format!("{}_API_KEY", provider_env_prefix);
39 self.api_key = std::env::var(&specific)
40 .ok()
41 .or_else(|| std::env::var("AI_API_KEY").ok());
42 }
43 if self.base_url.is_none() {
45 if let Ok(v) = std::env::var("AI_BASE_URL") {
46 self.base_url = Some(v);
47 }
48 }
49 if self.proxy.is_none() && !self.disable_proxy {
51 self.proxy = std::env::var("AI_PROXY_URL").ok();
52 }
53 if self.timeout.is_none() {
55 if let Ok(v) = std::env::var("AI_TIMEOUT_SECS") {
56 if let Ok(secs) = v.parse::<u64>() {
57 self.timeout = Some(Duration::from_secs(secs));
58 }
59 }
60 }
61 self
62 }
63}
64
65#[derive(Debug, Clone, Default)]
67pub struct ResilienceConfig {
68 pub circuit_breaker: Option<CircuitBreakerConfig>,
69 pub rate_limiter: Option<RateLimiterConfig>,
70 pub backpressure: Option<BackpressureConfig>,
71 pub error_handling: Option<ErrorHandlingConfig>,
72}
73
74#[derive(Debug, Clone)]
76pub struct BackpressureConfig {
77 pub max_concurrent_requests: usize,
78}
79
80#[derive(Debug, Clone)]
82pub struct ErrorHandlingConfig {
83 pub enable_recovery: bool,
84 pub enable_monitoring: bool,
85 pub error_thresholds: ErrorThresholds,
86}
87
88impl Default for BackpressureConfig {
91 fn default() -> Self {
92 Self {
93 max_concurrent_requests: 100,
94 }
95 }
96}
97
98impl Default for ErrorHandlingConfig {
99 fn default() -> Self {
100 Self {
101 enable_recovery: true,
102 enable_monitoring: true,
103 error_thresholds: ErrorThresholds::default(),
104 }
105 }
106}
107
108impl ResilienceConfig {
109 pub fn smart_defaults() -> Self {
111 Self {
112 circuit_breaker: Some(CircuitBreakerConfig::default()),
113 rate_limiter: Some(RateLimiterConfig::default()),
114 backpressure: Some(BackpressureConfig::default()),
115 error_handling: Some(ErrorHandlingConfig::default()),
116 }
117 }
118
119 pub fn production() -> Self {
121 Self {
122 circuit_breaker: Some(CircuitBreakerConfig::production()),
123 rate_limiter: Some(RateLimiterConfig::production()),
124 backpressure: Some(BackpressureConfig {
125 max_concurrent_requests: 50,
126 }),
127 error_handling: Some(ErrorHandlingConfig {
128 enable_recovery: true,
129 enable_monitoring: true,
130 error_thresholds: ErrorThresholds {
131 error_rate_threshold: 0.05, consecutive_errors: 3,
133 time_window: Duration::from_secs(30),
134 },
135 }),
136 }
137 }
138
139 pub fn development() -> Self {
141 Self {
142 circuit_breaker: Some(CircuitBreakerConfig::development()),
143 rate_limiter: Some(RateLimiterConfig::development()),
144 backpressure: Some(BackpressureConfig {
145 max_concurrent_requests: 200,
146 }),
147 error_handling: Some(ErrorHandlingConfig {
148 enable_recovery: false,
149 enable_monitoring: false,
150 error_thresholds: ErrorThresholds::default(),
151 }),
152 }
153 }
154}