agent.streamEvents() yields a typed union — text tokens, tool calls, tool results, and terminal events — in the exact order the agent produced them, so a UI can show tool activity instead of inferring it from prose.
Quick Start
1
Consume the event stream
One agent, one tool, one
for await — switch on event.type.The Event Union
streamEvents() yields the AgentEvent discriminated union — five variants, keyed on type.
Pairing Calls to Results with callId
callId is the provider’s id for the invocation and is the only key that may pair a tool_result to its tool_call.
Matching by position holds only while exactly one call is in flight, and silently attributes the wrong output the moment that stops being true.
Order Matters
Structured events share the same queue as the text, which keeps a tool call in its true position. On a separate channel a call could arrive before the sentence introducing it, and a reader cannot tell a reordered transcript from a model that genuinely said things in that order.stream() vs streamEvents()
Use stream() for text-only output; use streamEvents() when the UI must render tool activity.
stream() filters on type === 'text' internally, so widening the AgentEvent union does not affect it — text-only consumers are unaffected by this change.
Upgrading an Exhaustive switch
Widening a union is source-breaking for an exhaustive switch.
A consumer that handled text/finish/error and treated everything else as an error will now see tool_call/tool_result on the default branch. Add cases (or ignore the new variants explicitly) before upgrading.
Cancelling a Stream
Pass anAbortSignal through AgentStreamOptions.signal to stop generation when the user leaves the screen.
for await loop also aborts automatically — the iterator’s return() stops the in-flight provider request so no further tokens are generated or billed.
Best Practices
Show ok in the UI, not the output length
Show ok in the UI, not the output length
The whole point of
ok is that output length is not a signal. Render a checkmark or an error state from event.ok, never from whether event.output is non-empty.Render tool_call immediately
Render tool_call immediately
tool_call is emitted before the tool runs. Render a call-in-progress row the moment it arrives so the user knows work is happening.Match by callId from day one
Match by callId from day one
Position-matching works right up until the day two calls are in flight at once, then it silently attributes the wrong output. Key a
Map on callId from the start.Cancel long streams
Cancel long streams
Pass an
AbortSignal via AgentStreamOptions.signal when the user leaves the screen, or break the for await loop. Both stop the provider request so tokens are no longer generated or billed.Related
Streaming
Stream text token-by-token
Mobile Entry
Webview-safe bundle from praisonai/mobile
Events (listener API)
The agent.on(…) listener style
Agent
Full agent configuration

