import { ServerResponse } from 'node:http';

interface FunctionCall {
    /**
     * The arguments to call the function with, as generated by the model in JSON
     * format. Note that the model does not always generate valid JSON, and may
     * hallucinate parameters not defined by your function schema. Validate the
     * arguments in your code before calling your function.
     */
    arguments?: string;
    /**
     * The name of the function to call.
     */
    name?: string;
}
interface Function {
    /**
     * The name of the function to be called. Must be a-z, A-Z, 0-9, or contain
     * underscores and dashes, with a maximum length of 64.
     */
    name: string;
    /**
     * The parameters the functions accepts, described as a JSON Schema object. See the
     * [guide](/docs/guides/gpt/function-calling) for examples, and the
     * [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for
     * documentation about the format.
     *
     * To describe a function that accepts no parameters, provide the value
     * `{"type": "object", "properties": {}}`.
     */
    parameters: Record<string, unknown>;
    /**
     * A description of what the function does, used by the model to choose when and
     * how to call the function.
     */
    description?: string;
}
/**
 * Shared types between the API and UI packages.
 */
interface Message {
    id: string;
    createdAt?: Date;
    content: string;
    role: 'system' | 'user' | 'assistant' | 'function';
    /**
     * If the message has a role of `function`, the `name` field is the name of the function.
     * Otherwise, the name field should not be set.
     */
    name?: string;
    /**
     * If the assistant role makes a function call, the `function_call` field
     * contains the function call name and arguments. Otherwise, the field should
     * not be set.
     */
    function_call?: string | FunctionCall;
}
type CreateMessage = Omit<Message, 'id'> & {
    id?: Message['id'];
};
type ChatRequest = {
    messages: Message[];
    options?: RequestOptions;
    functions?: Array<Function>;
    function_call?: FunctionCall;
};
type FunctionCallHandler = (chatMessages: Message[], functionCall: FunctionCall) => Promise<ChatRequest | void>;
type RequestOptions = {
    headers?: Record<string, string> | Headers;
    body?: object;
};
type ChatRequestOptions = {
    options?: RequestOptions;
    functions?: Array<Function>;
    function_call?: FunctionCall;
};
type UseChatOptions = {
    /**
     * The API endpoint that accepts a `{ messages: Message[] }` object and returns
     * a stream of tokens of the AI chat response. Defaults to `/api/chat`.
     */
    api?: string;
    /**
     * A unique identifier for the chat. If not provided, a random one will be
     * generated. When provided, the `useChat` hook with the same `id` will
     * have shared states across components.
     */
    id?: string;
    /**
     * Initial messages of the chat. Useful to load an existing chat history.
     */
    initialMessages?: Message[];
    /**
     * Initial input of the chat.
     */
    initialInput?: string;
    /**
     * Callback function to be called when a function call is received.
     * If the function returns a `ChatRequest` object, the request will be sent
     * automatically to the API and will be used to update the chat.
     */
    experimental_onFunctionCall?: FunctionCallHandler;
    /**
     * Callback function to be called when the API response is received.
     */
    onResponse?: (response: Response) => void | Promise<void>;
    /**
     * Callback function to be called when the chat is finished streaming.
     */
    onFinish?: (message: Message) => void;
    /**
     * Callback function to be called when an error is encountered.
     */
    onError?: (error: Error) => void;
    /**
     * The credentials mode to be used for the fetch request.
     * Possible values are: 'omit', 'same-origin', 'include'.
     * Defaults to 'same-origin'.
     */
    credentials?: RequestCredentials;
    /**
     * HTTP headers to be sent with the API request.
     */
    headers?: Record<string, string> | Headers;
    /**
     * Extra body object to be sent with the API request.
     * @example
     * Send a `sessionId` to the API along with the messages.
     * ```js
     * useChat({
     *   body: {
     *     sessionId: '123',
     *   }
     * })
     * ```
     */
    body?: object;
    /**
     * Whether to send extra message fields such as `message.id` and `message.createdAt` to the API.
     * Defaults to `false`. When set to `true`, the API endpoint might need to
     * handle the extra fields before forwarding the request to the AI service.
     */
    sendExtraMessageFields?: boolean;
    /** Whether to send the entire chat history to the API. Defaults to `true`. */
    sendHistory?: boolean;
};
type UseCompletionOptions = {
    /**
     * The API endpoint that accepts a `{ prompt: string }` object and returns
     * a stream of tokens of the AI completion response. Defaults to `/api/completion`.
     */
    api?: string;
    /**
     * An unique identifier for the chat. If not provided, a random one will be
     * generated. When provided, the `useChat` hook with the same `id` will
     * have shared states across components.
     */
    id?: string;
    /**
     * Initial prompt input of the completion.
     */
    initialInput?: string;
    /**
     * Initial completion result. Useful to load an existing history.
     */
    initialCompletion?: string;
    /**
     * Callback function to be called when the API response is received.
     */
    onResponse?: (response: Response) => void | Promise<void>;
    /**
     * Callback function to be called when the completion is finished streaming.
     */
    onFinish?: (prompt: string, completion: string) => void;
    /**
     * Callback function to be called when an error is encountered.
     */
    onError?: (error: Error) => void;
    /**
     * The credentials mode to be used for the fetch request.
     * Possible values are: 'omit', 'same-origin', 'include'.
     * Defaults to 'same-origin'.
     */
    credentials?: RequestCredentials;
    /**
     * HTTP headers to be sent with the API request.
     */
    headers?: Record<string, string> | Headers;
    /**
     * Extra body object to be sent with the API request.
     * @example
     * Send a `sessionId` to the API along with the prompt.
     * ```js
     * useChat({
     *   body: {
     *     sessionId: '123',
     *   }
     * })
     * ```
     */
    body?: object;
};
type JSONValue = null | string | number | boolean | {
    [x: string]: JSONValue;
} | Array<JSONValue>;

