new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

AI SDK · Core · all subjects

ai sdk ui

457 notes in this subject, read out of this brain and free to use. This is page 1 of 8.

useChat hook initialMessages parameter

The useChat hook accepts an initialMessages parameter of type UIMessage[] to load initial messages from storage. These messages are displayed in the chat UI when the component mounts.

Pitfall: Chat ID validation for file path security

When using chat IDs in file paths, validate them as opaque tokens before using them to construct file paths. Use a regex like /^[A-Za-z0-9_-]+$/ and verify the resolved path stays within the intended directory to prevent directory traversal attacks.

Example: Server-side ID generation with createUIMessageStream

Example of using createUIMessageStream with custom messageId: const stream = createUIMessageStream({ execute: ({ writer }) => { writer.write({ type: 'start', messageId: generateId() }); const result = streamText({ ... }); writer.merge(toUIMessageStream({ stream: result.stream, sendStart: false })); }, originalMessages: messages, onEnd: ({ responseMessage }) => { /* save chat */ } })

generateMessageId option in toUIMessageStream

The toUIMessageStream function accepts a generateMessageId parameter that uses createIdGenerator() to control the ID format for server-side generated message IDs. This ensures stable, consistent message IDs for persistence across sessions. Example: generateMessageId: createIdGenerator({ prefix: 'msg', size: 16 })

Client-side vs server-side message ID generation

By default, user message IDs are generated client-side by useChat, and AI response message IDs are generated server-side by streamText. For persistence, server-side ID generation for assistant responses is recommended to ensure stable IDs before messages are stored. User message IDs from the client should be kept when saving incoming messages.

toUIMessageStream onEnd callback for storing messages

The onEnd callback in toUIMessageStream receives the complete messages including the new AI response as UIMessage[]. This callback is where you should store messages to persist the chat history. The onEnd callback is triggered after streaming completes.

Pitfall: Message format difference between useChat and ModelMessage

Do not confuse UIMessage format (used by useChat and for storage) with ModelMessage format (used by streamText model parameter). UIMessage includes additional fields like id and createdAt and is designed for frontend display. Always use convertToModelMessages() to convert UIMessage[] to ModelMessage[] before sending to the model.

Example: Server-side ID generation with generateMessageId

Example of using generateMessageId in toUIMessageStream: toUIMessageStream({ stream: result.stream, originalMessages: messages, generateMessageId: createIdGenerator({ prefix: 'msg', size: 16 }), onEnd: ({ messages }) => { saveChat({ chatId, messages }); } })

Example: Sending only last message with prepareSendMessagesRequest

Example of customizing request body to send only the last message: transport: new DefaultChatTransport({ api: '/api/chat', prepareSendMessagesRequest({ messages, id }) { return { body: { message: messages[messages.length - 1], id } }; } })

useChat hook messages return value

The useChat hook returns a messages array of UIMessage[] containing the current conversation history, including both user and assistant messages. Each message has properties like id, role, createdAt, and parts.

DefaultChatTransport api parameter

The DefaultChatTransport constructor accepts an api parameter specifying the endpoint URL where chat messages are sent. Example: new DefaultChatTransport({ api: '/api/chat' })

useChat hook id parameter

The useChat hook accepts an id parameter representing the chat ID. This ID is used to identify the chat and is typically passed to the server in requests to load/save messages for that specific chat.

Example: Chatbot message persistence with validateUIMessages

Example showing how to validate messages with tools before processing: const validatedMessages = await validateUIMessages({ messages, tools, dataPartsSchema, metadataSchema }). Then pass validatedMessages to convertToModelMessages() for the model.

useChat hook sendMessage method

The useChat hook returns a sendMessage method that accepts a message object with a text property. This method sends the user message and triggers the API call to the server.

UIMessage format for storage

Messages should be stored in UIMessage format, not ModelMessage format. UIMessage format is designed for frontend display and contains additional fields such as id and createdAt. This format is recommended for storage rather than the ModelMessage format used by the model.

DefaultChatTransport with custom prepareSendMessagesRequest

The DefaultChatTransport can accept a prepareSendMessagesRequest function that customizes the request body sent to the server. This function receives { messages, id } and returns { body: {...} }. It can be used to send only the last message instead of all messages, reducing data sent to the server.

useCompletion server-side handler with streamText

Example server handler for useCompletion: ```ts import { createUIMessageStreamResponse, streamText, toUIMessageStream, } from 'ai'; __PROVIDER_IMPORT__; export const maxDuration = 30; export async function POST(req: Request) { const { prompt }: { prompt: string } = await req.json(); const result = streamText({ model: __MODEL__, prompt, }); return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }), }); } ``` This shows how to use streamText with createUIMessageStreamResponse and toUIMessageStream to handle text completions on the server.

