Chatbot Tools, Persistence, and Resume
Purpose and Scope
This page explains how AI SDK UI chatbots combine tool calls, user interaction, message storage, stable message identifiers, and resumable streaming into one application flow. The central idea is that a chat session is not only text moving between a browser and an API route. It is a sequence of typed messages, assistant parts, tool calls, tool results, and sometimes approval decisions that must survive user interaction and page reloads. The documented chatbot tool flow uses the same client and server abstractions that persistence and resume features depend on, so it is best to design them together rather than as separate afterthoughts.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
The relevant AI SDK UI primitives are the chat hook on the client and streaming text generation on the server. The tool usage guide describes a flow where a user submits a message, the API route calls the model, tool calls are forwarded to the client, server tools execute on the server, client tools return their outputs from the browser, and the chat may automatically continue once all required tool outputs are available. Persistence extends that same flow by storing the messages for a chat identifier, while resume support keeps the UI attached to an active or recoverable stream when navigation or refresh interrupts the browser session.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Relevant Source Files
- content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx - Source documentation for AI SDK UI chatbot tool execution patterns, typed tool parts, client-side tool output submission, and automatic resubmission when tool results are complete.
Core Primitives
A chatbot using tools has two message shapes to keep in mind. The browser-oriented shape is the UI message, which contains displayable assistant parts and is suitable for storage and rendering. The model-oriented shape is the converted message list that the server sends into generation. In the documented route, the server receives UI messages, converts them before calling the model, and returns a UI message stream response. That conversion boundary matters for persistence: store the UI-facing history that the hook can reload, but send the model the normalized messages it expects for the next generation step.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Tools appear in the assistant response as typed tool parts. A tool part starts as a tool call and becomes a tool result after execution. Server-side tools include an execution function in the route, so the server can run them and stream results back. Client-side tools omit server execution and instead rely on the browser to provide output. Some client tools run automatically through the tool-call callback, while others intentionally require a button, dialog, or form. This distinction is important for persisted chats because an incomplete tool part represents pending work, not just historical transcript text.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Tool Execution Flow
The recommended flow begins when the user sends a message from the chat UI. The API route receives the message array, calls the language model through streaming generation, and exposes a UI message stream back to the client. During that stream, the model may emit tool calls. Server-side tools run through their declared execution function, and their results are integrated into the assistant message. Client-side tools are surfaced to the UI, where the application either handles them automatically or renders interaction controls for the user. After tool outputs are added, the conversation can continue with another model step.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
The guide’s example separates three useful patterns. A weather lookup is a server-side tool because the route can execute it and return a value directly. A confirmation prompt is a client-side interaction because the user must approve or reject the requested action in the UI. A location lookup is a client-side automatic tool because it represents browser-side context. In a production chatbot, these categories help decide where code should run, what should be stored, and which incomplete messages need special treatment during reload, resume, or audit review.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Approval UX and Human Interaction
Tool approval is a server-side execution pattern with a human gate. The docs distinguish it from client-side tools: approved tools still execute on the server, but only after the user confirms the requested operation. Use this when the model proposes sensitive actions such as payments, deletions, or external API calls. The UI should present the tool name, validated input, and a clear approve or deny action. Once the user responds, the application sends the approval decision back into the chat flow, allowing the server to continue or skip execution according to the decision.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Approval UX should be treated as part of message rendering rather than a separate modal with no transcript. The tool usage documentation says tool calls and tool results are integrated into the assistant message as typed parts, so the UI can render pending confirmations alongside assistant text. This makes the conversation understandable after persistence because the stored message history can show what was requested, what the user decided, and what result followed. It also prevents hidden state from being lost if the page refreshes while the tool is waiting for confirmation.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Persistence and Message IDs
Message persistence starts by giving each conversation a durable chat identifier and loading the message history for that identifier before rendering the chat UI. The official persistence guide frames storage and loading as crucial for most chatbots, and the tool usage flow explains why: the current assistant message may contain ordinary text, a pending tool call, a completed tool result, or a user-interaction part. Persisting only plain text loses the state needed to continue the interaction. Persist the UI message structure that the chat hook renders, including assistant parts and identifiers used by your application.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Stable message identifiers are especially useful when tool results and resumable streams are involved. A stored assistant message may be updated as streaming parts arrive, and a tool result may complete a part that was created earlier. If your storage layer replaces messages only by array position, reloads and retries can duplicate assistant responses or detach tool outputs from the call that produced them. Prefer an application-level chat record, message records with stable identifiers, and enough serialized part data to reconstruct the UI. This gives resume logic a reliable target when it reconnects to an in-progress stream.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Resumable Stream Behavior
Resume behavior should preserve the same lifecycle that the original stream used. The client submits or reloads a chat, the server streams UI message parts, and the browser renders them into the current assistant message. If the browser disconnects, the application should reload the persisted messages and reconnect to the stream associated with the chat when supported by the chosen transport. The important design constraint is that a resumed stream must not invent a second assistant turn for the same model response. It should continue filling the existing message or complete the pending tool interaction already visible to the user.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Automatic continuation after tool output is the bridge between tool usage and resume. The tool usage documentation calls out a configuration that submits again when all tool results are available, with a helper for detecting that the last assistant message is complete with tool calls. This is convenient, but it also means persistence must capture the exact completion state. On reload, the UI should know whether it is still waiting for a browser tool, waiting for approval, ready to continue, or already submitted. Otherwise, a resumed chat can accidentally repeat a tool call or skip a required user action.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Implementation Checklist
A practical implementation usually starts with the server route. Accept the client message array, convert UI messages to model messages before generation, declare the tools, and return a UI message stream response. Then build the client around typed parts: render text parts normally, render server tool results as completed details, render automatic client tools through the callback that supplies output, and render human interaction tools with explicit controls. Finally, add storage at the chat boundary: create a chat identifier, save submitted and streamed UI messages, load them on navigation, and reconnect or continue only when the stored state says it is safe.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
A compact route shape follows the documented pattern: receive UI messages, convert them for the model, call streaming text generation with tool definitions, and return a UI message stream response. The client side should pair that with rendering logic for each tool part state and an output submission path for browser tools. For approved server tools, present the approval request before execution rather than pretending it is a browser-only tool. These choices keep sensitive operations on the server, keep user decisions visible in the transcript, and keep resumed sessions aligned with persisted message state.
Sources: content/docs/04-ai-sdk-ui/03-chatbot-tool-usage.mdx
Related Pages and Next Steps
Read the AI SDK UI overview before implementing this flow if you are new to chat transports and UI message streams. Then pair this page with the stream protocol and metadata reference so your persistence layer stores the right message shape. For server behavior, review the core tool-calling documentation, especially multi-step execution and callbacks, because automatic continuation after tool results is a model-loop concern as well as a UI concern. If your chatbot performs sensitive actions, also read the tool approvals and policy-based approvals pages before shipping approval UX to production.