Skip to main content

systemprompt_models/validators/
rate_limits.rs

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