Skip to main content

systemprompt_models/validators/
rate_limits.rs

1use super::ValidationConfigProvider;
2use crate::config::RateLimitConfig;
3use systemprompt_traits::validation_report::{ValidationReport, ValidationWarning};
4use systemprompt_traits::{ConfigProvider, DomainConfig, DomainConfigError};
5
6#[derive(Debug, Default, Clone, Copy)]
7pub struct RateLimitsConfigValidator {
8    config: Option<RateLimitConfig>,
9}
10
11impl RateLimitsConfigValidator {
12    pub fn new() -> Self {
13        Self::default()
14    }
15}
16
17impl DomainConfig for RateLimitsConfigValidator {
18    fn domain_id(&self) -> &'static str {
19        "rate_limits"
20    }
21
22    fn priority(&self) -> u32 {
23        10
24    }
25
26    fn load(&mut self, config: &dyn ConfigProvider) -> Result<(), DomainConfigError> {
27        let provider = config
28            .as_any()
29            .downcast_ref::<ValidationConfigProvider>()
30            .ok_or_else(|| DomainConfigError::LoadError {
31                message: "Expected ValidationConfigProvider".into(),
32            })?;
33
34        self.config = Some(provider.config().rate_limits);
35        Ok(())
36    }
37
38    fn validate(&self) -> Result<ValidationReport, DomainConfigError> {
39        let mut report = ValidationReport::new("rate_limits");
40        let config = self
41            .config
42            .as_ref()
43            .ok_or_else(|| DomainConfigError::ValidationError {
44                message: "Not loaded".into(),
45            })?;
46
47        if config.disabled {
48            return Ok(report);
49        }
50
51        Self::validate_stream_limits(&mut report, config);
52        Self::validate_tier_multipliers(&mut report, config);
53        Self::validate_agent_limits(&mut report, config);
54
55        Ok(report)
56    }
57}
58
59impl RateLimitsConfigValidator {
60    fn validate_stream_limits(report: &mut ValidationReport, config: &RateLimitConfig) {
61        if config.stream_per_second < 10 {
62            report.add_warning(
63                ValidationWarning::new(
64                    "rate_limits.stream_per_second",
65                    format!(
66                        "stream_per_second={} is restrictive. Users may experience connection \
67                         issues.",
68                        config.stream_per_second
69                    ),
70                )
71                .with_suggestion("Consider increasing to at least 10 for production use"),
72            );
73        }
74    }
75
76    fn validate_tier_multipliers(report: &mut ValidationReport, config: &RateLimitConfig) {
77        if config.tier_multipliers.anon < 0.3 {
78            report.add_warning(
79                ValidationWarning::new(
80                    "rate_limits.tier_multipliers.anon",
81                    format!(
82                        "tier_multipliers.anon={} severely limits anonymous users.",
83                        config.tier_multipliers.anon
84                    ),
85                )
86                .with_suggestion("Consider at least 0.3 for basic anonymous access"),
87            );
88        }
89
90        if config.tier_multipliers.user < 0.5 {
91            report.add_warning(
92                ValidationWarning::new(
93                    "rate_limits.tier_multipliers.user",
94                    format!(
95                        "tier_multipliers.user={} restricts authenticated users below baseline.",
96                        config.tier_multipliers.user
97                    ),
98                )
99                .with_suggestion("User tier multiplier should typically be 1.0 or higher"),
100            );
101        }
102    }
103
104    fn validate_agent_limits(report: &mut ValidationReport, config: &RateLimitConfig) {
105        if config.agents_per_second < 5 {
106            report.add_warning(
107                ValidationWarning::new(
108                    "rate_limits.agents_per_second",
109                    format!(
110                        "agents_per_second={} may cause agent timeouts under load.",
111                        config.agents_per_second
112                    ),
113                )
114                .with_suggestion("Consider at least 10 for stable agent operations"),
115            );
116        }
117
118        if config.contexts_per_second < 20 {
119            report.add_warning(
120                ValidationWarning::new(
121                    "rate_limits.contexts_per_second",
122                    format!(
123                        "contexts_per_second={} may slow down conversation operations.",
124                        config.contexts_per_second
125                    ),
126                )
127                .with_suggestion("Consider at least 50 for responsive context management"),
128            );
129        }
130    }
131}