Telerik blogs

Let’s explore the CopilotKit, an open-source framework not just for generating content or ideas but also for working side by side with your users to automate tasks and get things done faster and easier.

Artificial intelligence (AI) is one of the most used two-word phrases in the tech world in recent years. Entrepreneurs, doctors, lawyers, mechanics, electricians—if you use an internet-enabled device, you have probably heard about artificial intelligence. Its use is ubiquitous and cuts across various industries, especially those with readily available, systematic and organized data.

Artificial intelligence is a field of computer technology that mimics human intelligence by building systems that can do things that previously only humans could do. Systems that have AI can recognize images and text, solve math equations, learn, reason, predict outcomes and even be creative enough to write poems and create images.

You can imagine how productive a person can be if they have a human assistant helping them perform basic, repetitive, non-creative or non-rewarding tasks. Now, imagine the productivity increase when an AI with non-human requirements to function helps you do these tasks—that means no days off or incentives needed for increased volume or quality of work.

Imagine an entity whose success can be directly linked to productivity, uptime and accuracy. Whether it be a business or an application, imagine enhancing that entity with powerful AI-driven capabilities. Well, you can stop imagining. We now have the CopilotKit.

In this article, we are going to explore the CopilotKit. An open-source framework that helps you achieve all that we just explained above in your application. It is not just for generating content or ideas but also for working side by side with your users to automate tasks and get things done faster and easier.

Prerequisites

To follow this tutorial, you must be familiar with React.js, EmailJS and Tailwind CSS.

What Is CopilotKit?

CopilotKit is an open-source framework that helps developers integrate Copilot AI into their applications. It helps you build powerful AI-powered features that understand your application’s data and take actions on your behalf.

Use Cases of Copilot AI

Today, Copilot AI can be used to achieve a lot. Here are some use cases:

  1. Task automation: You can ask Copilot AI to perform certain tasks as long as you give it access to data and functions to be able to carry out the tasks.
  2. Powerful research: Copilot can be used to search the web with AI-powered web search, giving you research data along with references, research ratings, important insights on that research and even summaries.
  3. Insightful data analysis: You can give certain data to Copilot AI and ask it questions about that data. Questions that would take a long time of calculations to answer can now be answered within seconds. For example, you can feed Copilot AI your business sales and purchase data and ask it to calculate your profit margin percentage, and it would do that easily.
  4. Data summarization and reporting: Copilot can summarize long text blocks and generate reports on that text. You can feed Copilot a customer complaint message and ask it to summarize the message and generate some creative solutions to solve each problem.
  5. Marketing and advertisement: Copilot can generate marketing action plans and advertisement targets based on the nature of your business.
  6. Effective inventory suggestions: Copilot can suggest items that need to be restocked to improve sales potential based on your sales data.
  7. Complex form filling: You can fill out complex forms even on the go using Copilot’s conversational audio capabilities.

What We Are Building

In this guide, we are going to build a Next.js application and embed Copilot AI into it to automate specific tasks—most importantly, sending emails.

We will also explore how Copilot AI can understand and respond to questions about our app’s data by feeding that data directly to it.

We will simulate a scenario where some users in our system have accounts that are not validated. So instead of manually emailing each of them to validate their account, we will designate that task to Copilot AI. It will handle the work of identifying those users and emailing them for us right from within our app.

This task would have otherwise required the administrator of the application to:

  • First outline all users with validation status of false.
  • Go to the admin’s email client and compose and send a personalized email to each user that is not validated.

This daunting two-step task will be automated with one sentence in a chat prompt. Like so:

“Compose and send a personalized email to all users that are not validated, telling them to log in and validate their account”

That’s all!

Project Setup

Start by creating a folder where this application will live. Let us call it copilotapp. Open your code editor and open the folder you just created.

Next, let’s set up our Next.js project. Run this command in your terminal:

npx create-next-app@latest

Run the following command to install the dependencies we will be needing:

