Embedding a copilot in Next.js

Next.js tutorial

This short tutorial shows how to implement a Continual AI Copilot in a basic Next.js template app. It's assumed you will not be using an existing Next.js application, but feel free to use an existing app if preferred!

Create a Next.js app

To create a Next.js app, open your terminal, cd into the directory you’d like to create the app in, and run the following command:

npx create-next-app@latest nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"

Under the hood, this uses the tool called create-next-app (opens in a new tab), which bootstraps a Next.js app for you using this template (opens in a new tab).

If it doesn’t work, please take a look at this page (opens in a new tab).

Run the development server

You now have a new directory called nextjs-blog. cd into it and start the dev server:

cd nextjs-blog
pnpm run dev

This starts the "development server" on port 3000.

Let’s check to see if it’s working. Open http://localhost:3000 (opens in a new tab) from your browser.

Return to your code editor and open the pages/index.js file where we'll drop in the Continual Copilot React component. The copilot backend has not been created yet, but since we're already in the frontend, let's start here and then go to the Continual console to create the copilot in Continual.

Install the Continual frontend package

Download and install the @continual/react package.

pnpm add @continual/react

Add the <Copilot/> component to Home()

At the top of index.js, import the necessary modules and set the Continual Copilot ID and Continual API secret. Once we create the copilot in Continual, we'll create the .env file to store these variables:

index.js
import { Copilot, CopilotProvider, useCopilotContext } from "@continual/react";
import "@continual/react/dist/styles.css";
 
const ContinualCopilotId = process.env.NEXT_PUBLIC_CONTINUAL_COPILOT_ID;
const ContinualSecret = process.env.NEXT_PUBLIC_CONTINUAL_SECRET;

In the Return statement, wrap the entire app component with the <CopilotProvider/> component:

index.js
return (
  <div className={styles.container}>
    <CopilotProvider copilotId={ContinualCopilotId} accessToken={ContinualSecret}>
      {/* Your other app components here. */}
      <Copilot />
    </CopilotProvider>
  </div>
);

The final frontend step is to create the .env in preparation for our Copilot ID and Continual API secret:

.env
NEXT_PUBLIC_CONTINUAL_COPILOT_ID=my-copilot-id
NEXT_PUBLIC_CONTINUAL_SECRET=my-continual-api-secret
 

We need to create a copilot and api key in Continual to generate those values.

Create a Copilot in Continual

If you haven’t already, begin by signing up (opens in a new tab) for Continual.

If you plan to collaborate with other team members, create a team workspace by clicking Create Workspace in the workspace menu in the top left of the Continual console.

After signing up for Continual, create a copilot in the Continual Console (opens in a new tab) by clicking Copilots from the sidebar and then Create Copilot. Give it a name and choose a model. We recommend starting with OpenAI GPT 4 Omni but be sure to try out our other supported models.

After the copilot has been created, copy the copilotId in the top right corner of the copilot page and go paste it into your .env file in place of my-copilot-id.

Copy Copilot ID from console

Create an API key

Next, click on API Keys and generate a Continual API key. We'll use the secret key to authenticate your copilot in the Next.js application with the Continual backend. Copy the secret key and go paste it into your .env file in place of continual-api-secret.

Create API key

Boom! You should see a small chat icon on the bottom right of your Next.js app.

Continual Icon displays in Next.js app

Click on it and say Hello!

Say hello in Next.js app

We haven't connected any Knowledge Bases or Tools to this copilot. It only has the underlying LLM's general knowledge and the default global guidelines. The Global Guidelines allow you to customize the behavior of your copilot and add important additional context. We recommended adding and removing a bulleted list of behavioral guidelines and context based on the observed behavior of your copilot.

Customize Copilot Behavior by editing Global Guidelines

Return to the Continual Console and click on your copilot and then the Settings tab. Update the first line of the default global guidelines to You are a highly intelligent AI copilot embedded within an NextJS blog template application.

