Chat SDK

ChatProvider

Context provider that manages chat state, WebSocket connections, and event subscriptions.

Props

interface ChatProviderProps {
  authConfig: {
    sessionId: string;
    accessToken: string;
    refreshToken?: string;
  };
  children: ReactNode;
  debug?: boolean;
  initialWelcome?: ReactNode;
  markdownComponents?: Record<string, ComponentType>;
  typingAnimation?: {
    mode?: 'char' | 'word' | 'batch' | 'instant';
    speed?: number;
    batchSize?: number;
  };
  statusComponents?: Record<string, ComponentType>;
  forwardingHandlers?: ForwardingHandlers;
  enableHistory?: boolean;
  loadingComponent?: ComponentType;
  headerComponent?: ComponentType;
  allowThinking?: boolean;
  agentId?: string;
  refreshTokenCallback?: (token: string) => Promise<any>;
  onError?: (error: any) => void;
}

Usage

<ChatProvider
  authConfig={{
    sessionId: session.sessionId,
    accessToken: session.token,
    refreshToken: session.refreshToken
  }}
  debug={process.env.NODE_ENV === 'development'}
  enableHistory={true}
  agentId="customer-support"
  onError={(error) => {
    console.error('Chat error:', error);
  }}
>
  {children}
</ChatProvider>

Refresh Token Callback

Handle token refresh automatically:

<ChatProvider
  authConfig={authConfig}
  refreshTokenCallback={async (refreshToken) => {
    const response = await fetch('/api/token/refresh', {
      method: 'POST',
      body: JSON.stringify({ refreshToken })
    });
    return await response.json();
  }}
>
  {children}
</ChatProvider>

ChatPanel

Complete chat interface with message display and input.

Props

interface ChatPanelProps {
  onCreateSession?: () => void;
  isDark?: boolean;
  allowEditMessage?: boolean;
}

Usage

<ChatProvider authConfig={authConfig}>
  <ChatPanel
    onCreateSession={handleNewSession}
    isDark={false}
    allowEditMessage={true}
  />
</ChatProvider>

ChatCore

Message display component without input - for custom layouts.

Props

interface ChatCoreProps {
  isDark?: boolean;
  className?: string;
  allowEditMessage?: boolean;
  showWelcome?: boolean;
  showLoadMore?: boolean;
  showLoadingIndicator?: boolean;
  welcomeComponent?: ComponentType;
  loadingComponent?: ComponentType;
  containerStyle?: React.CSSProperties;
  useGradientMask?: boolean;
  gradientMaskStyle?: string;
}

Ref API

interface ChatCoreRef {
  scrollToBottom: () => void;
  isAtBottom: () => boolean;
  scrollContainer: HTMLDivElement | null;
  virtualizer: any;
  sendMessage: (data?: SendMessageParams) => Promise<void>;
  abort: () => any;
  isStreaming: boolean;
  isLoading: boolean;
  messages: any[];
  messageManager: MessageManager;
}

Usage

import { useRef } from 'react';
import { ChatCore } from 'react-chat-agent';

function CustomLayout() {
  const coreRef = useRef();

  return (
    <div className="flex flex-col h-screen">
      <header>My Chat App</header>
      <ChatCore
        ref={coreRef}
        className="flex-1"
        isDark={true}
        showWelcome={true}
      />
      <footer>
        <button onClick={() => coreRef.current?.scrollToBottom()}>
          Scroll to Bottom
        </button>
      </footer>
    </div>
  );
}

ChatInput

Message input component with file attachments.

Props

interface ChatInputProps {
  onSend?: (message: string, files?: AttachedFile[]) => void;
  disabled?: boolean;
  placeholder?: string;
}

Usage

import { ChatInput, useChatContext } from 'react-chat-agent';

function CustomInput() {
  const { sendMsg } = useChatContext();

  const handleSend = async (message, files) => {
    await sendMsg({ message, attachedFiles: files });
  };

  return (
    <ChatInput
      onSend={handleSend}
      placeholder="Type your message..."
      disabled={false}
    />
  );
}

MessageItem

Individual message display component.

Props

interface MessageItemProps {
  message: Message;
  isLast?: boolean;
  theme?: string;
}

Usage

import { MessageItem } from 'react-chat-agent';

function CustomMessageList({ messages }) {
  return (
    <div>
      {messages.map((msg, i) => (
        <MessageItem
          key={msg.id}
          message={msg}
          isLast={i === messages.length - 1}
          theme="dark"
        />
      ))}
    </div>
  );
}

StartChat

Welcome screen component.

Props

interface StartChatProps {
  error?: any;
  miniMode?: boolean;
}

Usage

import { StartChat } from 'react-chat-agent';

<ChatProvider
  authConfig={authConfig}
  initialWelcome={<StartChat miniMode={false} />}
>
  <ChatPanel />
</ChatProvider>

LoadingResponse

Loading indicator for streaming responses.

Props

interface LoadingResponseProps {
  type?: 'text' | 'dots';
}

Usage

import { LoadingResponse } from 'react-chat-agent';

<ChatProvider
  authConfig={authConfig}
  loadingComponent={() => <LoadingResponse type="dots" />}
>
  <ChatPanel />
</ChatProvider>

StatusBlock

Display status updates and tool executions.

Props

interface StatusBlockProps {
  status?: any;
  message?: any;
}

Usage

import { StatusBlock } from 'react-chat-agent';

const statusComponents = {
  tool_call: (props) => <StatusBlock {...props} />,
};

<ChatProvider
  authConfig={authConfig}
  statusComponents={statusComponents}
>
  <ChatPanel />
</ChatProvider>

Custom Welcome Component

function CustomWelcome() {
  return (
    <div className="welcome">
      <h2>Welcome to Support Chat</h2>
      <p>How can we help you today?</p>
      <div className="suggested-prompts">
        <button>Check order status</button>
        <button>Technical support</button>
        <button>Billing question</button>
      </div>
    </div>
  );
}

<ChatProvider
  authConfig={authConfig}
  initialWelcome={<CustomWelcome />}
>
  <ChatPanel />
</ChatProvider>

Custom Loading Component

function CustomLoading() {
  return (
    <div className="loading">
      <div className="spinner" />
      <p>Agent is thinking...</p>
    </div>
  );
}

<ChatProvider
  authConfig={authConfig}
  loadingComponent={CustomLoading}
>
  <ChatPanel />
</ChatProvider>

Layout Examples

Split Layout

function SplitLayout() {
  return (
    <div className="flex h-screen">
      <aside className="w-64 bg-gray-100">
        <h3>Conversations</h3>
        {/* Conversation list */}
      </aside>
      <main className="flex-1">
        <ChatProvider authConfig={authConfig}>
          <ChatPanel />
        </ChatProvider>
      </main>
    </div>
  );
}
function ModalChat({ isOpen, onClose }) {
  if (!isOpen) return null;

  return (
    <div className="modal-overlay">
      <div className="modal-content h-96 w-96">
        <button onClick={onClose}>Close</button>
        <ChatProvider authConfig={authConfig}>
          <ChatPanel />
        </ChatProvider>
      </div>
    </div>
  );
}

Custom Header

function ChatWithHeader() {
  return (
    <ChatProvider authConfig={authConfig}>
      <div className="flex flex-col h-screen">
        <header className="p-4 border-b">
          <h1>Customer Support</h1>
          <p>Online</p>
        </header>
        <ChatCore className="flex-1" />
        <ChatInput />
      </div>
    </ChatProvider>
  );
}

Next Steps