Basic streaming

Loop over the stream and pull `delta` from `message_update` events. The full text is also available on `message_end.content` when the message finishes.

Event types you will see

The CLI emits the same set of events on every SDK. Match on `event.type` (TS/Python) or the sealed event subtype (Go/Java) and ignore the rest.

  • `agent_start` / `agent_end`: brackets the whole run.
  • `turn_start` / `turn_end`: brackets a single agent turn.
  • `message_start` / `message_update` / `message_end`: assistant text. `delta` carries each new chunk; `content` carries the full final message.
  • `tool_start` / `tool_update` / `tool_end`: tool execution. Use `toolName` (or `tool_name`) for routing.
  • `permission_request`: pause; respond with `permissionResponse` / `respond_to_permission`.
  • `file_modified`: the agent wrote to disk. Useful for invalidating caches or refreshing editors.
  • `error`: transport, runtime, or tool failure. Always handle this.

Render a full chat loop

A typical chat surface routes message text to the transcript, tool runs to a side panel, and permission requests to a modal. Here is the same shape across SDKs.

Cancel an in-flight stream

Call `abort()` to end the run. The stream loop closes and any pending permission request is cancelled. Use this when the user cancels in your UI or when a parent task is unwound.

When to stream vs await

  • Stream when the user is watching: chat UIs, terminal sessions, long-running refactors.
  • Await with `agent.run()` when you only need the final result: scripts, batch jobs, JSON pipelines.
  • Combine the two: stream for UI rendering, then call `run.wait()` (TS) / `run.waitForResult()` (Java) for the structured `RunResult`.