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 · Cookbook · all subjects

patterns/rsc

28 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

onSetAIState callback for saving messages

The createAI function has an experimental onSetAIState callback that gets called whenever the AI state changes. This callback receives an object with a state property containing the current AI state and a done property indicating whether the operation is complete. Use this callback to save the AI state to a database or file when done is true.

Load chat history into initial AI state

Chat history can be retrieved from a database and passed to the AI provider using the initialAIState prop. In a Root Layout component, fetch the chat history using a function like getChat() and pass it to the AI wrapper component's initialAIState property to restore previous conversations.

Update AI state with mutable state methods

Use getMutableAIState() to access the mutable AI state object. Call history.get() to retrieve the current state array and history.done() to update and finalize the state with new messages. The done() method accepts the complete updated state array.

Example: complete message persistence with RSC

The example shows: (1) In layout.tsx, fetch chat history with getChat() and pass to AI initialAIState. (2) In actions.tsx, use getMutableAIState() to track changes and call history.done() when responses complete. (3) In ai.ts, define onSetAIState callback to call saveChat(state) when done is true, and onGetUIState to reconstruct UI from AI state. (4) In page.tsx, use useUIState and useActions to display and send messages, calling continueConversation() for new messages.

Reconstruct UI state from AI state

The onGetUIState callback in createAI can reconstruct the UI state from the AI state. Use getAIState() to fetch the server messages and transform them into client messages by mapping over the array, adding generated IDs, and converting function results back into React components.

ServerMessage and ClientMessage interface structure

ServerMessage has three properties: role (one of 'user', 'assistant', or 'function'), content (string). ClientMessage has four properties: id (string), role (one of 'user', 'assistant', or 'function'), display (ReactNode).

Save conversation when done event received

In the text callback of streamUI, check the done parameter. When done is true, call history.done() with the complete updated conversation including both user and assistant messages. This triggers the onSetAIState callback which can then persist the conversation to a database.

Set maxDuration for streaming responses

Export a maxDuration constant from the page component to control streaming timeout. The example uses maxDuration = 30 to allow streaming responses up to 30 seconds.

Save conversation after tool execution

When a tool's generate function executes, call history.done() with the updated conversation including the function call and its result. This ensures tool invocations are saved to the database along with the rest of the conversation.

useUIState and useActions manage RSC chat client state

In client components, use useUIState() hook to get and set the displayed conversation array, and use useActions() hook to call server actions like continueConversation. The conversation state holds messages with id, role, and display (JSX) fields.

RSC chat client-server example with Stock and Flight components

This example shows a chat interface where the user sends messages, the server uses streamUI to decide between showing stock information or flight status, and renders Stock or Flight components fetched from external APIs. The client updates conversation state after each server response.

Define tools with description, inputSchema, and generate function

Each tool in streamUI tools object requires: description (string explaining when the model should use it), inputSchema (Zod schema defining parameters), and generate (async function receiving typed inputs and returning JSX component).

RSC ServerMessage interface for history state

ServerMessage has role ('user' or 'assistant') and content (string) fields. Used to store conversation history in mutable AI state.

RSC ClientMessage interface for UI display

ClientMessage has id (string), role ('user' or 'assistant'), and display (ReactNode) fields. Used to render conversations on the client with unique message keys.

Text renderer in streamUI receives streaming content

The text function in streamUI receives an object with content (string chunk) and done (boolean) properties. Return JSX to render the text. Call history.done() when done is true to finalize the assistant message in state.

Tool generate function updates history before returning component

In a tool's generate function, call history.done() to add an assistant message to the conversation before returning the component. This ensures the tool invocation is recorded in state before rendering the result.

Use 'use server' directive in RSC server actions

Mark server action files and functions with 'use server'; directive to enable them as server actions callable from client components.

Generate unique message IDs with generateId from ai package

Import generateId from the 'ai' package to create unique identifiers for each ClientMessage when adding to conversation state.

streamUI renders components from tool calls in RSC chat

Use streamUI from @ai-sdk/rsc to generate text responses and render React components based on tool invocations. The streamUI function accepts a model, messages array, a text renderer for LLM output, and a tools object. Each tool has a description, inputSchema defined with Zod, and a generate async function that returns JSX to render in the chat.

getMutableAIState tracks conversation history in RSC

Call getMutableAIState() in server actions to access the mutable conversation history. Use history.get() to read current messages and history.done() to update the state with new messages after a tool completes or text finishes streaming.

useUIState hook for client-side conversation display

The useUIState hook from @ai-sdk/rsc provides conversation state and a setter function. Use it to read the current conversation array and update it when new messages arrive. Call setConversation with a callback that receives the current conversation and returns the updated array with new messages appended.

Stream UI updates with streamUI function

Use the streamUI function from @ai-sdk/rsc to stream React components from server to client. The function takes a model, messages array, and handlers for text and tools. The text handler receives content and done flag, allowing you to render components as text streams in. The done flag indicates when streaming is complete, at which point you can update the mutable AI state with history.done().

Tool generators with yield for progressive updates

Tool handler functions can be async generators that yield intermediate React components before returning a final component. Each yield sends an update to the client, allowing progressive UI updates as the tool executes. For example, a deploy tool can yield 'Cloning...' then 'Building...' then finally return the completion message, with each stage displayed to the user.

Mutable AI state with getMutableAIState and history.done

Use getMutableAIState() to retrieve the conversation history on the server. Call history.get() to read current messages, and history.done(callback) to update the history after streaming completes. The callback receives the current messages array and must return the updated messages array, typically appending the assistant's response.

useActions hook to call server actions

The useActions hook from @ai-sdk/rsc provides access to server actions defined in your AI configuration. Destructure the action functions you need, such as continueConversation, and call them from the client. These functions return ClientMessage objects that can be added to the conversation state.

RSC streaming example with tool-generated progressive updates

This example shows a complete RSC implementation with a deploy tool that yields intermediate updates. The client sends a message, the server calls continueConversation, which uses streamUI to generate text or execute tools. The deploy tool yields 'Cloning repository...' (waits 3 seconds), then yields 'Building repository...' (waits 2 seconds), then returns 'deployed!' message. Each yield updates the client UI progressively.

createAI configuration for RSC

Use createAI from @ai-sdk/rsc to set up your AI context. Pass a generic type with two type parameters: the server message type (typically ServerMessage[]) and the client message type (typically ClientMessage[]). Configure actions object mapping action names to functions, initialAIState as an empty array for server messages, and initialUIState as an empty array for client messages.

maxDuration for streaming responses in RSC

When using streamUI with React Server Components, set the maxDuration export constant to allow streaming responses to continue for the desired duration. For example, export const maxDuration = 30; allows streaming responses up to 30 seconds.

Give your agent this brain