Skip to main content
Middleware lets you wrap agent execution with reusable logic such as logging, retries, metrics collection, and custom pre/post-processing. Middleware composes cleanly and executes in a predictable order.

How Middleware Works

Middleware wraps the agent’s core execution. Each middleware receives a RunContext and a next_handler function, and decides what to do before and after calling next_handler: The response travels back through the same chain in reverse order. The last middleware added is the outermost wrapper.

Using Middleware

Add middleware with the .use() method:

Built-in Middleware

LoggingMiddleware

Logs the start, completion, and any errors for each run.
logging.Logger
required
The Python logger instance to write to.
int
default:"logging.INFO"
Log level for normal events. Errors are always logged at ERROR.

RetryMiddleware

Retries the entire run on transient errors with exponential backoff.
int
default:"3"
Maximum number of retry attempts.
float
default:"1.0"
Base delay in seconds (doubles on each retry).
float
default:"60.0"
Maximum backoff delay in seconds.
Retries are triggered for ConnectionError, TimeoutError, and OSError.

MetricsMiddleware

Collects timing and count metrics across runs.

KnowledgeMiddleware

Automatically retrieves relevant documents from a knowledge base and injects them into the agent’s context. See Agent Integration for details.

Writing Custom Middleware

Implement the Middleware protocol — a callable that accepts context and next_handler:

Modifying Context

Middleware can modify the RunContext before passing it to the next handler:

Error Handling

Middleware can catch and handle errors:

Execution Order

Middleware executes in reverse registration order (last added = outermost):
Request flow: C → B → A → Agent Core Response flow: Agent Core → A → B → C This means if you want retries to wrap logging, add logging first, then retries.