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 rsc

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

createStreamableUI function

createStreamableUI is an AI SDK RSC function that creates a stream sending UI from the server to the client.

createAI context provider

createAI is an AI SDK RSC function that creates a client-server context provider used to wrap parts of your application tree to easily manage both UI and AI states of your application.

@ai-sdk/rsc package compatibility

The @ai-sdk/rsc package is compatible with frameworks that support React Server Components.

useAIState hook

useAIState is an AI SDK RSC hook that returns the current AI state and a function to update the AI state, similar to React's useState. The AI state is intended to contain context and information shared with the AI model, such as system messages, function responses, and other relevant data.

readStreamableValue function

readStreamableValue is an AI SDK RSC function that reads a streamable value from the client that was originally created using createStreamableValue.

streamUI function

streamUI is an AI SDK RSC function that calls a model and allows it to respond with React Server Components. It is used for streaming generated UI from the server to the client.

createStreamableValue function

createStreamableValue is an AI SDK RSC function that creates a stream sending values from the server to the client. The value can be any serializable data.

useActions hook

useActions is an AI SDK RSC hook that provides access to your Server Actions from the client. It is particularly useful for building interfaces that require user interactions with the server.

AI SDK RSC overview and purpose

AI SDK RSC is an experimental package that allows you to build AI-native applications with React Server Components. It enables the large language model to generate and stream UI directly from the server to the client by combining React Server Components with Server Actions for end-to-end type-safety.

Example: Restoring UI state with onGetUIState

```tsx export const AI = createAI<ServerMessage[], ClientMessage[]>({ actions: { continueConversation, }, onGetUIState: async () => { 'use server'; const historyFromDB: ServerMessage[] = await loadChatFromDB(); const historyFromApp: ServerMessage[] = getAIState(); if (historyFromDB.length !== historyFromApp.length) { return historyFromDB.map(({ role, content }) => ({ id: generateId(), role, display: role === 'function' ? ( <Component {...JSON.parse(content)} /> ) : ( content ), })); } }, }); ``` This example shows how to restore UI state using the onGetUIState callback by comparing database history with app history and returning a new UI state if they differ.

onSetAIState callback for saving AI state

The onSetAIState callback is called whenever the AI state is updated. It receives an object with properties: state (the current AI state) and done (a boolean indicating if the generation is complete). This callback can be used to save the AI state to a database or other persistence layer. The callback is marked with 'use server' directive in Server Components.

onGetUIState callback for restoring UI state

The onGetUIState callback listens for SSR events and is used to restore UI state. It is marked with 'use server' directive. Since UI state contents are not directly serializable, the callback uses AI state as a proxy to determine what UI state should be restored. It can compare persisted state from a database with the current app state and return a new UI state based on the database history if they differ.

initialAIState prop for restoring AI state

The initialAIState prop is passed to the context provider created by the createAI function. It allows you to restore the AI state when the component is mounted, typically by loading persisted state from a database.

Example: Saving AI state with onSetAIState

```tsx export const AI = createAI<ServerMessage[], ClientMessage[]>({ actions: { continueConversation, }, onSetAIState: async ({ state, done }) => { 'use server'; if (done) { saveChatToDB(state); } }, }); ``` This example shows how to save the chat history to a database when the generation is marked as done.

UI state cannot be saved directly

The UI state cannot be saved directly because its contents are not yet serializable. Instead, use the AI state as a proxy to store details about the UI state, then use those details to restore the UI state when needed.

Example: Restoring AI state with initialAIState

```tsx import { ReactNode } from 'react'; import { AI } from './ai'; export default async function RootLayout({ children, }: Readonly<{ children: ReactNode }>) { const chat = await loadChatFromDB(); return ( <html lang="en"> <body> <AI initialAIState={chat}>{children}</AI> </body> </html> ); } ``` This example shows how to restore the chat history from a database when the component is mounted by passing it to initialAIState.

Server Action example for streamUI

export async function streamComponent() {\n const result = await streamUI({\n model: openai('gpt-4o'),\n prompt: 'Get the weather for San Francisco',\n text: ({ content }) => <div>{content}</div>,\n tools: { /* tools defined here */ },\n });\n return result.value;\n}\nThis shows a Server Action that calls streamUI and returns the resulting component (result.value) as a ReactNode.