Update Global Guidelines

Now, tell the copilot to describe itself and observe the global guideline being applied.

Describe yourself

Next, let's create and connect a Knowledge Base and a Tool.

Enable RAG with Continual Knowledge Bases

Knowledge bases are semantically indexed stores of information that copilots can access to provide users with accurate and up-to-date information, whether that is product documentation, FAQs, or user uploaded documents and data. This ensures that your copilot always has the most up-to-date information to provide to users.

In this tutorial, we can use the Next.js documentation (opens in a new tab) as an example.

Create a Knowledge Base

On the main page of your Next.js blog sample app, there are tiles with links to their documentation, interactive courses, examples, and Vercel. Click on the tile to the documentation and copy the link.

Return to the Continual Console, click on Knowledge Bases and create a new one. There are two knowledge base types: Unmanaged and Managed. Managed knowledge bases continuously sync from an external data source like a website, cloud storage bucket, or content repository. Unmanaged knowledge bases allow you to manually upload files and documents.

Choose a managed knowledge base and enter the Next.js documentation URL.

Create Knowledge Base

Choose the Raw HTTP crawler and click Connect.

Enter docs link

Finally, click Create to create the knowledge base.

While the next.js documentation is being crawled, go onto the next step and create a Tool. We'll connect and test both Knowledge Bases and Tools after that.

Unlock Tool usage

Tools allow you to extend copilots by connecting them to APIs, whether your application's API or task-specific APIs to empower the copilot to perform new or better tasks. An external tool is defined using an OpenAPI specification, providing a standardized way to describe the API endpoints, parameters, and responses. In the future, Continual may support additional tool types.

Create a Tool

We're going to use the Continual API to create a Tool that allows the copilot to take action in the continual console.

Create a new Tool and give it a name. Choose "Service Bearer Token" for the authentication and paste in the Continual API Key you generated earlier. This would be your API key if we were making a Tool for your application. But we'll use a sample OpenAPI Specification of Continual's API for this example.

Create Tool

Copy the Continual API Specification Sample and paste it into the Tool Specification text box. Then click Create.