useCompletion request options example

Example of customizing useCompletion request options: ```tsx const { messages, input, handleInputChange, handleSubmit } = useCompletion({ api: '/api/custom-completion', headers: { Authorization: 'your_token', }, body: { user_id: '123', }, credentials: 'same-origin', }); ``` This example shows how to set a custom API endpoint, add authorization headers, include additional body fields, and configure credentials for the fetch request.

useCompletion throttle option

The useCompletion hook supports a throttle option to throttle UI updates. By default, the hook triggers a render every time a new chunk is received. The throttle option accepts a number in milliseconds to limit update frequency. This feature is currently only available for React.

useCompletion api option

The useCompletion hook accepts an api option to specify the endpoint where completion requests are sent. The default endpoint is '/api/completion'. This can be customized to point to a different server endpoint.

useCompletion credentials option

The useCompletion hook accepts a credentials option to control how credentials are handled in the fetch request.

useCompletion headers option

The useCompletion hook accepts a headers option to customize the HTTP headers sent with the POST request.

useCompletion hook location

The useCompletion hook is part of the @ai-sdk/react package.

useCompletion event callbacks example

Example of using event callbacks with useCompletion: ```tsx const { ... } = useCompletion({ onFinish: (prompt: string, completion: string) => { console.log('Finished streaming completion:', completion) }, onError: (error: Error) => { console.error('An error occurred:', error) }, }) ```

useCompletion onFinish callback

The useCompletion hook supports an onFinish callback that is called when streaming completes. It receives the prompt string and completion string as parameters.

useCompletion basic example

Example showing useCompletion usage: ```tsx 'use client'; import { useCompletion } from '@ai-sdk/react'; export default function Page() { const { completion, input, handleInputChange, handleSubmit } = useCompletion({ api: '/api/completion', }); return ( <form onSubmit={handleSubmit}> <input name="prompt" value={input} onChange={handleInputChange} id="input" /> <button type="submit">Submit</button> <div>{completion}</div> </form> ); } ``` This example shows how to set up a form that accepts user input and streams completion text back in real-time.

useCompletion stop function

The useCompletion hook returns a stop function that aborts the response message while it is still streaming back from the AI provider. This prevents consuming unnecessary resources and improves user experience.

useCompletion setInput API

The useCompletion hook provides a setInput function that allows you to control the input programmatically. This is useful for advanced scenarios such as form validation or customized components where you need more granular control than handleInputChange and handleSubmit provide.

useCompletion error state

The useCompletion hook returns an error state that reflects the error object thrown during the fetch request. It can be used to display an error message or show a toast notification.

useCompletion isLoading state

The useCompletion hook returns an isLoading state that indicates whether the chatbot is processing a user message. This can be used to display a loading spinner while waiting for the AI response.

useCompletion body option

The useCompletion hook accepts a body option to include additional fields in the request body that are sent to the server.

useCompletion onError callback

The useCompletion hook supports an onError callback that is called when an error occurs during streaming. It receives the Error object as a parameter.

Tool result states in UI messages

Tool parts in messages have a state property that can be 'input-available', 'output-available', or 'output-error'. 'input-available' indicates the tool is executing. 'output-available' means the tool has returned data available in part.output. 'output-error' indicates an error with text in part.errorText.

Tool part rendering pattern

To render tool results in the UI, check message.parts for tool parts with type 'tool-${toolName}', then switch on part.state. For 'input-available' show loading, for 'output-available' render the component with part.output spread as props, for 'output-error' display part.errorText.

Expanding generative UI with multiple tools

To add more tools to a generative UI application, define them in the tools configuration object with unique key names (e.g., displayWeather, getStockPrice). Create corresponding React components for each tool's output. Update the page component to handle each tool's parts with their specific type names (tool-displayWeather, tool-getStockPrice, etc.).

UIMessage parts structure

UIMessage objects contain a parts array where each part has a type property. Text content uses part.type === 'text' and has a text property. Tool results use typed naming with part.type === 'tool-${toolName}' format (for example, 'tool-displayWeather').

useChat hook basic usage

The useChat hook from '@ai-sdk/react' is used to build chat interfaces. It provides messages array and sendMessage function to send messages. Messages can be sent with sendMessage({ text: input }). The hook manages conversation state automatically.

Generative UI flow

The generative UI process works as follows: First, you provide the model with a prompt or conversation history along with a set of tools. Based on the context, the model may decide to call a tool. If a tool is called, it executes and returns data. This data can then be passed to a React component for rendering.

Generative UI definition

Generative user interfaces (generative UI) is the process of allowing a large language model (LLM) to go beyond text and generate UI. This creates a more engaging and AI-native experience for users by connecting the results of tool calls to React components.