type OpenAIStreamCallbacks = AIStreamCallbacksAndOptions & {
    /**
     * @example
     * ```js
     * const response = await openai.chat.completions.create({
     *   model: 'gpt-3.5-turbo-0613',
     *   stream: true,
     *   messages,
     *   functions,
     * })
     *
     * const stream = OpenAIStream(response, {
     *   experimental_onFunctionCall: async (functionCallPayload, createFunctionCallMessages) => {
     *     // ... run your custom logic here
     *     const result = await myFunction(functionCallPayload)
     *
     *     // Ask for another completion, or return a string to send to the client as an assistant message.
     *     return await openai.chat.completions.create({
     *       model: 'gpt-3.5-turbo-0613',
     *       stream: true,
     *       // Append the relevant "assistant" and "function" call messages
     *       messages: [...messages, ...createFunctionCallMessages(result)],
     *       functions,
     *     })
     *   }
     * })
     * ```
     */
    experimental_onFunctionCall?: (functionCallPayload: FunctionCallPayload, createFunctionCallMessages: (functionCallResult: JSONValue) => CreateMessage[]) => Promise<Response | undefined | void | string | AsyncIterableOpenAIStreamReturnTypes>;
};
interface ChatCompletionChunk {
    id: string;
    choices: Array<ChatCompletionChunkChoice>;
    created: number;
    model: string;
    object: string;
}
interface ChatCompletionChunkChoice {
    delta: ChoiceDelta;
    finish_reason: 'stop' | 'length' | 'function_call' | 'content_filter' | null;
    index: number;
}
interface ChoiceDelta {
    /**
     * The contents of the chunk message.
     */
    content?: string | null;
    /**
     * The name and arguments of a function that should be called, as generated by the
     * model.
     */
    function_call?: FunctionCall;
    /**
     * The role of the author of this message.
     */
    role?: 'system' | 'user' | 'assistant' | 'function';
}
/**
 * https://github.com/openai/openai-node/blob/3ec43ee790a2eb6a0ccdd5f25faa23251b0f9b8e/src/resources/completions.ts#L28C1-L64C1
 * Completions API. Streamed and non-streamed responses are the same.
 */