npm install emailjs-com @copilotkit/react-ui @copilotkit/react-core

From left to right, we installed EmailJS and CopilotKit respectively. The EmailJS SDK will allow us to send emails. The CopilotKit module provides us with the necessary tools to craft the AI agent that automates tasks for us.

Notice there are two parts of that CopilotKit installation code block:

  • @copilotkit/react-core: This is the main library for CopilotKit that contains the <CopilotKit> provider and various hooks.
  • @copilotkit/react-ui: This is the UI library for CopilotKit, which contains the CopilotKit UI components such as the <CopilotSidebar>, <CopilotPopup>, <CopilotChat> and more in case you want to customize them.

After installing all these, we can now begin building our dummy app called Tamar.

Add the Copilot Chat Interface

You can either self-host or use the cloud-hosted version of the CopilotKit runtime. In our case, we will go with the latter. So at this point, assuming you have a CopilotKit account, let’s go to the dashboard to get all the credentials we will need to complete our integration.

CopilotKit dashboard

On your dashboard, navigate to Api Key section.

CopilotKit API key

Copy your Api key and head back to our application.

To have Copilot AI accessible from anywhere in our application, we need to import it and wrap our entire application with it. We will do this by editing the layout.js file as follows:

import { CopilotKit } from "@copilotkit/react-core";
import "@copilotkit/react-ui/styles.css";
export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <CopilotKit publicApiKey="your_api_key">{children}</CopilotKit>
      </body>
    </html>
  );
}

To enable global access to CopilotKit from anywhere within our app, we wrapped our root app’s layout with the CopilotKit provider.

Let’s now embed the Copilot interface into page.js in our app

"use client";
import { CopilotPopup } from "@copilotkit/react-ui";
export default function Home() {
  return (
    <div className="p-6">
      <h1 className="text-3xl font-bold mb-4">Welcome to Tamar</h1>
      <h2 className="text-1xl font-bold mb-4">Registered Users Table</h2>
      <CopilotPopup
        instructions="You are assisting the user as best as you can. Answer in the best way possible given the data you have."
        labels={{
          title: "My Copilot AI",
          initial: "Do you need any help?",
        }}
      />
    </div>
  );
}

CopilotKit UI ships with a variety of user interfaces that you can choose from:

  • CopilotSidebar: Provides a collapsible and expandable sidebar chat interface.
  • CopilotChat: A chat interface that can be resized as you want, just like your regular chatting applications.
  • CopilotPopup: Provides a lookalike of your in-app admin (help) chatting interface. It is a floating chat icon usually at the bottom right of your screen that when clicked opens a chatting interface that can be toggled off as well.
  • CopilotKit also offers a completely headless UI that provides a fully customizable user interface.

Regardless of the CopilotKit chat interface you choose to implement, they are all customizable. You can play around with how you want it to look. For this guide though, we will be implementing the CopilotPopup UI.

We have imported the CopilotPopup component from the CopilotKit react-ui and added the component to the bottom of our application.

The component has two props:

  • The instructions prop: This tells the AI how to behave when responding to user prompts.
  • The labels prop: This is an object that contains the text in the popup chat user interface. title is the header while initial is the first message the AI sends to you when you open the chat.

Key Features of Copilot AI

According to the official CopilotKit website, CopilotKit provides you with four main features when you integrate its AI into your React application:

  • Customizable components – Components you can easily customize
  • User-data specific context – Ability to make your Copilot AI assistant context-aware by providing your application data
  • Action handling – Ability to have Copilot take actions on your behalf
  • Agent integration – Allow for the creation of more complex AI agents within your application by integrating CoAgents

Let’s Connect Our Data to Copilot AI

Connecting our application data to CopilotKit will make our Copilot AI aware of our data. That is, it will now be able to answer questions about our data and analyze our data.

To do this, we need to take two steps:

  • Fetch the data.
  • Share the data to CopilotKit using the useCopilotReadable hook.

