import { IdGenerator } from '@ai-sdk/provider-utils'; import { ServerResponse } from 'node:http'; import { CallWarning, FinishReason, LanguageModelRequestMetadata, ProviderMetadata, } from '../types'; import { Source } from '../types/language-model'; import { LanguageModelResponseMetadata } from '../types/language-model-response-metadata'; import { LanguageModelUsage } from '../types/usage'; import { InferUIMessageChunk } from '../ui-message-stream/ui-message-chunks'; import { UIMessageStreamOnFinishCallback } from '../ui-message-stream/ui-message-stream-on-finish-callback'; import { UIMessageStreamResponseInit } from '../ui-message-stream/ui-message-stream-response-init'; import { InferUIMessageMetadata, UIMessage } from '../ui/ui-messages'; import { AsyncIterableStream } from '../util/async-iterable-stream'; import { ErrorHandler } from '../util/error-handler'; import { ContentPart } from './content-part'; import { GeneratedFile } from './generated-file'; import { Output } from './output'; import { InferCompleteOutput, InferElementOutput, InferPartialOutput, } from './output-utils'; import { ReasoningOutput } from './reasoning-output'; import { ResponseMessage } from './response-message'; import { StepResult } from './step-result'; import { ToolApprovalRequestOutput } from './tool-approval-request-output'; import { DynamicToolCall, StaticToolCall, TypedToolCall } from './tool-call'; import { TypedToolError } from './tool-error'; import { StaticToolOutputDenied } from './tool-output-denied'; import { DynamicToolResult, StaticToolResult, TypedToolResult, } from './tool-result'; import { ToolSet } from './tool-set'; export type UIMessageStreamOptions = { /** * The original messages. If they are provided, persistence mode is assumed, * and a message ID is provided for the response message. */ originalMessages?: UI_MESSAGE[]; /** * Generate a message ID for the response message. * * If not provided, no message ID will be set for the response message (unless * the original messages are provided and the last message is an assistant message). */ generateMessageId?: IdGenerator; onFinish?: UIMessageStreamOnFinishCallback; /** * Extracts message metadata that will be send to the client. * * Called on `start` and `finish` events. */ messageMetadata?: (options: { part: TextStreamPart; }) => InferUIMessageMetadata | undefined; /** * Send reasoning parts to the client. * Default to true. */ sendReasoning?: boolean; /** * Send source parts to the client. * Default to false. */ sendSources?: boolean; /** * Send the finish event to the client. * Set to false if you are using additional streamText calls * that send additional data. * Default to true. */ sendFinish?: boolean; /** * Send the message start event to the client. * Set to false if you are using additional streamText calls * and the message start event has already been sent. * Default to true. */ sendStart?: boolean; /** * Process an error, e.g. to log it. Default to `() => 'An error occurred.'`. * * @returns error message to include in the data stream. */ onError?: (error: unknown) => string; }; export type ConsumeStreamOptions = { onError?: ErrorHandler; }; /** * A result object for accessing different stream types and additional information. */ export interface StreamTextResult< TOOLS extends ToolSet, OUTPUT extends Output, > { /** * The content that was generated in the last step. * * Automatically consumes the stream. */ readonly content: PromiseLike>>; /** * The full text that has been generated by the last step. * * Automatically consumes the stream. */ readonly text: PromiseLike; /** * The full reasoning that the model has generated. * * Automatically consumes the stream. */ readonly reasoning: PromiseLike>; /** * The reasoning that has been generated by the last step. * * Automatically consumes the stream. */ readonly reasoningText: PromiseLike; /** * Files that have been generated by the model in the last step. * * Automatically consumes the stream. */ readonly files: PromiseLike; /** * Sources that have been used as references in the last step. * * Automatically consumes the stream. */ readonly sources: PromiseLike; /** * The tool calls that have been executed in the last step. * * Automatically consumes the stream. */ readonly toolCalls: PromiseLike[]>; /** * The static tool calls that have been executed in the last step. * * Automatically consumes the stream. */ readonly staticToolCalls: PromiseLike[]>; /** * The dynamic tool calls that have been executed in the last step. * * Automatically consumes the stream. */ readonly dynamicToolCalls: PromiseLike; /** * The static tool results that have been generated in the last step. * * Automatically consumes the stream. */ readonly staticToolResults: PromiseLike[]>; /** * The dynamic tool results that have been generated in the last step. * * Automatically consumes the stream. */ readonly dynamicToolResults: PromiseLike; /** * The tool results that have been generated in the last step. * * Automatically consumes the stream. */ readonly toolResults: PromiseLike[]>; /** * The unified finish reason why the generation finished. Taken from the last step. * * Automatically consumes the stream. */ readonly finishReason: PromiseLike; /** * The raw reason why the generation finished (from the provider). Taken from the last step. * * Automatically consumes the stream. */ readonly rawFinishReason: PromiseLike; /** * The token usage of the last step. * * Automatically consumes the stream. */ readonly usage: PromiseLike; /** * The total token usage of the generated response. * When there are multiple steps, the usage is the sum of all step usages. * * Automatically consumes the stream. */ readonly totalUsage: PromiseLike; /** * Warnings from the model provider (e.g. unsupported settings) for the first step. * * Automatically consumes the stream. */ readonly warnings: PromiseLike; /** * Details for all steps. * You can use this to get information about intermediate steps, * such as the tool calls or the response headers. * * Automatically consumes the stream. */ readonly steps: PromiseLike>>; /** * Additional request information from the last step. * * Automatically consumes the stream. */ readonly request: PromiseLike; /** * Additional response information from the last step. * * Automatically consumes the stream. */ readonly response: PromiseLike< LanguageModelResponseMetadata & { /** * The response messages that were generated during the call. It consists of an assistant message, * potentially containing tool calls. * * When there are tool results, there is an additional tool message with the tool results that are available. * If there are tools that do not have execute functions, they are not included in the tool results and * need to be added separately. */ messages: Array; } >; /** * Additional provider-specific metadata from the last step. * Metadata is passed through from the provider to the AI SDK and * enables provider-specific results that can be fully encapsulated in the provider. */ readonly providerMetadata: PromiseLike; /** * A text stream that returns only the generated text deltas. You can use it * as either an AsyncIterable or a ReadableStream. When an error occurs, the * stream will throw the error. */ readonly textStream: AsyncIterableStream; /** * A stream with all events, including text deltas, tool calls, tool results, and * errors. * You can use it as either an AsyncIterable or a ReadableStream. * Only errors that stop the stream, such as network errors, are thrown. */ readonly fullStream: AsyncIterableStream>; /** * A stream of partial outputs. It uses the `output` specification. * * @deprecated Use `partialOutputStream` instead. */ readonly experimental_partialOutputStream: AsyncIterableStream< InferPartialOutput >; /** * A stream of partial parsed outputs. It uses the `output` specification. */ readonly partialOutputStream: AsyncIterableStream>; /** * A stream of individual array elements as they complete. * Only available when using `output: Output.array()`. */ readonly elementStream: AsyncIterableStream>; /** * The complete parsed output. It uses the `output` specification. */ readonly output: PromiseLike>; /** * Consumes the stream without processing the parts. * This is useful to force the stream to finish. * It effectively removes the backpressure and allows the stream to finish, * triggering the `onFinish` callback and the promise resolution. * * If an error occurs, it is passed to the optional `onError` callback. */ consumeStream(options?: ConsumeStreamOptions): PromiseLike; /** * Converts the result to a UI message stream. * * @returns A UI message stream. */ toUIMessageStream( options?: UIMessageStreamOptions, ): AsyncIterableStream>; /** * Writes UI message stream output to a Node.js response-like object. */ pipeUIMessageStreamToResponse( response: ServerResponse, options?: UIMessageStreamResponseInit & UIMessageStreamOptions, ): void; /** * Writes text delta output to a Node.js response-like object. * It sets a `Content-Type` header to `text/plain; charset=utf-8` and * writes each text delta as a separate chunk. * * @param response A Node.js response-like object (ServerResponse). * @param init Optional headers, status code, and status text. */ pipeTextStreamToResponse(response: ServerResponse, init?: ResponseInit): void; /** * Converts the result to a streamed response object with a stream data part stream. * * @returns A response object. */ toUIMessageStreamResponse( options?: UIMessageStreamResponseInit & UIMessageStreamOptions, ): Response; /** * Creates a simple text stream response. * Each text delta is encoded as UTF-8 and sent as a separate chunk. * Non-text-delta events are ignored. * @param init Optional headers, status code, and status text. */ toTextStreamResponse(init?: ResponseInit): Response; } export type TextStreamPart = | { type: 'text-start'; id: string; providerMetadata?: ProviderMetadata; } | { type: 'text-end'; id: string; providerMetadata?: ProviderMetadata; } | { type: 'text-delta'; id: string; providerMetadata?: ProviderMetadata; text: string; } | { type: 'reasoning-start'; id: string; providerMetadata?: ProviderMetadata; } | { type: 'reasoning-end'; id: string; providerMetadata?: ProviderMetadata; } | { type: 'reasoning-delta'; providerMetadata?: ProviderMetadata; id: string; text: string; } | { type: 'tool-input-start'; id: string; toolName: string; providerMetadata?: ProviderMetadata; providerExecuted?: boolean; dynamic?: boolean; title?: string; } | { type: 'tool-input-end'; id: string; providerMetadata?: ProviderMetadata; } | { type: 'tool-input-delta'; id: string; delta: string; providerMetadata?: ProviderMetadata; } | ({ type: 'source' } & Source) | { type: 'file'; file: GeneratedFile; providerMetadata?: ProviderMetadata } // different because of GeneratedFile object | ({ type: 'tool-call' } & TypedToolCall) | ({ type: 'tool-result' } & TypedToolResult) | ({ type: 'tool-error' } & TypedToolError) | ({ type: 'tool-output-denied' } & StaticToolOutputDenied) | ToolApprovalRequestOutput | { type: 'start-step'; request: LanguageModelRequestMetadata; warnings: CallWarning[]; } | { type: 'finish-step'; response: LanguageModelResponseMetadata; usage: LanguageModelUsage; finishReason: FinishReason; rawFinishReason: string | undefined; providerMetadata: ProviderMetadata | undefined; } | { type: 'start'; } | { type: 'finish'; finishReason: FinishReason; rawFinishReason: string | undefined; totalUsage: LanguageModelUsage; } | { type: 'abort'; reason?: string; } | { type: 'error'; error: unknown; } | { type: 'raw'; rawValue: unknown; };