systemprompt_models/validators/
rate_limits.rs1use 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(|| {
31 DomainConfigError::LoadError("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("Not loaded".into()))?;
44
45 if config.disabled {
46 return Ok(report);
47 }
48
49 Self::validate_stream_limits(&mut report, config);
50 Self::validate_tier_multipliers(&mut report, config);
51 Self::validate_agent_limits(&mut report, config);
52
53 Ok(report)
54 }
55}
56
57impl RateLimitsConfigValidator {
58 fn validate_stream_limits(report: &mut ValidationReport, config: &RateLimitConfig) {
59 if config.stream_per_second < 10 {
60 report.add_warning(
61 ValidationWarning::new(
62 "rate_limits.stream_per_second",
63 format!(
64 "stream_per_second={} is restrictive. Users may experience connection \
65 issues.",
66 config.stream_per_second
67 ),
68 )
69 .with_suggestion("Consider increasing to at least 10 for production use"),
70 );
71 }
72 }
73
74 fn validate_tier_multipliers(report: &mut ValidationReport, config: &RateLimitConfig) {
75 if config.tier_multipliers.anon < 0.3 {
76 report.add_warning(
77 ValidationWarning::new(
78 "rate_limits.tier_multipliers.anon",
79 format!(
80 "tier_multipliers.anon={} severely limits anonymous users.",
81 config.tier_multipliers.anon
82 ),
83 )
84 .with_suggestion("Consider at least 0.3 for basic anonymous access"),
85 );
86 }
87
88 if config.tier_multipliers.user < 0.5 {
89 report.add_warning(
90 ValidationWarning::new(
91 "rate_limits.tier_multipliers.user",
92 format!(
93 "tier_multipliers.user={} restricts authenticated users below baseline.",
94 config.tier_multipliers.user
95 ),
96 )
97 .with_suggestion("User tier multiplier should typically be 1.0 or higher"),
98 );
99 }
100 }
101
102 fn validate_agent_limits(report: &mut ValidationReport, config: &RateLimitConfig) {
103 if config.agents_per_second < 5 {
104 report.add_warning(
105 ValidationWarning::new(
106 "rate_limits.agents_per_second",
107 format!(
108 "agents_per_second={} may cause agent timeouts under load.",
109 config.agents_per_second
110 ),
111 )
112 .with_suggestion("Consider at least 10 for stable agent operations"),
113 );
114 }
115
116 if config.contexts_per_second < 20 {
117 report.add_warning(
118 ValidationWarning::new(
119 "rate_limits.contexts_per_second",
120 format!(
121 "contexts_per_second={} may slow down conversation operations.",
122 config.contexts_per_second
123 ),
124 )
125 .with_suggestion("Consider at least 50 for responsive context management"),
126 );
127 }
128 }
129}