Stream responses in real-time
`streamPrompt` returns an async iterable of structured events. Use it to render assistant text as it generates, surface tool runs, and respond to permission requests without blocking the event loop.
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`.