systemprompt_models/validators/
rate_limits.rs1use 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}