Skip to content
npm version

React: AI streaming helper functions ​

This page introduces two React helper functions: useAIChat and useAICompletion. Both support two streaming protocols — Text and Data — through a unified protocol option, so you can switch protocols without changing business logic. Control methods and state are consistent across chat and completion, making reuse easy.

Core features:

  • Protocol selection: protocol: 'text' | 'data'
  • Chat mode: supports context memory and message history
  • Completion mode: single-shot text generation
  • Control methods: append / complete / reload / stop / reset
  • State and error handling: isLoading / error / messages / completion

For message callback details — the full signatures, parsing, and trigger conditions of onMessage and onDataMessage — please read “Streaming” in the guide. This page focuses on their relationship to the React hooks and where to use them.

Configuration Example ​

Connect the backend through “send functions”, then select controller methods based on the chosen protocol. In your HTTP client, set responseType: 'stream' so the frontend can consume responses as streams.

ts
import { _http, type StreamProtocol } from 'vtzac';
import { useAIChat, useAICompletion } from 'vtzac/react';
import { AiSdkController } from 'nestjs-example/src/ai-sdk.controller';

// Initialize HTTP client (make sure to set responseType: 'stream')
const { controller } = _http({
  ofetchOptions: { baseURL: 'http://localhost:3000', responseType: 'stream' },
});
const aiSdk = controller(AiSdkController);

// Select chat send function by protocol
const getChatSender = (protocol: StreamProtocol) => {
  switch (protocol) {
    case 'text':
      return messages => aiSdk.chat({ messages });
    case 'data':
      return messages => aiSdk.chatUI({ messages });
  }
};

// Select completion send function by protocol
const getCompletionSender = (protocol: StreamProtocol) => {
  switch (protocol) {
    case 'text':
      return prompt => aiSdk.completion({ prompt });
    case 'data':
      return prompt => aiSdk.completionUI({ prompt });
  }
};

Basic Usage ​

Chat mode (useAIChat):

ts
// Initialize chat hook with the data protocol
const chat = useAIChat(getChatSender('data'), {
  protocol: 'data',
  initialMessages: [
    { id: '1', role: 'assistant', parts: [{ type: 'text', text: 'Hello!' }] },
  ],
});

// Send a message
await chat.append('Hello, tell me about Chengdu');

// Control operations
chat.stop(); // Stop current generation
chat.reset(); // Reset conversation
chat.reload(); // Regenerate the last message

// State access
console.log(chat.messages);
console.log(chat.isLoading);
console.log(chat.error);

Completion mode (useAICompletion):

ts
// Initialize completion hook with the text protocol
const completion = useAICompletion(getCompletionSender('text'), {
  protocol: 'text',
});

// Start a text generation
await completion.complete('Tell me about Chengdu');

// Control operations
completion.stop(); // Stop generation
completion.reset(); // Clear generated content

// State access
console.log(completion.completion);
console.log(completion.isLoading);
console.log(completion.error);

For the fields and parsing of callbacks (such as onMessage), please read “Streaming” in the guide.

Best Practices ​

  • Protocol selection:
    • data: Matches mainstream AI SDK default data streams; ideal for UI Message-driven chat. Messages are JSON text (parsed objects).
    • text: Plain text incremental transmission, suitable for lightweight or fallback scenarios.
  • Reuse the same hook when switching protocols; only adjust protocol and the send function mapping.
  • On the frontend, set responseType: 'stream' to enable streaming consumption.
  • Centralize parsing logic (especially JSON parsing) inside event handlers to avoid redundant parsing in business code.

API Reference ​

useAIChat ​

Function signature: useAIChat(send: (messages: UIMessage[]) => PromiseLike<any>, options?: UseAIChatOptions): UseAIChatReturn

Parameters:

ParameterTypeRequiredDescription
send(messages: UIMessage[]) => PromiseLike<any>YesSend function that receives the message list and returns a Promise
optionsUseAIChatOptionsNoConfiguration options (protocol, initial messages, callbacks)

UseAIChatOptions:

PropertyTypeRequiredDefaultDescription
protocolStreamProtocolNo'data'Streaming protocol: 'text' | 'data'
initialMessagesUIMessage[]No[]Initial message list
onMessage(ev: any) => voidNo-Streaming message callback; see “Streaming” for details
onDataMessage(data: Record<string,string>) => voidNo-Data message callback; see “Streaming” for details
onFinish(message: UIMessage) => voidNo-Completion callback, receives the final message
onError(err: Error) => voidNo-Error callback

UseAIChatReturn:

PropertyTypeDescription
messagesUIMessage[]Current message list
isLoadingbooleanWhether currently generating
errorError | nullError information, null when none
append(content: string) => Promise<void>Send a new message
reload() => Promise<void>Regenerate the last message
stop() => voidStop current generation
reset() => voidReset chat state, clear messages

useAICompletion ​

Function signature: useAICompletion(send: (prompt: string) => PromiseLike<any>, options?: UseAICompletionOptions): UseAICompletionReturn

Parameters:

ParameterTypeRequiredDescription
send(prompt: string) => PromiseLike<any>YesSend function that receives the prompt and returns a Promise
optionsUseAICompletionOptionsNoConfiguration options (protocol, callbacks)

UseAICompletionOptions:

PropertyTypeRequiredDefaultDescription
protocolStreamProtocolNo'data'Streaming protocol: 'text' | 'data'
onMessage(ev: any) => voidNo-Streaming message callback; see “Streaming” for details
onDataMessage(data: Record<string,string>) => voidNo-Data message callback; see “Streaming” for details
onFinish(completion: string) => voidNo-Completion callback, receives the final text
onError(err: Error) => voidNo-Error callback

UseAICompletionReturn:

PropertyTypeDescription
completionstringCurrent generated text content
isLoadingbooleanWhether currently generating
errorError | nullError information, null when none
complete(prompt: string) => Promise<void>Initiate a text generation
stop() => voidStop current generation
reset() => voidReset state, clear generated content

Type Definitions ​

StreamProtocol ​

Two supported streaming protocol types:

ValueDescription
'text'Plain text byte stream, suitable for simplified transmission
'data'Data stream (JSON text fragments), consistent with mainstream AI SDKs

UIMessage ​

Message object type from the ai package’s standard message format. Refer to the corresponding SDK documentation for structure details.

Events & Message Callbacks ​

  • For the usage, fields, parsing, and trigger conditions of onMessage and onDataMessage, read “Streaming”.
  • In the React hooks, pass them via options.onMessage / options.onDataMessage; parsing logic follows the “Streaming” rules.
  • End marker: the last message of the stream is fixed as data: [DONE].

Next Steps ​

  • To dive deeper into protocol differences and callback behavior, read “Streaming”.
  • Ensure the backend returns responses with responseType: 'stream'; the frontend completes interactions via the send-function mapping and hooks described on this page.