grate_limiter/lib.rs
1//! # grate-limiter
2//!
3//! Anticipatory rate-limit orchestration engine for multi-provider systems.
4//!
5//! **Predict limits before providers enforce them.**
6//!
7//! `grate-limiter` is not a retry library, proxy, or gateway. It is a predictive provider
8//! orchestration engine that routes traffic intelligently across providers by continuously
9//! learning their health, quota usage, and reliability — preventing rate-limit errors
10//! before they happen.
11//!
12//! # Quick Start
13//!
14//! ```rust
15//! use grate_limiter::{GrateLimiter, EngineConfig, ProviderConfig, CapabilityConfig};
16//! use grate_limiter::{QuotaConfig, Dimension, Window, CapabilityProvider};
17//! use grate_limiter::{Observation, Usage, Outcome, StatusClass};
18//!
19//! // Create the engine
20//! let engine = GrateLimiter::new(EngineConfig::default());
21//!
22//! // Register providers with their quotas
23//! engine.upsert_provider(ProviderConfig {
24//! name: "openai".into(),
25//! quotas: vec![
26//! QuotaConfig { dimension: Dimension::Requests, limit: 5000, window: Some(Window::Minute) },
27//! ],
28//! priority: 10,
29//! weight: 1.0,
30//! cooldown_seconds: 30,
31//! });
32//!
33//! engine.upsert_provider(ProviderConfig {
34//! name: "anthropic".into(),
35//! quotas: vec![
36//! QuotaConfig { dimension: Dimension::Requests, limit: 3000, window: Some(Window::Minute) },
37//! ],
38//! priority: 8,
39//! weight: 1.0,
40//! cooldown_seconds: 30,
41//! });
42//!
43//! // Register a capability with its providers
44//! engine.upsert_capability(CapabilityConfig {
45//! name: "chat-completion".into(),
46//! providers: vec![
47//! CapabilityProvider { provider: "openai".into(), priority: 10 },
48//! CapabilityProvider { provider: "anthropic".into(), priority: 8 },
49//! ],
50//! });
51//!
52//! // Select the best provider
53//! let decision = engine.select("chat-completion").unwrap();
54//! println!("Use: {} (score: {:.2})", decision.provider, decision.score);
55//!
56//! // Report what happened
57//! engine.observe(Observation {
58//! provider: "openai".into(),
59//! capability: Some("chat-completion".into()),
60//! usage: Usage { requests: 1, tokens: Some(1200), ..Default::default() },
61//! outcome: Outcome { status: StatusClass::Success, latency_ms: 830 },
62//! }).unwrap();
63//! ```
64//!
65//! # Architecture
66//!
67//! The engine has four major subsystems:
68//!
69//! - **Quota Tracking**: Token bucket / sliding window / fixed window / concurrency strategies
70//! - **Health Engine**: EWMA-based scoring with exponential decay and automatic cooldowns
71//! - **Scoring Engine**: Weighted composite scoring with anticipatory exhaustion prediction
72//! - **Decision Engine**: Deterministic, explainable provider selection
73//!
74//! # Deterministic Testing
75//!
76//! Use [`MockClock`] for fully deterministic, reproducible tests:
77//!
78//! ```rust
79//! use grate_limiter::{GrateLimiter, EngineConfig, MockClock};
80//! use std::sync::Arc;
81//!
82//! let clock = Arc::new(MockClock::new());
83//! let config = EngineConfig::default().with_clock(clock.clone());
84//! let engine = GrateLimiter::new(config);
85//!
86//! // Advance time deterministically
87//! clock.advance_ms(1000);
88//! ```
89
90mod capability;
91mod clock;
92mod config;
93mod decision;
94mod engine;
95mod error;
96mod health;
97mod metrics;
98mod observation;
99mod provider;
100mod quota;
101mod scoring;
102
103// Public API re-exports
104pub use capability::{CapabilityConfig, CapabilityProvider};
105pub use clock::{Clock, MockClock, RealClock, Timestamp};
106pub use config::EngineConfig;
107pub use decision::{Decision, ScoreBreakdown};
108pub use engine::GrateLimiter;
109pub use error::{Error, Result};
110pub use health::HealthConfig;
111pub use observation::{Observation, Outcome, StatusClass, Usage};
112pub use provider::ProviderConfig;
113pub use quota::{Dimension, QuotaConfig, Window};
114pub use scoring::{ScoringStrategy, ScoringWeights};