interface Completion {
    /**
     * A unique identifier for the completion.
     */
    id: string;
    /**
     * The list of completion choices the model generated for the input prompt.
     */
    choices: Array<CompletionChoice>;
    /**
     * The Unix timestamp of when the completion was created.
     */
    created: number;
    /**
     * The model used for completion.
     */
    model: string;
    /**
     * The object type, which is always "text_completion"
     */
    object: string;
    /**
     * Usage statistics for the completion request.
     */
    usage?: CompletionUsage;
}
interface CompletionChoice {
    /**
     * The reason the model stopped generating tokens. This will be `stop` if the model
     * hit a natural stop point or a provided stop sequence, or `length` if the maximum
     * number of tokens specified in the request was reached.
     */
    finish_reason: 'stop' | 'length' | 'content_filter';
    index: number;
    logprobs: any | null;
    text: string;
}
interface CompletionUsage {
    /**
     * Usage statistics for the completion request.
     */
    /**
     * Number of tokens in the generated completion.
     */
    completion_tokens: number;
    /**
     * Number of tokens in the prompt.
     */
    prompt_tokens: number;
    /**
     * Total number of tokens used in the request (prompt + completion).
     */
    total_tokens: number;
}
type AsyncIterableOpenAIStreamReturnTypes = AsyncIterable<ChatCompletionChunk> | AsyncIterable<Completion>;
declare function OpenAIStream(res: Response | AsyncIterableOpenAIStreamReturnTypes, callbacks?: OpenAIStreamCallbacks): ReadableStream;

interface FunctionCallPayload {
    name: string;
    arguments: Record<string, unknown>;
}
/**
 * Configuration options and helper callback methods for AIStream stream lifecycle events.
 * @interface
 */
interface AIStreamCallbacksAndOptions {
    /** `onStart`: Called once when the stream is initialized. */
    onStart?: () => Promise<void> | void;
    /** `onCompletion`: Called for each tokenized message. */
    onCompletion?: (completion: string) => Promise<void> | void;
    /** `onFinal`: Called once when the stream is closed with the final completion message. */
    onFinal?: (completion: string) => Promise<void> | void;
    /** `onToken`: Called for each tokenized message. */
    onToken?: (token: string) => Promise<void> | void;
    /**
     * A flag for enabling the experimental_StreamData class and the new protocol.
     * @see https://github.com/vercel-labs/ai/pull/425
     *
     * When StreamData is rolled out, this will be removed and the new protocol will be used by default.
     */
    experimental_streamData?: boolean;
}
/**
 * Custom parser for AIStream data.
 * @interface
 */
interface AIStreamParser {
    (data: string): string | void;
}
/**
 * Creates a TransformStream that parses events from an EventSource stream using a custom parser.
 * @param {AIStreamParser} customParser - Function to handle event data.
 * @returns {TransformStream<Uint8Array, string>} TransformStream parsing events.
 */
declare function createEventStreamTransformer(customParser?: AIStreamParser): TransformStream<Uint8Array, string>;
/**
 * Creates a transform stream that encodes input messages and invokes optional callback functions.
 * The transform stream uses the provided callbacks to execute custom logic at different stages of the stream's lifecycle.
 * - `onStart`: Called once when the stream is initialized.
 * - `onToken`: Called for each tokenized message.
 * - `onCompletion`: Called every time an AIStream completion message is received. This can occur multiple times when using e.g. OpenAI functions
 * - `onFinal`: Called once when the stream is closed with the final completion message.
 *
 * This function is useful when you want to process a stream of messages and perform specific actions during the stream's lifecycle.
 *
 * @param {AIStreamCallbacksAndOptions} [callbacks] - An object containing the callback functions.
 * @return {TransformStream<string, Uint8Array>} A transform stream that encodes input messages as Uint8Array and allows the execution of custom logic through callbacks.
 *
 * @example
 * const callbacks = {
 *   onStart: async () => console.log('Stream started'),
 *   onToken: async (token) => console.log(`Token: ${token}`),
 *   onCompletion: async (completion) => console.log(`Completion: ${completion}`)
 *   onFinal: async () => data.close()
 * };
 * const transformer = createCallbacksTransformer(callbacks);
 */
declare function createCallbacksTransformer(cb: AIStreamCallbacksAndOptions | OpenAIStreamCallbacks | undefined): TransformStream<string, Uint8Array>;
/**
 * Returns a stateful function that, when invoked, trims leading whitespace
 * from the input text. The trimming only occurs on the first invocation, ensuring that
 * subsequent calls do not alter the input text. This is particularly useful in scenarios
 * where a text stream is being processed and only the initial whitespace should be removed.
 *
 * @return {function(string): string} A function that takes a string as input and returns a string
 * with leading whitespace removed if it is the first invocation; otherwise, it returns the input unchanged.
 *
 * @example
 * const trimStart = trimStartOfStreamHelper();
 * const output1 = trimStart("   text"); // "text"
 * const output2 = trimStart("   text"); // "   text"
 *
 */
