0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
27 small wins to finish your pathNext lesson →

Streaming a run with run_streamed

Streaming is a way to read a run's events as they happen, so you can print the model's text piece by piece instead of waiting for the whole answer.

Last updated: 28 Sep, 2026 · openai-agents 0.22.3

Runner.run_streamed starts a run and returns at once. Its stream_events() is an async generator of events. A raw_response_event wraps the model's own events, and the text pieces arrive as ResponseTextDeltaEvent objects.

The run_streamed and stream_events calls

python
result = Runner.run_streamed(agent, "hello")   # returns immediately
async for event in result.stream_events():      # consume the events
    ...                                         # each event is one thing that happened
print(result.final_output)                      # ready once the stream ends

Filtering for text delta events

Most events are not text. Keep the raw model events whose data is a ResponseTextDeltaEvent, and print each delta as it comes.

python
from openai.types.responses import ResponseTextDeltaEvent

async for event in result.stream_events():
    if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
        print(event.data.delta, end="", flush=True)

Running the stream inside asyncio

Streaming is async, so the loop lives in an async def and is started with asyncio.run.

python
import asyncio

async def main():
    agent = Agent(name="Shop", instructions="Help with orders.", model=ShopModel())
    result = Runner.run_streamed(agent, "hello")
    async for event in result.stream_events():
        ...

asyncio.run(main())

Word by word from the stand-in

The whole program in one file. The stand-in yields one word at a time, then the run reports the final text.

Example
import asyncio
from agents import Agent, Runner, set_tracing_disabled
from openai.types.responses import ResponseTextDeltaEvent
from shop_model import ShopModel
set_tracing_disabled(True)

async def main():
    agent = Agent(name="Shop", instructions="Help with orders.", model=ShopModel())
    result = Runner.run_streamed(agent, "hello")
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            print(event.data.delta, end="", flush=True)
    print()
    print("FINAL:", result.final_output)

asyncio.run(main())

What the event loop printed

  • Each delta is one word from the stand-in's stream_response, printed the moment it arrives, so the line builds up across the loop.
  • The filter keeps only raw_response_event events whose data is a ResponseTextDeltaEvent, skipping the other event types.
  • final_output is the same full text, available once the stream has ended.

run_sync vs run_streamed

CallReturnsYou read the text
Runner.run_syncThe finished RunResultAll at once from final_output
Runner.run_streamedA streaming result at oncePiece by piece from stream_events()

When to stream a run

  • Showing a reply as it is typed, so a user sees words appear instead of a blank wait.
  • Reacting to tool calls or handoffs the moment the SDK emits them.
  • Stopping a long answer early once you have read enough.
Watch out. run_streamed returns before the work is done, and the run advances only while you consume stream_events(). If you never iterate it, no text prints and final_output is not ready.
Try it yourself
  • Add an else branch that prints event.type to see the other events.
  • Collect the deltas into a list and print the list after the loop.
  • Change the stand-in's text and confirm the deltas follow.

Little by little, you're building something great.