Continual API Specification Sample
{
  "openapi": "3.0.3",
  "info": {
    "title": "Continual API",
    "description": "OpenAPI compliant REST API for Continual.  The public API is not currently stable and may change without notice.  Use at your own risk.  For more information, see the [Continual API documentation](https://docs.continual.ai).",
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://console.continual.ai/api/v1"
    }
  ],
  "paths": {
    "/copilots": {
      "post": {
        "operationId": "mutation.copilots.create",
        "summary": "Create Copilot",
        "description": "Creates a Copilot that can be used headlessly or via an embedded widget",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "The name of the Copilot. Maximum length of 100 characters."
                  },
                  "workspaceId": {
                    "type": "string",
                    "description": "The workspace ID."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "number"
                        }
                      ]
                    },
                    "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                  },
                  "modelProviderId": {
                    "type": "string",
                    "description": "The Model Provider ID used by this copilot."
                  },
                  "description": {
                    "type": "string",
                    "description": "The description of the Copilot."
                  },
                  "instructions": {
                    "type": "string",
                    "description": "The LLM instructions for the Copilot."
                  },
                  "anonymousAccessEnabled": {
                    "type": "boolean",
                    "description": "If enabled, users do not need to be authenticated."
                  },
                  "avatarType": {
                    "type": "string",
                    "enum": [
                      "built-in",
                      "emoji",
                      "svg",
                      "url",
                      "BUILT_IN",
                      "EMOJI",
                      "SVG",
                      "URL"
                    ],
                    "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                  },
                  "avatar": {
                    "type": "string",
                    "description": "The source for the Copilot avatar"
                  },
                  "chatIconType": {
                    "type": "string",
                    "enum": [
                      "built-in",
                      "emoji",
                      "svg",
                      "url",
                      "BUILT_IN",
                      "EMOJI",
                      "SVG",
                      "URL"
                    ],
                    "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                  },
                  "chatIcon": {
                    "type": "string",
                    "description": "The source for the Copilot icon"
                  },
                  "chatUserInputPlaceholder": {
                    "type": "string",
                    "description": "The default user input prompt"
                  },
                  "chatGreetingMessage": {
                    "type": "string",
                    "description": "The copilot greeting message"
                  },
                  "displayFormat": {
                    "type": "string",
                    "enum": [
                      "popup",
                      "sidebar",
                      "inline",
                      "inline_fill",
                      "POPUP",
                      "SIDEBAR",
                      "INLINE",
                      "INLINE_FILL"
                    ],
                    "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                  },
                  "model": {
                    "type": "string",
                    "description": "The Model used by this copilot."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The Copilot ID."
                    },
                    "object": {
                      "type": "string",
                      "enum": [
                        "copilot"
                      ],
                      "description": "The resource type."
                    },
                    "workspaceId": {
                      "type": "string",
                      "description": "The workspace ID."
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 100,
                      "description": "The name of the Copilot. Maximum length of 100 characters."
                    },
                    "modelProviderId": {
                      "type": "string",
                      "description": "The Model Provider ID used by this copilot."
                    },
                    "model": {
                      "type": "string",
                      "description": "The Model used by this copilot."
                    },
                    "description": {
                      "type": "string",
                      "description": "The description of the Copilot."
                    },
                    "instructions": {
                      "type": "string",
                      "description": "The LLM instructions for the Copilot."
                    },
                    "displayFormat": {
                      "type": "string",
                      "enum": [
                        "popup",
                        "sidebar",
                        "inline",
                        "inline_fill",
                        "POPUP",
                        "SIDEBAR",
                        "INLINE",
                        "INLINE_FILL"
                      ],
                      "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                    },
                    "anonymousAccessEnabled": {
                      "type": "boolean",
                      "description": "If enabled, users do not need to be authenticated."
                    },
                    "avatarType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "avatar": {
                      "type": "string",
                      "description": "The source for the Copilot avatar"
                    },
                    "chatIconType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "chatIcon": {
                      "type": "string",
                      "description": "The source for the Copilot icon"
                    },
                    "chatUserInputPlaceholder": {
                      "type": "string",
                      "description": "The default user input prompt"
                    },
                    "chatGreetingMessage": {
                      "type": "string",
                      "description": "The copilot greeting message"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Updated time."
                    },
                    "metadata": {
                      "type": "object",
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Created time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "workspaceId",
                    "displayFormat",
                    "updatedAt",
                    "metadata",
                    "createdAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      },
      "get": {
        "operationId": "query.copilots.list",
        "summary": "List Copilots",
        "description": "Returns a list of Copilots for the workspace.",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by workspace ID.  Defaults to the currently active workspace."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "The order of the list. Defaults to `desc` by created date."
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 1000,
              "default": 30
            },
            "description": "The page size of the list. Defaults to 30."
          },
          {
            "name": "nextPageToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The page token of the list."
          },
          {
            "name": "previousPageToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The page token of the list."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "enum": [
                        "list"
                      ],
                      "description": "The object type of the list."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The Copilot ID."
                          },
                          "object": {
                            "type": "string",
                            "enum": [
                              "copilot"
                            ],
                            "description": "The resource type."
                          },
                          "workspaceId": {
                            "type": "string",
                            "description": "The workspace ID."
                          },
                          "name": {
                            "type": "string",
                            "maxLength": 100,
                            "description": "The name of the Copilot. Maximum length of 100 characters."
                          },
                          "modelProviderId": {
                            "type": "string",
                            "description": "The Model Provider ID used by this copilot."
                          },
                          "model": {
                            "type": "string",
                            "description": "The Model used by this copilot."
                          },
                          "description": {
                            "type": "string",
                            "description": "The description of the Copilot."
                          },
                          "instructions": {
                            "type": "string",
                            "description": "The LLM instructions for the Copilot."
                          },
                          "displayFormat": {
                            "type": "string",
                            "enum": [
                              "popup",
                              "sidebar",
                              "inline",
                              "inline_fill",
                              "POPUP",
                              "SIDEBAR",
                              "INLINE",
                              "INLINE_FILL"
                            ],
                            "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                          },
                          "anonymousAccessEnabled": {
                            "type": "boolean",
                            "description": "If enabled, users do not need to be authenticated."
                          },
                          "avatarType": {
                            "type": "string",
                            "enum": [
                              "built-in",
                              "emoji",
                              "svg",
                              "url",
                              "BUILT_IN",
                              "EMOJI",
                              "SVG",
                              "URL"
                            ],
                            "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                          },
                          "avatar": {
                            "type": "string",
                            "description": "The source for the Copilot avatar"
                          },
                          "chatIconType": {
                            "type": "string",
                            "enum": [
                              "built-in",
                              "emoji",
                              "svg",
                              "url",
                              "BUILT_IN",
                              "EMOJI",
                              "SVG",
                              "URL"
                            ],
                            "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                          },
                          "chatIcon": {
                            "type": "string",
                            "description": "The source for the Copilot icon"
                          },
                          "chatUserInputPlaceholder": {
                            "type": "string",
                            "description": "The default user input prompt"
                          },
                          "chatGreetingMessage": {
                            "type": "string",
                            "description": "The copilot greeting message"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Updated time."
                          },
                          "metadata": {
                            "type": "object",
                            "additionalProperties": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "number"
                                }
                              ]
                            },
                            "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "Created time."
                          }
                        },
                        "required": [
                          "id",
                          "object",
                          "workspaceId",
                          "displayFormat",
                          "updatedAt",
                          "metadata",
                          "createdAt"
                        ],
                        "additionalProperties": false
                      },
                      "description": "The list of resources."
                    },
                    "nextPageToken": {
                      "type": "string",
                      "description": "The next page token of the list."
                    },
                    "previousPageToken": {
                      "type": "string",
                      "description": "The previous page token of the list."
                    }
                  },
                  "required": [
                    "object",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      }
    },
    "/copilots/{id}": {
      "patch": {
        "operationId": "mutation.copilots.update",
        "summary": "Update Copilot",
        "description": "Update a Copilot.",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "The name of the Copilot. Maximum length of 100 characters."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "number"
                        }
                      ]
                    },
                    "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                  },
                  "modelProviderId": {
                    "type": "string",
                    "description": "The Model Provider ID used by this copilot."
                  },
                  "model": {
                    "type": "string",
                    "description": "The Model used by this copilot."
                  },
                  "description": {
                    "type": "string",
                    "description": "The description of the Copilot."
                  },
                  "instructions": {
                    "type": "string",
                    "description": "The LLM instructions for the Copilot."
                  },
                  "anonymousAccessEnabled": {
                    "type": "boolean",
                    "description": "If enabled, users do not need to be authenticated."
                  },
                  "avatarType": {
                    "type": "string",
                    "enum": [
                      "built-in",
                      "emoji",
                      "svg",
                      "url",
                      "BUILT_IN",
                      "EMOJI",
                      "SVG",
                      "URL"
                    ],
                    "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                  },
                  "avatar": {
                    "type": "string",
                    "description": "The source for the Copilot avatar"
                  },
                  "chatIconType": {
                    "type": "string",
                    "enum": [
                      "built-in",
                      "emoji",
                      "svg",
                      "url",
                      "BUILT_IN",
                      "EMOJI",
                      "SVG",
                      "URL"
                    ],
                    "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                  },
                  "chatIcon": {
                    "type": "string",
                    "description": "The source for the Copilot icon"
                  },
                  "chatUserInputPlaceholder": {
                    "type": "string",
                    "description": "The default user input prompt"
                  },
                  "chatGreetingMessage": {
                    "type": "string",
                    "description": "The copilot greeting message"
                  },
                  "displayFormat": {
                    "type": "string",
                    "enum": [
                      "popup",
                      "sidebar",
                      "inline",
                      "inline_fill",
                      "POPUP",
                      "SIDEBAR",
                      "INLINE",
                      "INLINE_FILL"
                    ],
                    "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The Copilot ID."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The Copilot ID."
                    },
                    "object": {
                      "type": "string",
                      "enum": [
                        "copilot"
                      ],
                      "description": "The resource type."
                    },
                    "workspaceId": {
                      "type": "string",
                      "description": "The workspace ID."
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 100,
                      "description": "The name of the Copilot. Maximum length of 100 characters."
                    },
                    "modelProviderId": {
                      "type": "string",
                      "description": "The Model Provider ID used by this copilot."
                    },
                    "model": {
                      "type": "string",
                      "description": "The Model used by this copilot."
                    },
                    "description": {
                      "type": "string",
                      "description": "The description of the Copilot."
                    },
                    "instructions": {
                      "type": "string",
                      "description": "The LLM instructions for the Copilot."
                    },
                    "displayFormat": {
                      "type": "string",
                      "enum": [
                        "popup",
                        "sidebar",
                        "inline",
                        "inline_fill",
                        "POPUP",
                        "SIDEBAR",
                        "INLINE",
                        "INLINE_FILL"
                      ],
                      "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                    },
                    "anonymousAccessEnabled": {
                      "type": "boolean",
                      "description": "If enabled, users do not need to be authenticated."
                    },
                    "avatarType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "avatar": {
                      "type": "string",
                      "description": "The source for the Copilot avatar"
                    },
                    "chatIconType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "chatIcon": {
                      "type": "string",
                      "description": "The source for the Copilot icon"
                    },
                    "chatUserInputPlaceholder": {
                      "type": "string",
                      "description": "The default user input prompt"
                    },
                    "chatGreetingMessage": {
                      "type": "string",
                      "description": "The copilot greeting message"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Updated time."
                    },
                    "metadata": {
                      "type": "object",
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Created time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "workspaceId",
                    "displayFormat",
                    "updatedAt",
                    "metadata",
                    "createdAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      },
      "get": {
        "operationId": "query.copilots.get",
        "summary": "Get Copilot",
        "description": "Returns a Copilot.",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Copilot ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The Copilot ID."
                    },
                    "object": {
                      "type": "string",
                      "enum": [
                        "copilot"
                      ],
                      "description": "The resource type."
                    },
                    "workspaceId": {
                      "type": "string",
                      "description": "The workspace ID."
                    },
                    "name": {
                      "type": "string",
                      "maxLength": 100,
                      "description": "The name of the Copilot. Maximum length of 100 characters."
                    },
                    "modelProviderId": {
                      "type": "string",
                      "description": "The Model Provider ID used by this copilot."
                    },
                    "model": {
                      "type": "string",
                      "description": "The Model used by this copilot."
                    },
                    "description": {
                      "type": "string",
                      "description": "The description of the Copilot."
                    },
                    "instructions": {
                      "type": "string",
                      "description": "The LLM instructions for the Copilot."
                    },
                    "displayFormat": {
                      "type": "string",
                      "enum": [
                        "popup",
                        "sidebar",
                        "inline",
                        "inline_fill",
                        "POPUP",
                        "SIDEBAR",
                        "INLINE",
                        "INLINE_FILL"
                      ],
                      "description": "The display format the Copilot (\"popup\" | \"sidebar\" | \"inline\" | \"inline_fill\" | \"POPUP\" | \"SIDEBAR\" | \"INLINE\" | \"INLINE_FILL\")."
                    },
                    "anonymousAccessEnabled": {
                      "type": "boolean",
                      "description": "If enabled, users do not need to be authenticated."
                    },
                    "avatarType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The avatar type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "avatar": {
                      "type": "string",
                      "description": "The source for the Copilot avatar"
                    },
                    "chatIconType": {
                      "type": "string",
                      "enum": [
                        "built-in",
                        "emoji",
                        "svg",
                        "url",
                        "BUILT_IN",
                        "EMOJI",
                        "SVG",
                        "URL"
                      ],
                      "description": "The Copilot icon type (\"built-in\" | \"emoji\" | \"svg\" | \"url\" | \"BUILT_IN\" | \"EMOJI\" | \"SVG\" | \"URL\")"
                    },
                    "chatIcon": {
                      "type": "string",
                      "description": "The source for the Copilot icon"
                    },
                    "chatUserInputPlaceholder": {
                      "type": "string",
                      "description": "The default user input prompt"
                    },
                    "chatGreetingMessage": {
                      "type": "string",
                      "description": "The copilot greeting message"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Updated time."
                    },
                    "metadata": {
                      "type": "object",
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Created time."
                    }
                  },
                  "required": [
                    "id",
                    "object",
                    "workspaceId",
                    "displayFormat",
                    "updatedAt",
                    "metadata",
                    "createdAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      },
      "delete": {
        "operationId": "mutation.copilots.delete",
        "summary": "Delete Copolot",
        "description": "Delete a Copilot.",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Copilot ID"
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {}
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      }
    },
    "/copilots/{copilotId}/threads": {
      "get": {
        "operationId": "query.copilots.listThreads",
        "summary": "List Copilot Threads",
        "description": "Returns a list of Threads for a Copilot.",
        "tags": [
          "Copilots"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "parameters": [
          {
            "name": "copilotId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The Copilot ID"
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter by workspace ID.  Defaults to the currently active workspace."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc"
            },
            "description": "The order of the list. Defaults to `desc` by created date."
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "schema": {
              "type": "number",
              "minimum": 1,
              "maximum": 1000,
              "default": 30
            },
            "description": "The page size of the list. Defaults to 30."
          },
          {
            "name": "nextPageToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The page token of the list."
          },
          {
            "name": "previousPageToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "The page token of the list."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "enum": [
                        "list"
                      ],
                      "description": "The object type of the list."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "workspaceId": {
                            "type": "string",
                            "description": "The workspace ID."
                          },
                          "copilotId": {
                            "type": "string",
                            "description": "The Copilot ID"
                          },
                          "threadId": {
                            "type": "string",
                            "description": "The Thread ID"
                          },
                          "copilotRuns": {
                            "type": "number",
                            "description": "The number of runs this Copilot has ran in this thread"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "The first time a was run executed on this thread for this Copilot"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "The lastest time a run was executed on this thread for this Copilot"
                          }
                        },
                        "required": [
                          "workspaceId",
                          "copilotId",
                          "threadId",
                          "copilotRuns"
                        ],
                        "additionalProperties": false
                      },
                      "description": "The list of resources."
                    },
                    "nextPageToken": {
                      "type": "string",
                      "description": "The next page token of the list."
                    },
                    "previousPageToken": {
                      "type": "string",
                      "description": "The previous page token of the list."
                    }
                  },
                  "required": [
                    "object",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      }
    },
    "/knowledgebases/{knowledgeBaseId}/documents/upsert": {
      "post": {
        "operationId": "mutation.knowledgeBases.upsertDocuments",
        "summary": "Upsert KnowledgeBase Documents",
        "description": "Upserts KnowledgeBase documents to be stored as documents.",
        "tags": [
          "KnowledgeBase"
        ],
        "security": [
          {
            "Authorization": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "docs": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "content": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "metadata": {
                          "type": "object",
                          "additionalProperties": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              }
                            ]
                          }
                        }
                      },
                      "required": [
                        "name",
                        "content"
                      ],
                      "additionalProperties": false
                    }
                  }
                },
                "required": [
                  "docs"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "knowledgeBaseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The ingestion ID."
                    },
                    "workspaceId": {
                      "type": "string",
                      "description": "The workspace ID."
                    },
                    "knowledgeBaseId": {
                      "type": "string",
                      "description": "The knowledge base id"
                    },
                    "toolId": {
                      "type": "string",
                      "description": "The tool id"
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "website",
                        "advancedWebsite",
                        "awsS3",
                        "azureBlobStorage",
                        "gcsBucket",
                        "document"
                      ],
                      "description": "The type of the ingestion job."
                    },
                    "documentCount": {
                      "type": "number",
                      "description": "The number of ingested documents."
                    },
                    "finishedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Finished time."
                    },
                    "apifyRunIdExternal": {
                      "type": "string",
                      "description": "The apify run id"
                    },
                    "output": {
                      "type": "object",
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "description": "The ingestion output"
                    },
                    "error": {
                      "type": "string",
                      "default": "",
                      "description": "Contains the description of errors encountered by the ingestion job"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "crawling",
                        "processing",
                        "success",
                        "error"
                      ],
                      "description": "The state of the ingestion job"
                    },
                    "sourceDetails": {
                      "description": "The details about the knowledge base source"
                    },
                    "authInfo": {
                      "description": "The auth info to connect to the knowledge base source"
                    },
                    "documents": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The documents ingested by this job"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Updated time."
                    },
                    "metadata": {
                      "type": "object",
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "Created time."
                    }
                  },
                  "required": [
                    "id",
                    "workspaceId",
                    "state",
                    "updatedAt",
                    "metadata",
                    "createdAt"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/error"
          }
        }
      }
  },
  "/documents": {
    "post": {
      "operationId": "mutation.documents.create",
      "summary": "Create Document",
      "description": "Create a Document.",
      "tags": [
        "Document"
      ],
      "security": [
        {
          "Authorization": []
        }
      ],
      "requestBody": {
        "required": false,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 100,
                  "description": "The title of the document. Maximum length of 100 characters."
                },
                "workspaceId": {
                  "type": "string",
                  "description": "The workspace ID."
                },
                "metadata": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                },
                "content": {
                  "type": "string",
                  "description": "The content of the document."
                },
                "knowledgeBaseId": {
                  "type": "string",
                  "description": "The knowledge base id"
                },
                "externalId": {
                  "type": "string",
                  "description": "The external id used to uniquely identify a document in the source"
                },
                "systemMetadata": {
                  "type": "object",
                  "additionalProperties": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "description": "Up to 20 system-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                },
                "url": {
                  "type": "string",
                  "description": "The url to access the document"
                },
                "embeddingState": {
                  "type": "string",
                  "enum": [
                    "progress",
                    "success",
                    "error"
                  ]
                },
                "contentType": {
                  "type": "string",
                  "description": "The content type of the document; e.g. application/pdf"
                },
                "embeddingDurationMs": {
                  "type": "number",
                  "description": "The embedding duration in milliseconds"
                },
                "chunkingDurationMs": {
                  "type": "number",
                  "description": "The chunking duration in milliseconds"
                }
              },
              "additionalProperties": false
            }
          }
        }
      },
      "parameters": [],
      "responses": {
        "200": {
          "description": "Successful response",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "The document key ID."
                  },
                  "object": {
                    "type": "string",
                    "enum": [
                      "document"
                    ],
                    "description": "The resource type."
                  },
                  "workspaceId": {
                    "type": "string",
                    "description": "The workspace ID."
                  },
                  "knowledgeBaseId": {
                    "type": "string",
                    "description": "The knowledge base id"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "The title of the document. Maximum length of 100 characters."
                  },
                  "content": {
                    "type": "string",
                    "description": "The content of the document."
                  },
                  "contentType": {
                    "type": "string",
                    "description": "The content type of the document; e.g. application/pdf"
                  },
                  "systemMetadata": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "number"
                        }
                      ]
                    },
                    "description": "Up to 20 system-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                  },
                  "url": {
                    "type": "string",
                    "description": "The url to access the document"
                  },
                  "externalId": {
                    "type": "string",
                    "description": "The external id used to uniquely identify a document in the source"
                  },
                  "modified": {
                    "type": "boolean",
                    "description": "Indicate whether a document has been modified"
                  },
                  "embeddingState": {
                    "type": "string",
                    "enum": [
                      "progress",
                      "success",
                      "error"
                    ]
                  },
                  "embeddingDurationMs": {
                    "type": "number",
                    "description": "The embedding duration in milliseconds"
                  },
                  "chunkingDurationMs": {
                    "type": "number",
                    "description": "The chunking duration in milliseconds"
                  },
                  "contentHash": {
                    "type": "string",
                    "description": "The hash of content"
                  },
                  "updatedAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Updated time."
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": {
                      "anyOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "number"
                        }
                      ]
                    },
                    "description": "Up to 20 user-defined metadata pairs can be attached to a resource. Keys can be a maximum of 100 characters."
                  },
                  "createdAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Created time."
                  }
                },
                "required": [
                  "id",
                  "object",
                  "workspaceId",
                  "knowledgeBaseId",
                  "title",
                  "content",
                  "systemMetadata",
                  "modified",
                  "contentHash",
                  "updatedAt",
                  "metadata",
                  "createdAt"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "default": {
          "$ref": "#/components/responses/error"
        }
      }
    }
  }
},
"components": {
  "securitySchemes": {
    "Authorization": {
      "type": "http",
      "scheme": "bearer"
    }
  },
  "responses": {
    "error": {
      "description": "Error response",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string"
              },
              "issues": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "message",
              "code"
            ],
            "additionalProperties": false
          }
        }
      }
    }
  }
},
"tags": [
  {
    "name": "API Keys"
  },
  {
    "name": "Copilots"
  }
],
"externalDocs": {
  "url": "https://docs.continual.ai"
}
}
 

