Client calls — retry, fallback, rate limits, redaction, prompt caching, planning, summarization. Each middleware wraps a Client and runs on every chat call. Multiple middlewares compose into a MiddlewarePipeline.
How it works
A middleware implementscognis::middleware::Middleware, a trait with one async method (call) that receives a MiddlewareCtx and an Arc<dyn Next>. The pipeline runs them in reverse-push order — the most-recently-pushed layer is the outermost wrapper.
RegexRedactor::call runs first, then ModelRetry::call, then the raw client. Push order is “innermost first.”
Middleware is not auto-wired into
AgentBuilder in v0.3. To run middleware inside an agent loop, wrap your client into a PipelinedClient and serve it through a custom LLMProvider — see Wiring middleware into an agent below.What’s in the box
The full catalog undercognis::middleware::*. Reach for these by job:
Resilience
Rate and cost
Privacy
Prompt and context
Planning and todos
Tools
For tool-call gating (require human approval before specific tools run), use
Approver + AgentBuilder::with_approver, not middleware. See Human-in-the-loop.
Workspace and subagents
Quick example — production stack
A reasonable defaults stack for a customer-facing client:Wiring middleware into an agent
AgentBuilder accepts a raw Client; it doesn’t take a PipelinedClient directly. Two ways to bridge:
Option 1 — PipelinedClient standalone, for code that calls the model directly without the agent harness:
LLMProvider that delegates to the pipeline. Wrap that provider into a Client, then hand it to AgentBuilder:
Writing your own middleware
The trait is small:See also
Production → Resilience
Patterns for
ModelRetry, ModelFallback, and Recovery.Production → Security
PII redaction, deny-lists, SSRF protection.
Human-in-the-loop
Approval-gated tools — different from middleware.
Reference → cognis
Full middleware re-export list.