Extend the runtime#

Reach for an extension when behavior belongs inside the request lifecycle: restoring history, reshaping context, adding tools, asking the user, or emitting UI events. For display-only callbacks, use an AgentEventDispatcher instead. You never subclass Agent or write a second model loop.

Write your first extension

Register a tool, transform input, emit an event, and clean up.

Write your first extension
Built-in extensions

Sessions, compaction, subagents, approvals, skills, MCP, and more.

Compose built-in extensions
Lifecycle hooks

Every hook boundary and which one to override for a given job.

Lifecycle hook reference
Middleware

Wrap each provider request or tool call, in a documented order.

Middleware
Events and external input

Publish notifications and route responses back into a running request.

Emit events and accept user input
State and cleanup

Keep per-request data safe when one instance serves many sessions.

State, concurrency, and cleanup
Model adapters

Add a provider or normalize a protocol the built-ins do not cover.

Implement a model adapter
Server-side tools

Declare provider-hosted tools such as web search or code execution.

Register provider-hosted tools
Storage adapters

Persist raw history and compaction checkpoints in your own store.

Implement a storage adapter

Suggested path: build your first extension, learn the event channels, then add state and cancellation handling. Implement a new provider or storage adapter only when an existing one cannot satisfy your application boundary.