The useCopilotReadable hook requires two props:

  • description – A short description of the data you are sharing
  • value – The data in JSON format

Fetching the Data

CopilotKit allows you to connect your data either through the frontend or backend. CopilotKit does not care where your data comes from; it just needs the data in JSON format. Whether from an API or database call, just fetch the data like you would do in any React app.

You can also choose to have Copilot AI retrieve your data from the backend for you by defining actions that can be called by your Copilot.

If your data is already in the frontend, whether it is hardcoded, from a form, or from a previous API fetch request, you are halfway to connecting your data to CopilotKit.

Sharing Your Data with Copilot

So whatever way you got your data, store it in state. Then the next step is to pass that state into the useCopilotReadable hook. In this guide, we will use data hard-coded on the frontend for easy access.

Update your page.js file with the following:

"use client";
import { useCopilotReadable } from "@copilotkit/react-core";
import { CopilotPopup } from "@copilotkit/react-ui";
import { useState } from "react";
export default function Home() {
  const [users] = useState([
    {
      name: "Janet Monrow",
      email: "janet@yupmail.com",
      dob: "23-01-1995",
      validated: true,
    },
    {
      name: "Nanret Rodriguez",
      email: "nanret@yupmail.com",
      dob: "02-03-1998",
      validated: true,
    },
    {
      name: "Jacob Costco",
      email: "jacob@yupmail.com",
      dob: "15-12-2000",
      validated: false,
    },
    {
      name: "Lilian Fisher",
      email: "lilian@yupmail.com",
      dob: "30-06-1995",
      validated: true,
    },
    {
      name: "Terdoo Lisan",
      email: "terdoo@yupmail.com",
      dob: "10-10-1995",
      validated: true,
    },
    {
      name: "johnny whip",
      email: "johnny@yupmail.com",
      dob: "12-08-1995",
      validated: false,
    },
  ]);

  useCopilotReadable({
    description: "A list of registered users in Tamar's website",
    value: users,
  });
  return (
    <div className="p-6">
      <h1 className="text-3xl font-bold mb-4">Welcome to Tamar</h1>
      <h2 className="text-1xl font-bold mb-4">Registered Users Table</h2>
      <div className="overflow-x-auto">
        <table className="min-w-full bg-white border border-gray-200 rounded-lg shadow-sm">
          <thead>
            <tr className="bg-gray-100 text-left text-sm font-semibold text-gray-600 uppercase">
              <th className="p-3 border-b">Name</th>
              <th className="p-3 border-b">Email</th>
              <th className="p-3 border-b">Date Of Birth</th>
              <th className="p-3 border-b">validated</th>
            </tr>
          </thead>
          <tbody>
            {users.map((user, i) => (
              <tr key={i} className="border-t hover:bg-gray-50">
                <td className="p-3">{user.name}</td>
                <td className="p-3">{user.email}</td>
                <td className="p-3">{user.dob}</td>
                <td className="p-3">{user.validated ? "Yes" : "No"}</td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <CopilotPopup
        instructions="You are assisting the user as best as you can. Answer in the best way possible given the data you have."
        labels={{
          title: "My Copilot AI",
          initial: "Do you need any help?",
        }}
      />
    </div>
  );
}

The useCopilotReadable hook expects an object with two properties:

  • value – Represents the data to be passed to the AI. Here we fed our hard-coded users array.
  • description – This is a brief explanation of the data.

We also added a table that simply displays our users data.

Finally, let us start our local server by running the following command:

npm run dev

Now that it is up and running, let’s ask Copilot some interesting questions like what users are not validated in our users data.

Ask Copilot AI questions

As you can see, now our AI is context-aware. It can answer questions about the data we fed it. There are two ways to interact with the Copilot AI. You can talk to it directly, which is the usual and standard way (the way we just did). You can use something called CoAgents, which are like smarter assistants that can plan and execute tasks with more context (e.g., LangGraph and CrewAI).

Enable Copilot to Send Emails for Us

AI can handle many tasks independently, but it needs clear instructions to achieve its objectives, especially when interfacing with external services. Now we are going to use the useCopilotAction hook to define exactly what should happen and how it should happen.

Update your page.js file so that Copilot AI can take action for us:

import { useCopilotAction, useCopilotReadable } from "@copilotkit/react-core";
useCopilotAction({
  name: "sendEmailToUser",
  description: "Send a custom email to a specific user",
  parameters: [
    {
      name: "recipient",
      type: "string",
      description: "The recipient's email address",
    },
    {
      name: "subject",
      type: "string",
      description: "The subject of the email",
    },
    {
      name: "body",
      type: "string",
      description: "The body of the email",
    },
  ],
  handler: async ({ recipient, subject, body }) => {
    //our not yet defined sendEmail function
  },
});

We begin by importing the useCopilotAction hook from CopilotKit’s react-core.

The useCopilotAction hook accepts a single object that represents a specific action. The object must have four properties:

  • name – The special name of the action we are about to let Copilot take for us.
  • description – A short description of what the action will do.
  • parameters – An array of variables that will be needed for the action to be carried out. They will eventually be passed to the handler() function, which will then use them to carry out the action
  • handler – An asynchronous function that performs the actual logic to carry out the action that useCopilotAction will perform.

If you want multiple actions, you can call useCopilotAction as many times as you like.

Creating a Function That Sends an Email

Now let’s create a function called sendEmail() that sends emails so that the useCopilotAction handler can use that to send emails for us. Update the page.js file with the following:

const sendEmail(recipient, subject, body){
  const SERVICE_ID = 'EMAILJS_SERVICE_ID';
  const TEMPLATE_ID = 'EMAILJS_TEMPLATE_ID';
  const PUBLIC_KEY = 'EMAILJS_PUBLIC_KEY';
  if (!SERVICE_ID || !TEMPLATE_ID || !PUBLIC_KEY) {
    return "invalid configuration";
  }
    try {
      await emailjs.send( SERVICE_ID, TEMPLATE_ID,
        {
          to_email: recipient,
          subject,
          message: body,
        },PUBLIC_KEY
      );
      console.log(`Email sent to ${recipient}`);
      return `Email sent to ${recipient}`;
    } catch (error) {
      console.error("Email error:", error);
      return `Failed to send email to ${recipient}`;
    }
}

The code snippet above shows the function that holds the logic that can send emails. The function requires three parameters: a recipient, a subject and a body.

This function uses the EmailJS SDK to send emails to users. You can create an account with EmailJS to get the credentials needed to use the SDK, which are: service ID, template ID and public key.

Asking copilot to send email

From our data, we know that Johnny Whip and Jacob Costco are the users with accounts that have not been validated. As seen in the picture above, in the console, Copilot excellently sends email notifications to the right emails.

And in the chatting area, Copilot says emails were successfully sent! Now let’s verify if that is true by checking the users’ emails to see if the emails Copilot sent for us were received.

Johnny’s email clientl

Jacobs email client

The pictures above clearly show that the emails from admin@tamar.com definitely came in for both Johnny and Jacob. The emails were nicely worded and personalized with full names.

Conclusion

From this guide, we have shown that with just a couple of steps, we can turn a simple Next.js app into one with AI-powered task automation abilities. We can see that Copilot AI is not just a chatbot. It is a machine that, when made knowledgeable about our data, can quickly move beyond answering questions to taking actions inside your application and can even work with external services.

It is important to note that while Copilot AI is powerful on its own, it is even more effective, relational and accurate with human guidance. It works its very best when given the right data, clear instructions and permissions to perform meaningful tasks.


About the Author

Christian Nwamba

Chris Nwamba is a Senior Developer Advocate at AWS focusing on AWS Amplify. He is also a teacher with years of experience building products and communities.

Related Posts

Comments

Comments are disabled in preview mode.