CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-copilotkit--react-ui

Production-ready React UI components library for building deeply-integrated AI assistants and copilots

Overview
Eval results
Files

chat-components.mddocs/

Chat Interface Components

Three production-ready chat layouts providing different UI patterns for integrating AI assistants into React applications. All layouts share the same core functionality with different presentation styles.

Capabilities

CopilotChat

Main embedded chat component for displaying a chat interface directly in your application. Provides a fully-featured chat panel with message history, input controls, and customizable UI elements.

/**
 * Main chatbot panel component for embedding directly in your application
 * @param props - Configuration props for the chat interface
 * @returns Rendered chat component
 */
function CopilotChat(props: CopilotChatProps): JSX.Element;

interface CopilotChatProps {
  /** Custom instructions for the system message */
  instructions?: string;

  /** Suggestion behavior: "auto" (AI-generated), "manual" (programmatic), or static array */
  suggestions?: ChatSuggestions;

  /** Callback when generation state changes */
  onInProgress?: (inProgress: boolean) => void;

  /** Callback when user submits a message */
  onSubmitMessage?: (message: string) => void | Promise<void>;

  /** Custom stop generation handler */
  onStopGeneration?: OnStopGeneration;

  /** Custom reload/regenerate handler */
  onReloadMessages?: OnReloadMessages;

  /** Callback when message is regenerated */
  onRegenerate?: (messageId: string) => void;

  /** Callback when message is copied to clipboard */
  onCopy?: (message: string) => void;

  /** Callback for positive feedback */
  onThumbsUp?: (message: Message) => void;

  /** Callback for negative feedback */
  onThumbsDown?: (message: Message) => void;

  /** Custom markdown component renderers */
  markdownTagRenderers?: ComponentsMap;

  /** Custom icon overrides */
  icons?: CopilotChatIcons;

  /** Custom label/text overrides */
  labels?: CopilotChatLabels;

  /** Enable image upload functionality (default: false) */
  imageUploadsEnabled?: boolean;

  /** File input accept attribute (default: "image/*") */
  inputFileAccept?: string;

  /** Override system message generation */
  makeSystemMessage?: SystemMessageFunction;

  /** Disable system message entirely */
  disableSystemMessage?: boolean;

  /** Custom assistant message component */
  AssistantMessage?: React.ComponentType<AssistantMessageProps>;

  /** Custom user message component */
  UserMessage?: React.ComponentType<UserMessageProps>;

  /** Custom error message component */
  ErrorMessage?: React.ComponentType<ErrorMessageProps>;

  /** Custom messages container component */
  Messages?: React.ComponentType<MessagesProps>;

  /** Custom message renderer */
  RenderMessage?: React.ComponentType<RenderMessageProps>;

  /** Custom suggestions list renderer */
  RenderSuggestionsList?: React.ComponentType<RenderSuggestionsListProps>;

  /** Custom input component */
  Input?: React.ComponentType<InputProps>;

  /** Custom image renderer */
  ImageRenderer?: React.ComponentType<ImageRendererProps>;

  /** Additional CSS class */
  className?: string;

  /** Child elements */
  children?: React.ReactNode;

  /** Hide the stop generation button */
  hideStopButton?: boolean;

  /** Event tracking hooks (requires publicApiKey in CopilotKit provider) */
  observabilityHooks?: CopilotObservabilityHooks;

  /** Custom error renderer */
  renderError?: (error: {
    message: string;
    operation?: string;
    timestamp: number;
    onDismiss: () => void;
    onRetry?: () => void;
  }) => React.ReactNode;

  /** Error handler for debugging */
  onError?: CopilotErrorHandler;
}

type ChatSuggestions = "auto" | "manual" | SuggestionItem[];

interface SuggestionItem {
  title: string;
  message: string;
  partial?: boolean;
  className?: string;
}

Usage Example:

import { CopilotChat } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

function MyApp() {
  return (
    <div className="app-container">
      <main className="content">
        {/* Your app content */}
      </main>
      <aside className="chat-panel">
        <CopilotChat
          instructions="You are a helpful assistant for project management."
          labels={{
            title: "Project Assistant",
            initial: "Hi! I can help you manage your projects.",
            placeholder: "Ask about your projects...",
          }}
          onSubmitMessage={(message) => {
            console.log("User sent:", message);
          }}
          onThumbsUp={(message) => {
            console.log("User liked:", message.id);
          }}
        />
      </aside>
    </div>
  );
}

CopilotPopup

Popup/modal version of the chat interface that displays as a floating window. Can be opened and closed by users, with keyboard shortcuts and customizable triggers.

/**
 * Popup/modal version of the chat interface
 * @param props - Configuration props extending CopilotChatProps with modal-specific options
 * @returns Rendered popup component with toggle button
 */
function CopilotPopup(props: CopilotModalProps): JSX.Element;

interface CopilotModalProps extends CopilotChatProps {
  /** Whether popup is open by default (default: false) */
  defaultOpen?: boolean;

  /** Close popup when clicking outside (default: true) */
  clickOutsideToClose?: boolean;

  /** Close popup when pressing Escape (default: true) */
  hitEscapeToClose?: boolean;

  /** Keyboard shortcut to toggle popup (default: "/") */
  shortcut?: string;

  /** Callback when open state changes */
  onSetOpen?: (open: boolean) => void;

  /** Custom window/modal component */
  Window?: React.ComponentType<WindowProps>;