declare function trimStartOfStreamHelper(): (text: string) => string;
/**
 * Returns a ReadableStream created from the response, parsed and handled with custom logic.
 * The stream goes through two transformation stages, first parsing the events and then
 * invoking the provided callbacks.
 *
 * For 2xx HTTP responses:
 * - The function continues with standard stream processing.
 *
 * For non-2xx HTTP responses:
 * - If the response body is defined, it asynchronously extracts and decodes the response body.
 * - It then creates a custom ReadableStream to propagate a detailed error message.
 *
 * @param {Response} response - The response.
 * @param {AIStreamParser} customParser - The custom parser function.
 * @param {AIStreamCallbacksAndOptions} callbacks - The callbacks.
 * @return {ReadableStream} The AIStream.
 * @throws Will throw an error if the response is not OK.
 */
declare function AIStream(response: Response, customParser?: AIStreamParser, callbacks?: AIStreamCallbacksAndOptions): ReadableStream<Uint8Array>;
/**
 * Implements ReadableStream.from(asyncIterable), which isn't documented in MDN and isn't implemented in node.
 * https://github.com/whatwg/streams/commit/8d7a0bf26eb2cc23e884ddbaac7c1da4b91cf2bc
 */
declare function readableFromAsyncIterable<T>(iterable: AsyncIterable<T>): ReadableStream<T>;

/**
 * A stream wrapper to send custom JSON-encoded data back to the client.
 */
declare class experimental_StreamData {
    private encoder;
    private controller;
    stream: TransformStream<Uint8Array, Uint8Array>;
    private isClosedPromise;
    private isClosedPromiseResolver;
    private isClosed;
    private data;
    constructor();
    close(): Promise<void>;
    append(value: JSONValue): void;
}
/**
 * A TransformStream for LLMs that do not have their own transform stream handlers managing encoding (e.g. OpenAIStream has one for function call handling).
 * This assumes every chunk is a 'text' chunk.
 */
declare function createStreamDataTransformer(experimental_streamData: boolean | undefined): TransformStream<any, any>;

/**
 * A utility class for streaming text responses.
 */
declare class StreamingTextResponse extends Response {
    constructor(res: ReadableStream, init?: ResponseInit, data?: experimental_StreamData);
}
/**
 * A utility function to stream a ReadableStream to a Node.js response-like object.
 */
declare function streamToResponse(res: ReadableStream, response: ServerResponse, init?: {
    headers?: Record<string, string>;
    status?: number;
}): void;

declare function HuggingFaceStream(res: AsyncGenerator<any>, callbacks?: AIStreamCallbacksAndOptions): ReadableStream;

declare function CohereStream(reader: Response, callbacks?: AIStreamCallbacksAndOptions): ReadableStream;

interface CompletionChunk {
    /**
     * The resulting completion up to and excluding the stop sequences.
     */
    completion: string;
    /**
     * The model that performed the completion.
     */
    model: string;
    /**
     * The reason that we stopped sampling.
     *
     * This may be one the following values:
     *
     * - `"stop_sequence"`: we reached a stop sequence — either provided by you via the
     *   `stop_sequences` parameter, or a stop sequence built into the model
     * - `"max_tokens"`: we exceeded `max_tokens_to_sample` or the model's maximum
     */
    stop_reason: string;
}
/**
 * Accepts either a fetch Response from the Anthropic `POST /v1/complete` endpoint,
 * or the return value of `await client.completions.create({ stream: true })`
 * from the `@anthropic-ai/sdk` package.
 */
declare function AnthropicStream(res: Response | AsyncIterable<CompletionChunk>, cb?: AIStreamCallbacksAndOptions): ReadableStream;

