Middleware
Middleware is how you add cross-cutting behavior to the kernel without touching it: logging, retries, permission gates, compaction. A middleware is an added layer around the turn loop — the kernel folds your layers into the classic onion, so each one sees the call on the way in and the result on the way out. Permissions and compaction in lite-agent are themselves just middleware, which proves the seam: anything they do, your own layer can do too.
Usage
Pass middleware via use in createAgent:
The Middleware interface
A Middleware can implement lifecycle hooks and two wrappers:
AgentContext is the only handle middleware gets: sessionId, mutable messages, turn, signal, emit, a shared state map, and recordSessionEvent for persisting custom facts. No globals.
The onion model: fold order
composeModelCall and composeToolCall fold the middleware array around the base call with reduceRight — array order is outer → inner. Given use: [a, b], a model call flows a → b → provider → b → a. runLifecycle simply runs each hook in array order.
The first middleware in the array is the outermost layer — it sees the call first on the way in and last on the way out.
Built-in middleware
Permission is just a middleware. Nothing about gating is hard-coded in the kernel; you can reorder, replace, or drop any of these layers like any other.
See also
- The kernel — where hooks fire and wrappers wrap in the loop.
- Strategies —
PermissionPolicy,ApprovalHandler,Compactorand friends. - Context compaction — the compaction middleware and compactor toolkit.
- Events — what middleware can observe and emit via
ctx.emit.