docs/capabilities/process-event-stream.md
[ProcessEventStream][pydantic_ai.capabilities.ProcessEventStream] is a capability that forwards the agent's stream of [AgentStreamEvent][pydantic_ai.messages.AgentStreamEvent]s — model streaming and tool execution events — to a handler. When it's registered, agent.run() automatically enables streaming, so the handler fires without passing an explicit event_stream_handler argument:
from collections.abc import AsyncIterable
from pydantic_ai import Agent, AgentStreamEvent, RunContext
from pydantic_ai.capabilities import ProcessEventStream
async def log_events(ctx: RunContext, events: AsyncIterable[AgentStreamEvent]) -> None:
async for event in events:
print(event) # (1)!
agent = Agent('openai:gpt-5.2', capabilities=[ProcessEventStream(log_events)])
The handler comes in two forms:
EventStreamHandler][pydantic_ai.agent.EventStreamHandler] — an async def returning None, as above. Events are forwarded to the handler and passed through unchanged, so multiple handlers (and a top-level event_stream_handler argument) can all observe the same stream. Events are delivered synchronously, so a slow handler back-pressures the rest of the stream.EventStreamProcessor — an async generator that yields events. What it yields replaces the stream for downstream consumers, so it can modify, drop, or add events.Registering the capability composes with other streaming mechanisms: see Streaming all events for the event vocabulary and handler examples.
!!! note "Durable execution"
Under a durable execution capability, a ProcessEventStream handler runs in workflow code and must be deterministic, because it re-runs on workflow replay. Tool and final-output events arrive live, while model events are replayed after each model request completes. For handler I/O that must run exactly once inside the durable boundary, pass event_stream_handler= to the durability capability instead.