Generator function in streamUI tools

The generate function in a streamUI tool can be an async generator function (using function* syntax). Generator functions allow you to pause execution with yield and resume on the next call, which is useful for streaming data. You can yield intermediate components (like loading states) while fetching data asynchronously, then return the final component.

streamUI function overview

The streamUI function allows you to stream React components from the server to the client. It works similarly to AI SDK Core APIs like streamText, accepting the same model interfaces. The function takes parameters including model, prompt, text handler, and tools. It must return a React component.

Using streamUI with Next.js Server Actions

To use streamUI in a Next.js application, create a Server Action (marked with 'use server') that calls streamUI and returns result.value (a ReactNode). Then create a client component page (marked with 'use client') that calls the Server Action and renders the returned component using React state.

Client page example for calling streamUI Server Action

'use client';\n\nimport { useState } from 'react';\nimport { streamComponent } from './actions';\n\nexport default function Page() {\n const [component, setComponent] = useState<React.ReactNode>();\n\n return (\n <div>\n <form onSubmit={async e => {\n e.preventDefault();\n setComponent(await streamComponent());\n }}>\n <Button>Stream Component</Button>\n </form>\n <div>{component}</div>\n </div>\n );\n}\nThis client component calls the streamComponent Server Action on form submission and renders the returned component using React state.

streamUI tool with generator function example

const result = await streamUI({\n model: openai('gpt-4o'),\n prompt: 'Get the weather for San Francisco',\n text: ({ content }) => <div>{content}</div>,\n tools: {\n getWeather: {\n description: 'Get the weather for a location',\n inputSchema: z.object({ location: z.string() }),\n generate: async function* ({ location }) {\n yield <LoadingComponent />;\n const weather = await getWeather(location);\n return <WeatherComponent weather={weather} location={location} />;\n },\n },\n },\n});\nThis example shows a tool that yields a loading component first, then fetches weather data, and finally returns a weather component.

streamUI with tools behaves like a dynamic router

When using streamUI with tools, the model acts as a dynamic router that understands user intention and can display relevant UI by calling appropriate tools. If the model decides to call a tool based on the conversation context, it generates a tool call and streamUI runs the respective tool returning a React component. If no relevant tool exists, the model returns text which is passed to the text handler.

streamUI text handler parameter

The text parameter in streamUI is a function that handles the model's plain text response. It receives an object with a content property containing the text response, and must return a React component to render that text.

streamUI basic usage example

const result = await streamUI({\n model: openai('gpt-4o'),\n prompt: 'Get the weather for San Francisco',\n text: ({ content }) => <div>{content}</div>,\n tools: {},\n});\nThis example shows basic streamUI usage with OpenAI's gpt-4o model, a prompt, a text handler that renders plain text responses as a div, and an empty tools object.

AI Context setup with RootLayout

To use createAI to manage AI and UI State in your application, wrap your application with the created context. This is typically done in the root layout component, allowing all child components to access and update application state through the hooks provided by the RSC API.

State access location restrictions

AI state can be accessed and modified from both server and client. UI state can only be accessed client-side. The getAIState and getMutableAIState functions can only be used within Server Actions that have been passed to the createAI context within the actions key.

getMutableAIState function usage

The getMutableAIState function from @ai-sdk/rsc can be used within any Server Action provided to the createAI context to access and update the AI state. It returns the state with methods to read and update it: .get() to read the current state, .update() to update the state, and .done() to finalize updates. The .update() and .done() methods should be used to keep the conversation history in sync.

Updating UI State after Server Action calls

After calling a Server Action from the client, it is important to update the UI State, otherwise the streamed component will not show in the UI. This ensures that the UI reflects the changes made by the Server Action.

AI State and UI State split concept

With Generative UI, the model can return a React component rather than a plain text message. The client can render that component, but that state cannot be sent back to the model because React components are not serializable. The solution is to split the state into two parts: AI State provides a serializable JSON representation of the UI that can be passed back and forth to the model, while UI State contains the actual UI elements that are rendered on the client.

