For the complete documentation index, see llms.txt. This page is also available as Markdown.

Middleware

Attaching middleware to an agent and the agent-specific lifecycle it participates in — full hook/result/built-in reference lives on the main Middleware page.

Since BoxLang AI v3.0+. This page covers attaching middleware to an agent specifically. For the full hook list, the complete AiMiddlewareResult vocabulary, and one page per middleware class, see Middleware Overview.

Adding Middleware to an Agent

Pass an array of middleware instances (or struct-based inline middleware) to aiAgent():

agent = aiAgent(
    name      : "SafeAgent",
    middleware: [
        new LoggingMiddleware(),
        new RetryMiddleware( maxRetries: 3 ),
        new GuardrailMiddleware( blockedTools: [ "deleteRecord" ] )
    ]
)

Or attach after construction with the fluent API:

agent = aiAgent( name: "Assistant" )
    .withMiddleware( new LoggingMiddleware() )
    .withMiddleware( new RetryMiddleware() )

Middleware fires in order on inbound hooks (beforeAgentRun, beforeLLMCall, beforeToolCall) and in reverse order on outbound hooks (afterToolCall, afterLLMCall, afterAgentRun) — a stack, not a flat list. Fetch an attached instance back by name:

recorder = agent.getMiddlewareByName( "Flight Recorder Middleware" )

Agent-Scoped Hooks

Two hooks only make sense at the agent level — they bracket the entire run() call, not an individual LLM or tool call:

Hook
Fires When
Context

beforeAgentRun

Agent run() begins

agent, input, messages, params, options

afterAgentRun

Agent run() completes

+ response

Every other hook (beforeLLMCall/afterLLMCall, beforeToolCall/afterToolCall, afterToolBatch, the wrap-style hooks, onError) behaves identically whether attached to an agent or a bare model — see Middleware Overview for all of them.

Suspending an Agent for Human Approval

HumanInTheLoopMiddleware is the middleware you'll attach to agents most often — it suspends agent.run() mid-turn until a human approves, rejects, or edits a pending tool call, and resumes via agent.resume()/resumeStream().

This is a thin slice of a larger topic — approval policies, durable approve_always/approve_session grants, batched approvals, and presenting through a gateway all live on their own pages:

Last updated