For simplicity, the example specification only has 3 API endpoints. We'll use /copilots/ for this example.

Connect Knowledge Base and Tool to the Copilot

Return to our copilot overview page and select Integrations.

Clicking on copilot integrations

Connect the Next.js Documentation knowledge base and the Continual Console tool.

Connect integrations

Go to Playground to try out queries.

Asking questions

Go to the copilot widget in the Next.js template app. Let's test whether our copilot can answer a question from the Next.js documentation. Suppose the user hits this known error and asks: How do I fix the error "No Script Component in Head"?

Compare the copilot's response to the source document: https://nextjs.org/docs/messages/no-script-component-in-head (opens in a new tab)

Let's use the copilot to make an API request to view our Continual Copilots. Instruct it to List my copilots.

Taking actions

Next, let's ask the copilot to take an action for us. Tell the copilot: Update AI Copilot's greeting to "Howdy Partner". Be sure to use the copilot's name (e.g. AI Copilot) when giving the instruction. Refresh the page to see the new greeting.

Howdy Partner

Troubleshooting copilot issues

Threads are a helpful feature in Continual that provide a full list of user-copilot conversations.

Threads

There is an Overview of the conversation, as the user experienced it, as well as a Traces view for debugging. Traces are for admins to track the execution flow, identify bottlenecks, and troubleshoot issues. The Trace view provides a detailed, hierarchical breakdown of a copilot's processing flow through Threads, Runs, and Steps. A Run within a Thread represents a single execution responding to a user prompt, encompassing the entire processing flow. Steps within a Run include Tool Calls and Message Creation, helping to verify information retrieval, identify performance issues, and evaluate message quality. With this information, admins can effectively analyze and optimize the Copilot's performance. Checkout the Traces documentation for more information.

Click on the Traces tab and you'll see everything that occurred while testing the copilot. Threads Traces

The second column text describes each Run and Step. For example, you can see the user's two top level messages are "Hello!" and "describe yourself" in this thread. We can also see the first Step was to call the tool that searches all knowledge bases.

Traces Double click