useActions hook for calling Server Actions

The useActions hook from @ai-sdk/rsc is used in Client Components to call Server Actions. It returns all the available Actions that were provided to createAI. Example: const { sendMessage } = useActions<typeof AI>();

getAIState function usage

The getAIState function from @ai-sdk/rsc can be used within any Server Action provided to the createAI context to access the current AI state as a read-only value. It returns the AI state without modification capabilities. This function can only be used in Server Actions that have been registered in the createAI context's actions key.

useAIState hook usage

The useAIState hook from @ai-sdk/rsc is used in Client Components to access AI state. It returns the current AI state and a function to update it. Example: const [messages, setMessages] = useAIState();

useUIState hook usage

The useUIState hook from @ai-sdk/rsc is used in Client Components to access UI state. It returns the current UI state and a function to update the UI state, similar to React's useState. Example: const [messages, setMessages] = useUIState();

createAI function and configuration

The createAI function from @ai-sdk/rsc creates a React context for managing AI and UI State across your application. It is called with a configuration object containing: initialAIState (the initial AI state), initialUIState (the initial UI state), and actions (an object containing Server Actions that must be passed as Server Actions). The function is generic and accepts type parameters for AIState and UIState types.

UI State definition and purpose

UI State refers to the state of your application that is rendered on the client. It is a fully client-side state similar to useState that can store anything from JavaScript values to React elements. UI state is a list of actual UI elements that are rendered on the client. UI State can only be accessed client-side.

AI State definition and purpose

AI State refers to the state of your application in a serializable format that will be used on the server and can be shared with the language model. For a chat app, the AI State is the conversation history (messages) between the user and the assistant. Components generated by the model are represented in a JSON format as a tool alongside any necessary props. AI State can also store other values and meta information such as createdAt for each message and chatId for each conversation. The LLM reads this history to generate the next message. This state serves as the source of truth for the current application state. AI state can be accessed and modified from both the server and the client.

Server Actions required in createAI configuration

The actions object passed to createAI must contain Server Actions. Regular functions will not work; they must be marked with 'use server' directive to be Server Actions.

streamUI file extension requirement

When using the streamUI function to define React components, the server file must have a .tsx extension instead of .ts because React components are being defined in the streamUI function.

maxDuration configuration for RSC streaming

When using AI SDK RSC with streaming, export const maxDuration = 30 at the top of the page to force the page to be dynamic and allow streaming responses up to 30 seconds.

streamUI function for streaming loading components

The streamUI function allows streaming React Server Components to the client. It supports JavaScript generator functions using the function* syntax, which allow yielding a loading component while blocking work completes. The text option receives an async generator function that yields a loading component and returns the final component when content is ready.

Reading multiple streamable values on the client

When the server returns multiple streamable values, iterate through each separately on the client using readStreamableValue. Use one loop for the response delta to build up text content, and another loop for the loading state delta to update the loading state variable with the streamed boolean value.

Streaming loading state from server with createStreamableValue

To track loading state on the server and stream it to the client, create two separate streamable values: one for the text response and one for loading state. Initialize the loading state streamable with { loading: true }. After the text stream completes, call loadingState.done({ loading: false }) to update the client. Return both streamable values as an object from the server function.

streamUI server implementation example

Example streamUI server implementation: call streamUI with model, prompt, and a text async generator function. The generator receives { content } parameter from the text generation. Yield a loading component like <div>loading...</div> initially, then return the final component <div>{content}</div> when complete. Return result.value to the client.

Server-side generateResponse with streamText and createStreamableValue

The generateResponse server function uses createStreamableValue to create a stream object. Call streamText with the model and prompt. Iterate through the textStream from streamText, updating the stream with each text chunk. Call stream.done() when the text stream completes, then return stream.value to the client.

Client-side loading state pattern with generateResponse

To handle loading state on the client, create a loading state variable initialized to false. When the form is submitted, set loading to true before calling generateResponse. After receiving the response and iterating through readStreamableValue, set loading back to false. Use the loading state to disable form inputs with disabled={loading} during generation.