  /** Custom toggle button component */
  Button?: React.ComponentType<ButtonProps>;

  /** Custom header component */
  Header?: React.ComponentType<HeaderProps>;
}

interface WindowProps {
  clickOutsideToClose: boolean;
  hitEscapeToClose: boolean;
  shortcut: string;
  children?: React.ReactNode;
}

interface ButtonProps {
  // Can be extended with custom props
}

interface HeaderProps {
  // Can be extended with custom props
}

Usage Example:

import { CopilotPopup } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

function App() {
  const [isOpen, setIsOpen] = React.useState(false);

  return (
    <div>
      <YourAppContent />
      <CopilotPopup
        instructions="You are a helpful coding assistant."
        defaultOpen={false}
        shortcut="/"
        clickOutsideToClose={true}
        hitEscapeToClose={true}
        onSetOpen={setIsOpen}
        labels={{
          title: "Code Assistant",
          initial: "Hi! Press '/' to ask me anything about coding.",
        }}
        icons={{
          openIcon: <CustomOpenIcon />,
          closeIcon: <CustomCloseIcon />,
        }}
      />
    </div>
  );
}

CopilotSidebar

Sidebar version of the chat interface that slides in from the side. Wraps your content and adjusts layout when the sidebar is expanded.

/**
 * Sidebar version of the chat interface that slides in/out from the side
 * @param props - Configuration props same as CopilotModalProps
 * @returns Rendered sidebar with content wrapper
 */
function CopilotSidebar(props: CopilotModalProps): JSX.Element;

Usage Example:

import { CopilotSidebar } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css";

function App() {
  return (
    <CopilotSidebar
      instructions="You are a helpful document assistant."
      defaultOpen={false}
      labels={{
        title: "Document Helper",
        initial: "Need help with your documents?",
      }}
    >
      <div className="main-content">
        {/* Your app content - automatically adjusts when sidebar opens */}
        <h1>My Document Editor</h1>
        <Editor />
      </div>
    </CopilotSidebar>
  );
}

Observability Hooks

Event tracking system for monitoring user interactions and chat behavior. Requires publicApiKey to be set in the CopilotKit provider.

interface CopilotObservabilityHooks {
  /** Called when user sends a message */
  onMessageSent?: (message: string) => void;

  /** Called when chat is closed/minimized */
  onChatMinimized?: () => void;

  /** Called when chat is opened/expanded */
  onChatExpanded?: () => void;

  /** Called when message is regenerated */
  onMessageRegenerated?: (messageId: string) => void;

  /** Called when message is copied to clipboard */
  onMessageCopied?: (content: string) => void;

  /** Called when user provides feedback */
  onFeedbackGiven?: (messageId: string, type: "thumbsUp" | "thumbsDown") => void;

  /** Called when generation starts */
  onChatStarted?: () => void;

  /** Called when generation stops */
  onChatStopped?: () => void;

  /** Called on errors */
  onError?: (errorEvent: CopilotErrorEvent) => void;
}

Usage Example:

<CopilotPopup
  instructions="You are a helpful assistant."
  observabilityHooks={{
    onMessageSent: (message) => {
      analytics.track("chat_message_sent", { message });
    },
    onChatExpanded: () => {
      analytics.track("chat_opened");
    },
    onChatMinimized: () => {
      analytics.track("chat_closed");
    },
    onFeedbackGiven: (messageId, type) => {
      analytics.track("chat_feedback", { messageId, type });
    },
  }}
/>

Custom Stop and Reload Handlers

Advanced handlers for customizing stop generation and message regeneration behavior.

Note: These types are not exported from the package. Use the type signatures shown below or infer types from the prop definitions.

type OnStopGeneration = (args: OnStopGenerationArguments) => void;

interface OnStopGenerationArguments {
  /** Currently executing agent name */
  currentAgentName: string | undefined;

  /** Current message array */
  messages: Message[];

  /** Function to update messages */
  setMessages: (messages: Message[]) => void;

  /** Default stop generation function */
  stopGeneration: () => void;

  /** Restart the current agent */
  restartCurrentAgent: () => void;

  /** Stop the current agent */
  stopCurrentAgent: () => void;

  /** Run the current agent with optional hint */
  runCurrentAgent: (hint?: HintFunction) => Promise<void>;

  /** Set agent state */
  setCurrentAgentState: (state: any) => void;
}

type OnReloadMessages = (args: OnReloadMessagesArguments) => void;

interface OnReloadMessagesArguments extends OnStopGenerationArguments {
  /** ID of message to regenerate */
  messageId: string;
}

Usage Example:

<CopilotChat
  onStopGeneration={(args) => {
    // Custom stop logic
    console.log("Stopping agent:", args.currentAgentName);
    args.stopGeneration();
    // Custom cleanup
    cleanupResources();
  }}
  onReloadMessages={(args) => {
    // Custom reload logic
    console.log("Reloading message:", args.messageId);
    // Filter out messages after the one being regenerated
    const index = args.messages.findIndex((m) => m.id === args.messageId);
    args.setMessages(args.messages.slice(0, index + 1));
    // Run agent again
    args.runCurrentAgent();
  }}
/>

Install with Tessl CLI

npx tessl i tessl/npm-copilotkit--react-ui@1.10.1

docs

chat-components.md

customization.md

dev-console.md

hooks.md

index.md

message-components.md

types.md

README.md

tile.json