# mailrs-intelligence
[](https://crates.io/crates/mailrs-intelligence)
[](https://docs.rs/mailrs-intelligence)
[](#license)
[](https://crates.io/crates/mailrs-intelligence)
LLM-powered email analysis primitives for Rust — pluggable provider, OpenAI-compatible reference impl, with no-LLM heuristics included.
Extracted from [mailrs] so any Rust project that needs to classify, summarize, or embed email content can lean on the same primitives without dragging in the entire mail server.
## Highlights
- **Pluggable backend** — `LlmProvider` trait keeps the choice of model visible at the call site, so small-core vs big-core decisions stay grep-auditable in your own code.
- **OpenAI-compatible reference impl** — `OpenAiCompatibleProvider` wraps `reqwest` and works against any service speaking the standard `{system, messages, temperature}` shape (self-hosted vLLM, llama.cpp servers, etc.).
- **Five primitives, one shape** — full email analysis (`analyze::analyze_email`), spam classification with optional cache (`spam::classify`), structured-data extraction from JSON-LD (`structured::extract_structured_data`), heuristic importance scoring (`importance::calculate_importance`), and embeddings via the provider's `embed` method.
- **No-LLM modules** — `importance` and `structured` are pure heuristics — they don't need a provider, network, or async runtime.
- **Optional Redis cache** — `KevySpamCache` is included behind the default `kevy-cache` feature, but `SpamCache` is a trait so you can plug in whatever store you have.
## Quick start
```rust
use std::sync::Arc;
use mailrs_intelligence::{
OpenAiCompatibleProvider,
analyze::{analyze_email, PROMPT_VERSION},
importance::{calculate_importance, ImportanceSignals},
LlmProvider,
};
# async fn run() -> Option<()> {
let provider: Arc<dyn LlmProvider> = Arc::new(OpenAiCompatibleProvider::new(
"https://llm.example.com/complete".into(),
Some("sk-…".into()),
format!("qwen3.5-9b/{PROMPT_VERSION}"),
));
// LLM-powered full analysis
let analysis = analyze_email(
provider.as_ref(),
"boss@example.com",
"Q3 review",
"Please send your Q3 self-review by Friday.",
)
.await?;
println!("category={} requires_action={}", analysis.category, analysis.requires_action);
// No-LLM heuristic importance
let (level, score) = calculate_importance(&ImportanceSignals {
is_mutual_contact: true,
is_reply_to_my_email: true,
has_action_items: analysis.requires_action,
..Default::default()
});
println!("importance={} score={:.2}", level.as_str(), score);
# Some(())
# }
```
## Feature flags
| Flag | Default | What it enables |
|------|---------|-----------------|
| `http` | yes | `OpenAiCompatibleProvider` (reqwest + rustls). Disable if you supply your own `LlmProvider`. |
| `kevy-cache` | yes | `KevySpamCache` for `spam::classify`. Disable if you cache yourself or run without a cache. |
Disable both default features (`default-features = false`) if you're plugging in your own backends:
```toml
[dependencies]
mailrs-intelligence = { version = "1", default-features = false }
async-trait = "0.1"
```
## Why a trait
Production mail servers tend to mix cheap inference (per-message spam classification, hot path) with rarer expensive calls (deep structured extraction, big context). Letting analysis functions take `&dyn LlmProvider` keeps the choice of model **visible at the call site** — you can grep your own code for "which provider does this path hand into `analyze_email`?" without diving into config or environment variables. That visibility is the whole point of carving the trait out instead of shipping the concrete config struct.
<!-- AUDIT-FOOTER:BEGIN -->
## Stone audit (v3 cycle, 2026-05-25)
| Axis | Status |
|---|---|
| **doc** | ✅ clean (`cargo doc --no-deps -p mailrs-intelligence`) |
| **test** | line cov: 92.2% (`cargo llvm-cov -p mailrs-intelligence --summary-only`) |
| **bench** | ✅ 1 file(s) criterion + ✅ 2 gate(s) `perf_gate.rs` |
| **size** | release rlib: 1.4 MB |
| **fuzz** | ❌ none |
| **mem** | dhat profile pending (v3.4 backlog) |
### Competitor comparisons
- Searched crates.io + competing impls: see PERFORMANCE.md or 'first-in-Rust' marker.
<!-- AUDIT-FOOTER:END -->
## License
Licensed under either of [Apache License 2.0](LICENSE-APACHE) or [MIT license](LICENSE-MIT) at your option.
[mailrs]: https://github.com/goliajp/mailrs
## Performance
Criterion benches: `cargo bench -p mailrs-intelligence`. Per-bench medians + regression budgets are documented in [`BUDGETS.md`](BUDGETS.md) (this crate) and the workspace [`PERFORMANCE.md`](../../PERFORMANCE.md).