AI SDK RSC loading state handling approaches

There are three approaches to handle loading state with AI SDK RSC: managing loading state similar to traditional Next.js applications by setting a loading state variable on the client and updating it when the response is received; streaming loading state from the server to the client for more granular tracking; and streaming loading components from the server to the client as React Server Components while awaiting the model's response.

Adding interactivity to rendered components

To add user interaction to a rendered component, convert it into a client component and use the useActions hook to trigger the next step in the conversation. Client components can call submitUserMessage with a prompt string and use setMessages (from useUIState) to append the response to the UI State.

Example: searchFlights and lookupFlight tools

Example tool implementation showing searchFlights (searches for flights based on source, destination, and date, yields a loading message then returns a component displaying results) and lookupFlight (looks up details for a specific flight by flight number, yields a loading message then returns a component displaying flight details including flight number, departure time, and arrival time).

Example: Complete multistep interface implementation

A complete example showing: (1) app/actions.tsx with streamUI call defining searchFlights and lookupFlight tools using async generator functions; (2) app/ai.ts using createAI with initialUIState and initialAIState as empty arrays and actions containing submitUserMessage; (3) app/layout.tsx wrapping the application with the AI context; (4) app/page.tsx as a client component using useUIState to render conversation and useActions to call submitUserMessage on form submission; (5) components/flights.tsx as a client component with Flights component that renders flight results and triggers lookupFlight on click.

Wrapping application with AI context

The root layout component should wrap the application with the AI context created by createAI. This makes the AI State, UI State, and actions available to all child components.

streamUI function usage in Server Actions

The streamUI function is called within a Server Action to handle the multistep interface flow. It accepts parameters including model, instructions, prompt, text (a handler for text content), and tools (an object defining available tools). The function returns an object with a value property containing the rendered React component.

Turn-by-turn implementation for multistep interfaces

The turn-by-turn implementation is the simplest form of multistep interfaces. In this implementation, the user and the model take turns during the conversation. For every user input, the model generates a response, and the conversation continues in this turn-by-turn fashion.

Multistep interface general flow

The general flow for multistep interfaces is: (1) User sends a message by calling a Server Action with useActions, passing the message as input. (2) Message is appended to the AI State and then passed to the model alongside tools. (3) Model can decide to call a tool, which will render a component. (4) Within that component, interactivity is added using useActions to call the model with the Server Action and useUIState to append the model's response to the UI State. (5) The process continues as needed.

Requirements for building multistep interfaces with AI SDK RSC

To build a multistep interface with @ai-sdk/rsc, you need: a Server Action that calls and returns the result from the streamUI function; tool(s) representing sub-tasks necessary to complete your overall task; React component(s) that should be rendered when the tool is called; and a page to render your chatbot.

Multistep interfaces definition and concepts

Multistep interfaces are user interfaces that require multiple independent steps to be executed in order to complete a specific task. Building multistep interfaces leverages two concepts: tool composition and application context. Tool composition is the process of combining multiple tools to create a new tool, breaking down complex tasks into smaller, more manageable steps. Application context refers to the state of the application at any given point in time, including the user's input, the output of the language model, and any other relevant information.

createAI function for multistep interfaces

The createAI function creates an AI context that holds UI State and AI State. It accepts a configuration object with initialUIState (initial UI state, typically an empty array), initialAIState (initial AI state, typically an empty array), and actions (an object containing Server Actions like submitUserMessage).

createStreamableValue API methods

The createStreamableValue object has the following methods: update() to update the streamable value with a new value, done() to mark the stream as finished and pass a final value, and a .value property that contains the actual value to be sent to the client.

createStreamableUI function purpose

The createStreamableUI function creates a stream that holds a React component. Unlike AI SDK Core APIs, this function does not call a language model. Instead, it provides a primitive for granular control over streaming a React component from server to client.

createStreamableValue function purpose

The createStreamableValue function creates a streamable (serializable) JavaScript value that can be streamed from server to client. It provides full control over how you create, update, and close the stream. It is useful for streaming text generations from language models in real-time, buffer values from multi-modal models for images and audio, and progress updates from multi-step agent runs.

Give your agent this brain