Docs
Streaming & Results
Every adapter exposes the AI SDK agent surface: stream() for live turns and generate() for one-shots. The stream is a typed async iterable, so your UI can render exactly what is happening — text, tool calls, results, approval requests — as it happens.
const result = await agent.stream({ messages }) // streaming
const result = await agent.generate({ messages }) // one-shotThe result object#
| Property | What it is |
|---|---|
| result.fullStream | Async iterable of typed chunks: text-delta, tool-call, tool-result, tool-approval-request, error. |
| result.response | Resolves to the final messages — append them to your history. |
| result.text | The final assistant text. |
| result.totalUsage | Token counts for the turn. |
Consuming the stream#
for await (const chunk of result.fullStream) {
if (chunk.type === 'text-delta') process.stdout.write(chunk.text)
else if (chunk.type === 'tool-call') console.log(`\n↳ ${chunk.toolName}`, chunk.input)
else if (chunk.type === 'tool-result') console.log(' done')
else if (chunk.type === 'tool-approval-request') {
// Pause point: respond and continue — see Tool Approval.
} else if (chunk.type === 'error') {
console.error(chunk.error)
}
}Keeping history#
The agent is stateless between turns by design — you own the conversation. Keep a messages array and push result.response.messages after each turn:
const messages = []
async function turn(text) {
messages.push({ role: 'user', content: text })
const result = await agent.stream({ messages })
for await (const chunk of result.fullStream) { /* render */ }
const response = await result.response
messages.push(...response.messages)
}Building a chat UI? The stream shape is AI SDK-native, so it plugs into
useChat-style frontends with a thin transport — Sharables wires it exactly that way.