Setup

Install CopilotKit

Install the CopilotKit frontend packagess:

npm i @copilotkit/react-core @copilotkit/react-ui

Setup the frontend

A CopilotKit must wrap all components which interact with CopilotKit. It’s recommended you also get started with CopilotSidebar (you can swap to a different UI provider later).

For simplicity’s sake, it’s recommended you wrap both around your entire application:

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

export default function RootLayout({children}) {
  return (
    <CopilotKit publicApiKey="the api key or self host (see below)">
      <CopilotSidebar>
        {children}
      </CopilotSidebar>
    </CopilotKit>
  );
}

Setup the Copilot Runtime endpoint:

Setup the Copilot Runtime endpoint, see Quickstart-Runtime

Provide context

You likely want to provide external context to inform CopilotTextarea completions, insertions, and edits.

You can do so through the useCopilotReadable and useMakeCopilotDocumentReadable react hooks. See their respective documentation for additional details.

In particular, you can specify categories which bind specific context to specific textareas, and not to others.

"use client";

import { useCopilotReadable } from "@copilotkit/react-core";
import {
  useMakeCopilotDocumentReadable,
  DocumentPointer,
} from "@copilotkit/react-document";

// You can pass top-level data to the Copilot engine by calling `useCopilotReadable`.
const employeeContextId = useCopilotReadable({
  description: "Employee name",
  value: employeeName,
});

// Pass a parentID to maintain a hiearchical structure.
//
// This example is a bit artificial, but this sort of hiearchical data
// comes in handy with child React components, list elements, etc.
useCopilotReadable({
  description: "Employee work profile",
  value: workProfile.description(),
  parentId: employeeContextId,
});
useCopilotReadable({
  description: "Employee metadata",
  value: metadata.description(),
  parentId: employeeContextId,
});

const document: DocumentPointer = {
  id: "2",
  name: "Travel Pet Peeves",
  sourceApplication: "Google Docs",
  iconImageUri: "/images/GoogleDocs.svg",
  getContents: () => {
    return "hello document";
  },
} as DocumentPointer;

// ...then, in a react component:
useMakeCopilotDocumentReadable(document); // You can pass top-level data to the Copilot engine by calling `useCopilotReadable`.
const employeeContextId = useCopilotReadable({
  description: "Employee name",
  value: employeeName,
});

Let the Copilot take action

"use client";

import { useCopilotAction } from "@copilotkit/react-core";

// Let the copilot take action on behalf of the user.
useCopilotAction(
  {
    name: "setEmployeesAsSelected", // no spaces allowed in the function name
    description: "Set the given employees as 'selected'",
    parameters: [
      {
        name: "employeeIds",
        type: "string[]",
        description: "The IDs of employees to set as selected",
        required: true,
      },
    ],
    handler: async ({ employeeIds }) => setEmployeesAsSelected(employeeIds),
  },
  []
);

CopilotTextarea is configured essentially identically to a standard react <textarea />.

The primary difference is the additional autosuggestionsConfig variable, which provides copilot-specific configurations.

See the CopilotTextarea documentation for all parameters.

import { CopilotTextarea } from "@copilotkit/react-textarea";
import { useState } from "react";

export function SomeReactComponent() {
  const [text, setText] = useState("");

  return (
    <>
      <CopilotTextarea
        className="px-4 py-4"
        value={text}
        onValueChange={(value: string) => setText(value)}
        placeholder="What are your plans for your vacation?"
        autosuggestionsConfig={{
          textareaPurpose:
            "Travel notes from the user's previous vacations. Likely written in a colloquial style, but adjust as needed.",
          chatApiConfigs: {
            suggestionsApiConfig: {
              forwardedParams: {
                max_tokens: 20,
                stop: [".", "?", "!"],
              },
            },
          },
        }}
      />
    </>
  );
}