Overview
CrewAI exposes a frame-based streaming contract for runtimes that need more than plain text chunks. The contract emits orderedStreamFrame objects for Flow lifecycle events, direct LLM tokens, tool activity, conversation messages, and custom events.
Use this API when you are building a UI, service bridge, terminal app, or deployment runtime that needs a stable stream of structured events while a Flow, chat turn, or direct LLM call is running.
StreamFrame
Every frame has the same envelope:channel field is the fastest way to route frames in consumers:
| Channel | Contains |
|---|---|
llm | Token and thinking chunks from LLM streaming events |
flow | Flow lifecycle, method execution, routing, and pause/resume events |
tools | Tool usage events |
messages | Conversation transcript events |
lifecycle | Runtime lifecycle events that are not specific to another channel |
custom | Events that do not map to a built-in channel |
frame.type preserves the source event type, so consumers can handle specific events inside a channel.
Stream a Flow
Setstream=True on a Flow to make kickoff() return a stream session:
stream.result. Accessing the result early raises a RuntimeError so consumers do not accidentally treat a partial run as complete.
You can also call flow.stream_events(...) directly when you want streaming for a single invocation without setting stream=True on the Flow instance.
Filter by Channel
StreamSession exposes channel projections that preserve global frame order within the selected channel:
| Projection | Frames |
|---|---|
stream.events | All frames |
stream.llm | LLM frames |
stream.messages | Conversation message frames |
stream.flow | Flow frames |
stream.tools | Tool frames |
stream.interleave([...]) | A selected set of channels |
stream.interleave(["flow", "llm", "messages"]) when a consumer wants only some channels but still needs their relative order.
Async Streaming
Useastream() for async consumers:
Stream a Direct LLM Call
llm.call(...) still returns the final assembled result. Use llm.stream_events(...) when you want to iterate over chunks as they arrive while keeping the structured event payload:
llm.stream_events(...) temporarily enables streaming for the wrapped call and restores the LLM’s previous stream setting afterward. Provider integrations continue to emit the underlying LLM stream events; this helper provides a common iterator API over those events for every LLM provider.
Conversational Turns
Conversational Flows can stream one user turn withstream_turn():
stream_turn(), the built-in conversational answer path enables LLM token streaming for that turn and restores the LLM’s previous stream setting afterward. Custom route handlers that create their own agents or LLM instances should configure those LLMs for streaming if they need token-level output.
Cleanup
Use the session as a context manager when possible. If a client disconnects before the stream is exhausted, close the session explicitly:await stream.aclose().
Legacy Chunk Streaming
Crew streaming withstream=True still returns the chunk-oriented CrewStreamingOutput API described in Streaming Crew Execution. Direct llm.call(...) still returns the final LLM result. The frame contract is intended for runtimes that need a stable event envelope across Flows, direct LLM calls, conversational turns, tools, and messages.