nooa-middleware-hooks
Installation
SKILL.md
Middleware and Hooks
Three interception surfaces, one decision rule:
| Surface | Registration | Can it change behavior? | Errors | Scope |
|---|---|---|---|---|
| Middleware | agent.event_manager.intercept(kind, fn) |
YES — transform inputs/outputs, short-circuit, block | propagate (a guardrail raising aborts the call) | per-agent |
| Observers | agent.event_manager.on(event_type, fn) |
no — fire-and-forget after the event is recorded | isolated | per-agent |
| InstrumentationHooks | set_hooks(obj) (nooa.runtime.hooks) |
no — observational timing/tracing pairs | swallowed + logged, overhead metered | one global slot per async context |
Rule of thumb: enforcing or transforming → intercept(); reacting → on(); building an observability backend → you probably want a tracing exporter (nooa-capturing-traces), not raw hooks — the tracing system already occupies the hooks slot.
Middleware (intercept)
Each middleware is async def mw(ctx, nxt) -> ctx — a typed context object and a nxt callable running the rest of the chain. Three kinds (nooa.runtime.middleware):