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(|| 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}