import { LanguageModelV4, LanguageModelV4StreamResult } from '@ai-sdk/provider'; import { ProviderOptions, InferSchema } from '@ai-sdk/provider-utils'; import { Schema, LanguageModelCallOptions, RequestOptions, Prompt, ToolChoice, FinishReason, LanguageModelUsage, CallWarning } from 'ai'; import { ReactNode } from 'react'; import * as z3 from 'zod/v3'; import * as z4 from 'zod/v4'; type AIAction = (...args: T[]) => Promise; type AIActions = Record>; type AIProviderProps = { children: React.ReactNode; initialAIState?: AIState; initialUIState?: UIState; /** $ActionTypes is only added for type inference and is never used at runtime **/ $ActionTypes?: Actions; }; type AIProvider = (props: AIProviderProps) => Promise; type InferAIState = T extends AIProvider ? AIState : Fallback; type OnSetAIState = ({ key, state, done, }: { key: string | number | symbol | undefined; state: S; done: boolean; }) => void | Promise; type OnGetUIState = AIAction; type ValueOrUpdater = T | ((current: T) => T); type MutableAIState = { get: () => AIState; update: (newState: ValueOrUpdater) => void; done: ((newState: AIState) => void) | (() => void); }; /** * Get the current AI state. * If `key` is provided, it will return the value of the specified key in the * AI state, if it's an object. If it's not an object, it will throw an error. * * @example const state = getAIState() // Get the entire AI state * @example const field = getAIState('key') // Get the value of the key */ declare function getAIState(): Readonly>; declare function getAIState(key: keyof InferAIState): Readonly[typeof key]>; /** * Get the mutable AI state. Note that you must call `.done()` when finishing * updating the AI state. * * @example * ```tsx * const state = getMutableAIState() * state.update({ ...state.get(), key: 'value' }) * state.update((currentState) => ({ ...currentState, key: 'value' })) * state.done() * ``` * * @example * ```tsx * const state = getMutableAIState() * state.done({ ...state.get(), key: 'value' }) // Done with a new state * ``` */ declare function getMutableAIState(): MutableAIState>; declare function getMutableAIState(key: keyof InferAIState): MutableAIState[typeof key]>; declare function createAI({ actions, initialAIState, initialUIState, onSetAIState, onGetUIState, }: { actions: Actions; initialAIState?: AIState; initialUIState?: UIState; /** * This function is called whenever the AI state is updated by an Action. * You can use this to persist the AI state to a database, or to send it to a * logging service. */ onSetAIState?: OnSetAIState; /** * This function is used to retrieve the UI state based on the AI state. * For example, to render the initial UI state based on a given AI state, or * to sync the UI state when the application is already loaded. * * If returning `undefined`, the client side UI state will not be updated. * * This function must be annotated with the `"use server"` directive. * * @example * ```tsx * onGetUIState: async () => { * 'use server'; * * const currentAIState = getAIState(); * const externalAIState = await loadAIStateFromDatabase(); * * if (currentAIState === externalAIState) return undefined; * * // Update current AI state and return the new UI state * const state = getMutableAIState() * state.done(externalAIState) * * return
...
; * } * ``` */ onGetUIState?: OnGetUIState; }): AIProvider; type Streamable = ReactNode | Promise; type Renderer> = (...args: T) => Streamable | Generator | AsyncGenerator; type RenderTool = { description?: string; inputSchema: INPUT_SCHEMA; generate?: Renderer<[ InferSchema, { toolName: string; toolCallId: string; } ]>; }; type RenderText = Renderer<[ { /** * The full text content from the model so far. */ content: string; /** * The new appended text content from the model since the last `text` call. */ delta: string; /** * Whether the model is done generating text. * If `true`, the `content` will be the final output and this call will be the last. */ done: boolean; } ]>; type RenderResult = { value: ReactNode; } & LanguageModelV4StreamResult; /** * `streamUI` is a helper function to create a streamable UI from LLMs. */ declare function streamUI({ model, tools, toolChoice, instructions, system, prompt, messages, allowSystemInMessages, maxRetries, abortSignal, headers, initial, text, providerOptions, onFinish, ...settings }: LanguageModelCallOptions & Omit & Prompt & { /** * The language model to use. */ model: LanguageModelV4; /** * The tools that the model can call. The model needs to support calling tools. */ tools?: { [name in keyof TOOLS]: RenderTool; }; /** * The tool choice strategy. Default: 'auto'. */ toolChoice?: ToolChoice; text?: RenderText; initial?: ReactNode; /** * Additional provider-specific options. They are passed through * to the provider from the AI SDK and enable provider-specific * functionality that can be fully encapsulated in the provider. */ providerOptions?: ProviderOptions; /** * Callback that is called when the LLM response and the final object validation are finished. */ onFinish?: (event: { /** * The reason why the generation finished. */ finishReason: FinishReason; /** * The token usage of the generated response. */ usage: LanguageModelUsage; /** * The final ui node that was generated. */ value: ReactNode; /** * Warnings from the model provider (e.g. unsupported settings) */ warnings?: CallWarning[]; /** * Optional response data. */ response?: { /** * Response headers. */ headers?: Record; }; }) => Promise | void; }): Promise; type StreamableUIWrapper = { /** * The value of the streamable UI. This can be returned from a Server Action and received by the client. */ readonly value: React.ReactNode; /** * This method updates the current UI node. It takes a new UI node and replaces the old one. */ update(value: React.ReactNode): StreamableUIWrapper; /** * This method is used to append a new UI node to the end of the old one. * Once appended a new UI node, the previous UI node cannot be updated anymore. * * @example * ```jsx * const ui = createStreamableUI(
hello
) * ui.append(
world
) * * // The UI node will be: * // <> * //
hello
* //
world
* // * ``` */ append(value: React.ReactNode): StreamableUIWrapper; /** * This method is used to signal that there is an error in the UI stream. * It will be thrown on the client side and caught by the nearest error boundary component. */ error(error: any): StreamableUIWrapper; /** * This method marks the UI node as finalized. You can either call it without any parameters or with a new UI node as the final state. * Once called, the UI node cannot be updated or appended anymore. * * This method is always **required** to be called, otherwise the response will be stuck in a loading state. */ done(...args: [React.ReactNode] | []): StreamableUIWrapper; }; /** * Create a piece of changeable UI that can be streamed to the client. * On the client side, it can be rendered as a normal React node. */ declare function createStreamableUI(initialValue?: React.ReactNode): StreamableUIWrapper; declare const __internal_curr: unique symbol; declare const __internal_error: unique symbol; /** * StreamableValue is a value that can be streamed over the network via AI Actions. * To read the streamed values, use the `readStreamableValue` or `useStreamableValue` APIs. */ type StreamableValue = { [__internal_curr]?: T; [__internal_error]?: E; }; /** * Create a wrapped, changeable value that can be streamed to the client. * On the client side, the value can be accessed via the readStreamableValue() API. */ declare function createStreamableValue(initialValue?: T | ReadableStream): StreamableValueWrapper; type StreamableValueWrapper = { /** * The value of the streamable. This can be returned from a Server Action and * received by the client. To read the streamed values, use the * `readStreamableValue` or `useStreamableValue` APIs. */ readonly value: StreamableValue; /** * This method updates the current value with a new one. */ update(value: T): StreamableValueWrapper; /** * This method is used to append a delta string to the current value. It * requires the current value of the streamable to be a string. * * @example * ```jsx * const streamable = createStreamableValue('hello'); * streamable.append(' world'); * * // The value will be 'hello world' * ``` */ append(value: T): StreamableValueWrapper; /** * This method is used to signal that there is an error in the value stream. * It will be thrown on the client side when consumed via * `readStreamableValue` or `useStreamableValue`. */ error(error: any): StreamableValueWrapper; /** * This method marks the value as finalized. You can either call it without * any parameters or with a new value as the final state. * Once called, the value cannot be updated or appended anymore. * * This method is always **required** to be called, otherwise the response * will be stuck in a loading state. */ done(...args: [T] | []): StreamableValueWrapper; }; export { createAI, createStreamableUI, createStreamableValue, getAIState, getMutableAIState, streamUI };