declare function LangChainStream(callbacks?: AIStreamCallbacksAndOptions): {
    stream: ReadableStream<any>;
    writer: WritableStreamDefaultWriter<any>;
    handlers: {
        handleLLMNewToken: (token: string) => Promise<void>;
        handleLLMStart: (_llm: any, _prompts: string[], runId: string) => Promise<void>;
        handleLLMEnd: (_output: any, runId: string) => Promise<void>;
        handleLLMError: (e: Error, runId: string) => Promise<void>;
        handleChainStart: (_chain: any, _inputs: any, runId: string) => Promise<void>;
        handleChainEnd: (_outputs: any, runId: string) => Promise<void>;
        handleChainError: (e: Error, runId: string) => Promise<void>;
        handleToolStart: (_tool: any, _input: string, runId: string) => Promise<void>;
        handleToolEnd: (_output: string, runId: string) => Promise<void>;
        handleToolError: (e: Error, runId: string) => Promise<void>;
    };
};

interface Prediction {
    id: string;
    status: 'starting' | 'processing' | 'succeeded' | 'failed' | 'canceled';
    version: string;
    input: object;
    output?: any;
    source: 'api' | 'web';
    error?: any;
    logs?: string;
    metrics?: {
        predict_time?: number;
    };
    webhook?: string;
    webhook_events_filter?: ('start' | 'output' | 'logs' | 'completed')[];
    created_at: string;
    updated_at?: string;
    completed_at?: string;
    urls: {
        get: string;
        cancel: string;
        stream?: string;
    };
}
/**
 * Stream predictions from Replicate.
 * Only certain models are supported and you must pass `stream: true` to
 * replicate.predictions.create().
 * @see https://github.com/replicate/replicate-javascript#streaming
 *
 * @example
 * const response = await replicate.predictions.create({
 *  stream: true,
 *  input: {
 *    prompt: messages.join('\n')
 *  },
 *  version: '2c1608e18606fad2812020dc541930f2d0495ce32eee50074220b87300bc16e1'
 * })
 *
 * const stream = await ReplicateStream(response)
 * return new StreamingTextResponse(stream)
 *
 */
declare function ReplicateStream(res: Prediction, cb?: AIStreamCallbacksAndOptions): Promise<ReadableStream>;

declare const nanoid: (size?: number | undefined) => string;
declare function createChunkDecoder(complex?: boolean): (chunk: Uint8Array | undefined) => any;

/**
 * The map of prefixes for data in the stream
 *
 * - 0: Text from the LLM response
 * - 1: (OpenAI) function_call responses
 * - 2: custom JSON added by the user using `Data`
 *
 * Example:
 * ```
 * 0:Vercel
 * 0:'s
 * 0: AI
 * 0: AI
 * 0: SDK
 * 0: is great
 * 0:!
 * 2: { "someJson": "value" }
 * 1: {"function_call": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}
 *```
 */
declare const StreamStringPrefixes: {
    readonly text: 0;
    readonly function_call: 1;
    readonly data: 2;
};
declare const isStreamStringEqualToType: (type: keyof typeof StreamStringPrefixes, value: string) => value is `0:${string}\n` | `1:${string}\n` | `2:${string}\n`;
/**
 * Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it, and appends a new line.
 */
declare const getStreamString: (type: keyof typeof StreamStringPrefixes, value: JSONValue) => StreamString;
type StreamString = `${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\n`;
declare const getStreamStringTypeAndValue: (line: string) => {
    type: keyof typeof StreamStringPrefixes;
    value: string;
};
/**
 * A header sent to the client so it knows how to handle parsing the stream (as a deprecated text response or using the new prefixed protocol)
 */
declare const COMPLEX_HEADER = "X-Experimental-Stream-Data";

export { AIStream, AIStreamCallbacksAndOptions, AIStreamParser, AnthropicStream, COMPLEX_HEADER, ChatRequest, ChatRequestOptions, CohereStream, CompletionUsage, CreateMessage, FunctionCall, FunctionCallHandler, FunctionCallPayload, HuggingFaceStream, JSONValue, LangChainStream, Message, OpenAIStream, OpenAIStreamCallbacks, ReplicateStream, RequestOptions, StreamString, StreamStringPrefixes, StreamingTextResponse, UseChatOptions, UseCompletionOptions, createCallbacksTransformer, createChunkDecoder, createEventStreamTransformer, createStreamDataTransformer, experimental_StreamData, getStreamString, getStreamStringTypeAndValue, isStreamStringEqualToType, nanoid, readableFromAsyncIterable, streamToResponse, trimStartOfStreamHelper };