Basic chat implementation code example

Example showing useChat hook usage with text messages and tool results rendering: ```tsx 'use client'; import { useChat } from '@ai-sdk/react'; import { useState } from 'react'; import { Weather } from '@/components/weather'; export default function Page() { const [input, setInput] = useState(''); const { messages, sendMessage } = useChat(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); sendMessage({ text: input }); setInput(''); }; return ( <div> {messages.map(message => ( <div key={message.id}> <div>{message.role === 'user' ? 'User: ' : 'AI: '}</div> <div> {message.parts.map((part, index) => { if (part.type === 'text') { return <span key={index}>{part.text}</span>; } if (part.type === 'tool-displayWeather') { switch (part.state) { case 'input-available': return <div key={index}>Loading weather...</div>; case 'output-available': return <div key={index}><Weather {...part.output} /></div>; case 'output-error': return <div key={index}>Error: {part.errorText}</div>; default: return null; } } return null; })} </div> </div> ))} <form onSubmit={handleSubmit}> <input value={input} onChange={e => setInput(e.target.value)} placeholder="Type a message..." /> <button type="submit">Send</button> </form> </div> ); } ```

Error handling with message recovery

When an error occurs after a user message, you can use setMessages to clean up the message history. If an assistant response began streaming before the error, remove both the partial assistant response and its corresponding user message by slicing the messages array to remove the last two entries. If the error occurred before any assistant response, remove only the last user message.

Testing errors by throwing in route handler

To create test errors, throw an error in your route handler. The error will be caught and handled by the error handling mechanisms in the UI hooks.

onError callback option for useChat and useCompletion

The useChat and useCompletion hooks accept an onError option that takes a callback function. This function receives an error object as an argument and allows you to process errors programmatically.

Error object from UI hooks

Each AI SDK UI hook returns an error object that can be used to render errors in the UI, show error messages, disable submit buttons, or show retry buttons.

Warning message format

All AI SDK warnings start with the prefix 'AI SDK Warning:' in the browser console to make them easily identifiable.

Custom warning handler function

A custom warning handler can be provided by setting globalThis.AI_SDK_LOG_WARNINGS to a function. The function receives an object with properties: warnings (array of warnings), provider (provider id), and model (model id).

Warning display control with global flag

Warnings can be turned off completely by setting globalThis.AI_SDK_LOG_WARNINGS = false. By default, warnings are shown in the browser console.

Generic error messages best practice

Show generic error messages to the user, such as 'Something went wrong', rather than detailed error messages. This prevents leaking sensitive information from the server.

useObject example with notifications

Example showing useObject usage with a notifications schema. The hook is called with api: '/api/notifications' and schema: notificationSchema. The submit function is called with a prompt string like 'Messages during finals week.' The object property contains partial results that update as they stream in, accessible via object?.notifications?.map().

useObject hook basic usage

The useObject hook is called with configuration including 'api' (the endpoint), 'schema' (a Zod schema defining the object structure). It returns an object with properties including 'object' (the streaming result) and 'submit' (a function to trigger generation).

useObject event callbacks

The useObject hook supports optional event callbacks: 'onFinish' (called when object generation completes, receives typed object and error) and 'onError' (called when an error occurs during fetch request). These can be used for logging, analytics, or custom UI updates.

useObject error state handling

The error state returned by useObject reflects the error object thrown during the fetch request. It can be used to display an error message or disable the submit button. It is recommended to show a generic error message to the user to avoid leaking information from the server.

useObject onFinish callback parameters

The onFinish callback receives an object with properties: 'object' (the typed, validated object, undefined if schema validation fails) and 'error' (schema validation error, undefined if validation succeeds).

useObject hook purpose

The useObject hook allows you to create interfaces that represent a structured JSON object that is being streamed.

useObject enum output mode

When using useObject with enum output mode for classification, the schema must be an object with 'enum' as the key containing a z.enum with predefined option values, for example: z.object({ enum: z.enum(['true', 'false']) }).

useObject return values

The useObject hook returns an object with the following properties: 'object' (the streamed result, may be partial), 'submit' (function to trigger generation), 'isLoading' (boolean indicating if generation is in progress), 'stop' (function to cancel generation), and 'error' (error object if fetch fails).

useObject hook availability

The useObject hook is only available in React, Svelte, and Vue.

useObject isLoading state

The isLoading state returned by useObject can be used to show a loading spinner while the object is generated and to disable the submit button during generation.

useObject stop function

The stop function returned by useObject can be used to cancel the object generation process. This is useful if the user wants to cancel the request or if the server is taking too long to respond.

useObject onError callback

The onError callback receives an error that occurred during the fetch request and can be used to handle request-level failures separately from schema validation errors.

Give your agent this brain