<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Farhan Ahmad</title>
    <description>The latest articles on Forem by Farhan Ahmad (@coding_farhan).</description>
    <link>https://forem.com/coding_farhan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2561929%2F32c4c0d9-4574-4059-a50a-9b32e944b8dd.jpeg</url>
      <title>Forem: Farhan Ahmad</title>
      <link>https://forem.com/coding_farhan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/coding_farhan"/>
    <language>en</language>
    <item>
      <title>Build stateful AI agents using Mem0</title>
      <dc:creator>Farhan Ahmad</dc:creator>
      <pubDate>Sat, 30 Aug 2025 11:52:35 +0000</pubDate>
      <link>https://forem.com/coding_farhan/build-stateful-ai-agents-using-mem0-4b1c</link>
      <guid>https://forem.com/coding_farhan/build-stateful-ai-agents-using-mem0-4b1c</guid>
      <description>&lt;p&gt;You may have interacted with (or built) many AI bots in the last few years. Most of them serve a basic purpose (like helping with customer support) but many lack the ability to remember the user's preferences and conversations from previous sessions (which means the agents are &lt;strong&gt;stateless&lt;/strong&gt;), so every new session with the AI agent feels like you're starting with a blank slate.&lt;/p&gt;

&lt;p&gt;This is where the concept of &lt;strong&gt;stateful&lt;/strong&gt; agents comes in.&lt;br&gt;
An an Agent that actually remembers your user's preferences and past behaviors (a &lt;strong&gt;stateful&lt;/strong&gt; agent), and then uses that info to guide the user is extremely helpful. This helps the user reach their goals faster and the conversation flows more smoothly which ultimately keeps your users happy with your product/service.&lt;/p&gt;

&lt;p&gt;Let's see how &lt;a href="https://mem0.ai/" rel="noopener noreferrer"&gt;Mem0&lt;/a&gt; makes it possible to build stateful agents in a few easy steps.&lt;/p&gt;
&lt;h2&gt;
  
  
  What's Mem0?
&lt;/h2&gt;

&lt;p&gt;To put it simply, &lt;a href="https://mem0.ai/" rel="noopener noreferrer"&gt;Mem0&lt;/a&gt; is a framework that helps your agent remember the user's past behaviors and preferences by storing the conversation and also helping you retrieve it as needed, using natural language. It does the heavy lifting for us, all we have to do is add a couple of lines of code in our app and we're good to go.&lt;/p&gt;

&lt;p&gt;With Mem0 you can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Store conversations&lt;/li&gt;
&lt;li&gt;Get older conversations&lt;/li&gt;
&lt;li&gt;Search Conversations using natural language&lt;/li&gt;
&lt;li&gt;Update stored conversations as needed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this tutorial we'll build a very simple Next.js app that showcases the power of this framework. We'll keep it super easy to follow and beginner friendly :)&lt;/p&gt;
&lt;h2&gt;
  
  
  Overview of what we're building today
&lt;/h2&gt;

&lt;p&gt;We're going to be building a very basic but powerful &lt;strong&gt;stateful&lt;/strong&gt; agent. We'll be using the below stack for this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Typescript framework - Next.js&lt;/li&gt;
&lt;li&gt;LLM provider - OpenAI&lt;/li&gt;
&lt;li&gt;Memory layer - Mem0&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzhkiyo4395461h9v8lh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzhkiyo4395461h9v8lh.gif" alt="Mem0 helps your agent remember" width="480" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our goal is to demonstrate the concept of &lt;strong&gt;stateful&lt;/strong&gt; agents using Mem0, which is why we'll keep this tutorial simple and beginner-friendly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started (Next.js project initialization)
&lt;/h2&gt;

&lt;p&gt;Alright, we'll start with initializing a Next.js app using &lt;code&gt;create-next-app&lt;/code&gt; (I know, I'm a lazy guy).&lt;/p&gt;

&lt;p&gt;If you don't already have npx installed, use this command to install it:&lt;br&gt;
&lt;code&gt;npm install -g npx&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Fire up your favorite text editor, open the command line and type the below command to initialize a new project:&lt;br&gt;
&lt;code&gt;npx create-next-app@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It's going to ask you a bunch of questions, starting with the project name, linter choice, etc. If you're new, you can just follow my lead according to the screenshot below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqywrh0j0bdu4asef5byv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqywrh0j0bdu4asef5byv.png" alt="Initializing new project using create-next-app" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the project name I specified was "smart-agent". After this step, a new project gets initialized with the name "smart-agent" (or whatever name that you chose to specify) on the left hand side in VS Code (see screenshot below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8otvy9bsu11wncuqvrww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8otvy9bsu11wncuqvrww.png" alt="Project structure for newly initialized nextjs project" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A good way to get familiar with Next.js is to expand/collapse each folder in this project to get a feel for how things are structured and how different components inside the app interact with each other.&lt;/p&gt;
&lt;h2&gt;
  
  
  Try running the app to see all's good
&lt;/h2&gt;

&lt;p&gt;Use the command below to switch to the project directory inside the CLI (remember, in my case the name of the agent is "smart-agent"):&lt;br&gt;
&lt;code&gt;cd smart-agent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now run the below command to run the server:&lt;br&gt;
&lt;code&gt;npm run dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;(Screenshot for reference)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1p5b0mipnk5utvzih0a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1p5b0mipnk5utvzih0a.png" alt="CLI command to run Nextjs app" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now when you open your browser and search for "localhost:3000" you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmccprh9d2ntz4mvdgqb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcmccprh9d2ntz4mvdgqb.png" alt="A running Nextjs app" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool! That means our app is officially set up. Let's add some features now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a simple chat feature
&lt;/h2&gt;

&lt;p&gt;For the next step we'll create a simple app that will help us interact with the LLM using the OpenAI API. We're not going to worry about adding the "remembering feature" just now to keep things simple.&lt;/p&gt;

&lt;p&gt;The very first thing we'll need is the OpenAI API key. Let's go grab it from OpenAI's website. Go to the URL &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;https://platform.openai.com/api-keys&lt;/a&gt; where you can either use an existing API key or create a new one.&lt;/p&gt;

&lt;p&gt;Once you have copied the API key, come back to VS code and add it to our project's environment variable. To do this we'll create a new file called ".env.local" signifying that this file is for the local environment. So when we run &lt;code&gt;npm run dev&lt;/code&gt; and start the server, the server will pick up all values specified here. You can refer to the screenshot below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwqf9ek7f8b226shebpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwwqf9ek7f8b226shebpt.png" alt="Adding OpenAI API key inside Next.js project" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, now that we have added the API key, let's go ahead and install the official openai package to interact with the LLM API.&lt;/p&gt;

&lt;p&gt;Run the below command to install the "openai" package:&lt;br&gt;
&lt;code&gt;npm i openai&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can see below that the openai package was added to the &lt;strong&gt;package.json&lt;/strong&gt; file:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fau7k2t3x5x1ufnpx7y1x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fau7k2t3x5x1ufnpx7y1x.png" alt="installed package" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Alright let's now build the UI and logic for our chat app
&lt;/h3&gt;

&lt;p&gt;Since our app was initialized using create-next-app, the &lt;strong&gt;page.tsx&lt;/strong&gt; file is the easiest way to update the UI of our app. To keep this tutorial super easy, we'll only update &lt;strong&gt;page.tsx&lt;/strong&gt; file (and one server file) to build out our app.&lt;/p&gt;

&lt;p&gt;Go ahead and copy the below code and paste it in your &lt;strong&gt;page.tsx&lt;/strong&gt; file (replacing the older code):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client"

import { useEffect, useRef, useState } from "react"

type Role = "system" | "user" | "assistant"

export type ChatMessage = {
  role: Role
  content: string
}

export default function Page() {
  return &amp;lt;Chat /&amp;gt;
}

function Chat() {
  const [messages, setMessages] = useState&amp;lt;ChatMessage[]&amp;gt;([
    {
      role: "system",
      content: "You are a concise, friendly assistant. Keep answers under ~120 words unless asked.",
    },
  ])

  const [input, setInput] = useState("")
  const [pending, setPending] = useState(false)
  const [error, setError] = useState&amp;lt;string | null&amp;gt;(null)
  const bottomRef = useRef&amp;lt;HTMLDivElement&amp;gt;(null)

  useEffect(() =&amp;gt; {
    bottomRef.current?.scrollIntoView({ behavior: "smooth" })
  }, [messages, pending])

  async function send() {
    const text = input.trim()
    if (!text || pending) return

    // Add the user's message locally first
    const next = [...messages, { role: "user" as const, content: text }]
    setMessages(next)
    setInput("")
    setPending(true)
    setError(null)

    try {
      const res = await fetch("/api/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ messages: next }),
      })

      if (!res.ok) throw new Error(`HTTP ${res.status}`)

      const data: { reply?: string } = await res.json()
      const reply = data.reply ?? "(No response)"

      setMessages((cur) =&amp;gt; [...cur, { role: "assistant", content: reply }])

      /* eslint-disable @typescript-eslint/no-explicit-any */
    } catch (e: any) {
      console.error(e)
      setError(e?.message || "Something went wrong.")
      setMessages((cur) =&amp;gt; [...cur, { role: "assistant", content: "Sorry—something went wrong. Try again." }])
    } finally {
      setPending(false)
    }
  }

  function onSubmit(e: React.FormEvent) {
    e.preventDefault()
    void send()
  }

  return (
    &amp;lt;div className="flex flex-col h-[100svh] max-w-2xl mx-auto p-4 gap-3"&amp;gt;
      &amp;lt;header className="flex items-center justify-between"&amp;gt;
        &amp;lt;h1 className="text-xl font-semibold"&amp;gt;Simple Chat&amp;lt;/h1&amp;gt;
      &amp;lt;/header&amp;gt;

      &amp;lt;main className="flex-1 overflow-y-auto rounded-2xl border bg-white p-3 space-y-3 text-black"&amp;gt;
        {/* Hide system message from the transcript */}
        {messages
          .filter((m) =&amp;gt; m.role !== "system")
          .map((m, i) =&amp;gt; (
            &amp;lt;Bubble key={i} role={m.role} text={m.content} /&amp;gt;
          ))}
        {pending &amp;amp;&amp;amp; &amp;lt;Bubble role="assistant" text="…thinking" muted /&amp;gt;}
        &amp;lt;div ref={bottomRef} /&amp;gt;
      &amp;lt;/main&amp;gt;

      &amp;lt;form onSubmit={onSubmit} className="flex gap-2"&amp;gt;
        &amp;lt;input
          value={input}
          onChange={(e) =&amp;gt; setInput(e.target.value)}
          placeholder="Type a message and press Enter…"
          className="flex-1 px-4 py-2 rounded-xl border outline-none"
          aria-label="Message"
        /&amp;gt;
        &amp;lt;button type="submit" disabled={!input.trim() || pending} className="px-4 py-2 rounded-xl border shadow disabled:opacity-50"&amp;gt;
          Send
        &amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;

      {error &amp;amp;&amp;amp; (
        &amp;lt;p className="text-xs text-red-600" role="alert"&amp;gt;
          {error}
        &amp;lt;/p&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  )
}

function Bubble({ role, text, muted }: { role: Role; text: string; muted?: boolean }) {
  const isUser = role === "user"
  return (
    &amp;lt;div
      className={
        "max-w-[85%] whitespace-pre-wrap px-4 py-2 rounded-2xl shadow " +
        (isUser ? "bg-gray-200 ml-auto" : "bg-white border") +
        (muted ? " text-gray-500" : "")
      }
    &amp;gt;
      {text}
    &amp;lt;/div&amp;gt;
  )
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you're done updating your &lt;strong&gt;page.tsx&lt;/strong&gt; file, open your browser and visit &lt;strong&gt;localhost:3000&lt;/strong&gt; URL and you'll see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnqgnirhu68v1p5864cg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmnqgnirhu68v1p5864cg.png" alt="Chat app's updated UI" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our app is taking shape for sure! But if you try sending a message it'll throw an error, because we have only implemented the UI, and we still need to add the logic to communicate with OpenAI's LLM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a new route to handle requests to OpenAI API
&lt;/h3&gt;

&lt;p&gt;Whenever the user sends a message, we want that message to be sent to OpenAI's LLM and receive back a response. Finally, we want to add this LLM's response to the chat UI. Age old game of state updates and API requests. Let's get it going.&lt;/p&gt;

&lt;p&gt;Create a new folder inside the &lt;strong&gt;app&lt;/strong&gt; folder named &lt;strong&gt;api&lt;/strong&gt;, and within &lt;strong&gt;api&lt;/strong&gt; folder create another folder named &lt;strong&gt;chat&lt;/strong&gt;. Inside the &lt;strong&gt;chat&lt;/strong&gt; folder create a new file called &lt;strong&gt;route.ts&lt;/strong&gt; as shown in the screenshot:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxgk4xka28lfrh5cn5jb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxgk4xka28lfrh5cn5jb.png" alt="New project structure after creating a new route" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see that our &lt;strong&gt;route.ts&lt;/strong&gt; file is empty. Let's paste the below code into the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextRequest, NextResponse } from "next/server"
import OpenAI from "openai"

export const runtime = "nodejs"
export const dynamic = "force-dynamic" // avoid caching

export async function POST(req: NextRequest) {
  if (!process.env.OPENAI_API_KEY) {
    return NextResponse.json({ error: "Missing OPENAI_API_KEY on the server." }, { status: 500 })
  }

  let body: unknown
  try {
    body = await req.json()
  } catch {
    return NextResponse.json({ error: "Invalid JSON body." }, { status: 400 })
  }
  /* eslint-disable @typescript-eslint/no-explicit-any */
  const { messages } = (body as any) || {}

  if (!Array.isArray(messages) || messages.length === 0) {
    return NextResponse.json({ error: "'messages' must be a non-empty array." }, { status: 400 })
  }

  try {
    const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

    const completion = await openai.chat.completions.create({
      model: "gpt-4.1-nano", // an affordable model here
      messages,
    })

    const reply = completion.choices?.[0]?.message?.content?.trim() ?? ""

    return NextResponse.json({ reply })
  } catch (err: any) {
    console.error("/api/chat error:", err?.response?.data || err?.message || err)
    return NextResponse.json({ error: "Something went wrong generating a reply." }, { status: 500 })
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now run the server if it isn't already using &lt;code&gt;npm run dev&lt;/code&gt; and you should be able to talk to the AI as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F787pnp70kzy0gy5v30us.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F787pnp70kzy0gy5v30us.png" alt="AI chat feature works!" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  But.. why do we want our Agent to remember?
&lt;/h3&gt;

&lt;p&gt;Before we get into implementing the memory feature, lets quickly demonstrate why we need this memory feature.&lt;/p&gt;

&lt;p&gt;As shown in the GIF below, try telling the agent something about your likes/preferences (for example, "My favorite travel destination is Japan"). Then go ahead and refresh the page. Once the page is refreshed ask the agent about your preference that you had mentioned earlier ("What's my favorite travel destination?"). &lt;/p&gt;

&lt;p&gt;You'll quickly notice that the agent doesn't remember anything about you:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynacmk9jomlv9wzuxgsy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynacmk9jomlv9wzuxgsy.gif" alt="GIF" width="480" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this is why we want to add memory to the agent. This will help the agent remember user's preferences across different user sessions, as you'll see soon.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding the ability to remember using Mem0
&lt;/h2&gt;

&lt;p&gt;Okay now that our simple chat feature is ready let's give our app the ability to remember user's preferences from past conversations. We'll use &lt;strong&gt;Mem0&lt;/strong&gt; for implementing this feature. If you are someone who prefers reading docs first, feel free to read Mem0's quick start guide if you want to dive deeper using this link: &lt;a href="https://docs.mem0.ai/quickstart" rel="noopener noreferrer"&gt;Mem0's Quick-start guide&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Two ways to use Mem0
&lt;/h3&gt;

&lt;p&gt;Broadly speaking, there are two ways to use Mem0. You can either: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use Mem0's cloud platform to manage your conversations using a &lt;strong&gt;MEM0_API_KEY&lt;/strong&gt; (easiest)&lt;/li&gt;
&lt;li&gt;or, you can choose to host Mem0's open-source version on your own infra (hard + time consuming)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this tutorial, for the sake of keeping things simple, we'll use Mem0's platform for building out our agent in an instant.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up Mem0 in our project
&lt;/h3&gt;

&lt;p&gt;Let's start by installing the npm package &lt;code&gt;mem0ai&lt;/code&gt; using the below command:&lt;br&gt;
&lt;code&gt;npm install mem0ai&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After running the command our &lt;strong&gt;package.json&lt;/strong&gt; should be updated as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnc6kzcs1byqumvb412.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fopnc6kzcs1byqumvb412.png" alt="installed mem0 package" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we have the package installed, there is one more step that's required before we can start using Mem0. We need to grab an API key for Mem0's website to actually make it work. &lt;/p&gt;

&lt;p&gt;Head over to this URL &lt;a href="https://app.mem0.ai/login" rel="noopener noreferrer"&gt;https://app.mem0.ai/login&lt;/a&gt; and create a new account if you haven't already. &lt;/p&gt;

&lt;p&gt;Once you're done, head over to &lt;a href="https://app.mem0.ai/dashboard/get-started" rel="noopener noreferrer"&gt;https://app.mem0.ai/dashboard/get-started&lt;/a&gt; and copy your API key. At the time when I'm writing this, that page should look something like below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8g30e5w8u6m0m8f2zbs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8g30e5w8u6m0m8f2zbs.png" alt="Copy API key from Mem0's dashboard" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've copied the API key come back to your code editor and open the &lt;strong&gt;.env.local&lt;/strong&gt; file and add the API key you just copied as &lt;code&gt;MEM0_API_KEY&lt;/code&gt;. See the screenshot below for reference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflbabdcb6dxkp7xnpp4y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflbabdcb6dxkp7xnpp4y.png" alt="updated .env.local file" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nice! let's start implementing the memory feature using the mem0 library.&lt;/p&gt;
&lt;h2&gt;
  
  
  Implementing Mem0 in our route.ts file
&lt;/h2&gt;

&lt;p&gt;We know that Mem0 allows us to store conversations and search from older one's using natural language. Let's now see it in action by implementing it in our app.&lt;/p&gt;

&lt;p&gt;Go into the &lt;strong&gt;route.ts&lt;/strong&gt; file that we created earlier inside &lt;strong&gt;app/api/chat&lt;/strong&gt; folder. Next, replace the code inside &lt;strong&gt;route.ts&lt;/strong&gt; file with the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextRequest, NextResponse } from "next/server"
import OpenAI from "openai"
import MemoryClient from "mem0ai"
import { ChatCompletionMessageParam } from "openai/resources"

export const runtime = "nodejs"
export const dynamic = "force-dynamic" // avoid caching

export async function POST(req: NextRequest) {
  const mem0 = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! })

  if (!process.env.OPENAI_API_KEY) {
    return NextResponse.json({ error: "Missing OPENAI_API_KEY on the server." }, { status: 500 })
  }

  let body: unknown
  try {
    body = await req.json()
  } catch {
    return NextResponse.json({ error: "Invalid JSON body." }, { status: 400 })
  }
  /* eslint-disable @typescript-eslint/no-explicit-any */
  const { messages } = (body as any) || {}

  if (!Array.isArray(messages) || messages.length === 0) {
    return NextResponse.json({ error: "'messages' must be a non-empty array." }, { status: 400 })
  }

  const userId: string = (body as any)?.userId || "demo-user"
  const lastUserContent = [...messages].reverse().find((m: any) =&amp;gt; m.role === "user")?.content || ""

  let memoryContext = ""
  try {
    console.log("searching from memory...")
    const hits = await mem0.search(lastUserContent || "recent preferences", { user_id: userId })
    // Each hit can be an object; we try common fields (text/memory/value)
    const lines = (Array.isArray(hits) ? hits : [])
      .map((m: any) =&amp;gt; m?.text ?? m?.memory ?? m?.value ?? "")
      .filter(Boolean)
      .slice(0, 6)
    if (lines.length) {
      memoryContext = "Known about user (from memory): \n" + lines.join(" - ")
    }
  } catch (e) {
    console.log("mem0.search error", e)
  }

  // Prepend memory context so the model can personalize
  const messagesWithMemory: ChatCompletionMessageParam[] = memoryContext
    ? [
        { role: "system", content: "Use the following user memory if helpful. Don’t repeat it verbatim." },
        { role: "system", content: memoryContext },
        ...messages,
      ]
    : messages

  try {
    const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })

    const completion = await openai.chat.completions.create({
      model: "gpt-4.1-nano", // an affordable model here
      messages: messagesWithMemory,
    })
    const reply = completion.choices?.[0]?.message?.content?.trim() ?? ""

    try {
      // Grab the latest user turn as a natural-language search query for Mem0
      console.log("adding to memory...")
      const lastUserMessage = [...messages].reverse().find((m: any) =&amp;gt; m?.role === "user")
      const messagesToStore = [
        lastUserMessage ? { role: "user", content: lastUserMessage.content } : messages[messages.length - 1],
        { role: "assistant", content: reply },
      ]
      await mem0.add(messagesToStore as any, { user_id: userId, metadata: { category: "chat" } })
    } catch (e) {
      console.log("mem0.add failed:", e)
    }

    return NextResponse.json({ reply })
  } catch (err: any) {
    console.error("/api/chat error:", err?.response?.data || err?.message || err)
    return NextResponse.json({ error: "Something went wrong generating a reply." }, { status: 500 })
  }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Can you spot the changes that we made? Let's go through these new changes one by one below.&lt;/p&gt;

&lt;p&gt;First, we initialized a new mem0 client:&lt;br&gt;
&lt;code&gt;const mem0 = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! })&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice that we're passing the &lt;strong&gt;MEM0_API_KEY&lt;/strong&gt; environment variable we had added earlier to &lt;strong&gt;.env.local&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Next, we added this block of code to search the conversation in Mem0 using user's recent message:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const userId: string = (body as any)?.userId || "demo-user"
  const lastUserContent = [...messages].reverse().find((m: any) =&amp;gt; m.role === "user")?.content || ""

  let memoryContext = ""
  try {
    console.log("searching from memory...")
    const hits = await mem0.search(lastUserContent || "recent preferences", { user_id: userId })
    // Each hit can be an object; we try common fields (text/memory/value)
    const lines = (Array.isArray(hits) ? hits : [])
      .map((m: any) =&amp;gt; m?.text ?? m?.memory ?? m?.value ?? "")
      .filter(Boolean)
      .slice(0, 6)
    if (lines.length) {
      memoryContext = "Known about user (from memory): \n" + lines.join(" - ")
    }
  } catch (e) {
    console.log("mem0.search error", e)
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, every conversation thats stored needs some kind of identifier. In our app we haven't implemented authentication which is why we'll simply mock the user_id value to be "demo-user".&lt;br&gt;
Then, we use &lt;code&gt;mem0.search()&lt;/code&gt; to search for any memory that could help us learn about the user's preferences that belongs to the unique &lt;strong&gt;user_id&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And now finally, we've also added logic to store the conversations in Mem0 as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
      // Grab the latest user turn as a natural-language search query for Mem0
      console.log("adding to memory...")
      const lastUserMessage = [...messages].reverse().find((m: any) =&amp;gt; m?.role === "user")
      const messagesToStore = [
        lastUserMessage ? { role: "user", content: lastUserMessage.content } : messages[messages.length - 1],
        { role: "assistant", content: reply },
      ]
      await mem0.add(messagesToStore as any, { user_id: userId, metadata: { category: "chat" } })
    } catch (e) {
      console.log("mem0.add failed:", e)
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code adds the last assistant message + the last user message to conversation. We do this so that only the new messages get stored in Mem0 and not the entire conversation history. This helps us save cost and prevents duplicate memory from being saved in Mem0.&lt;/p&gt;

&lt;p&gt;And that's pretty much all we need! Our agent now has the ability to learn user's preferences and remember them across sessions. Let's try it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trying out our Mem0 Agent
&lt;/h2&gt;

&lt;p&gt;Okay let's take for a run now. We'll tell the agent about our favorite color, refresh the page and ask it about our favorite color again to see if it remembers anything.&lt;/p&gt;

&lt;p&gt;Below is a GIF of me doing it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzhkiyo4395461h9v8lh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkzhkiyo4395461h9v8lh.gif" alt="Mem0 helps your agent remember" width="480" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Voila! Your agent will now remember anything you talk about, even across sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can we see the stored memories in Mem0?
&lt;/h3&gt;

&lt;p&gt;Yes you can also see the memories that are stored with Mem0 for every user_id. Go to your Mem0 dashboard here: &lt;a href="https://app.mem0.ai/dashboard/memories" rel="noopener noreferrer"&gt;https://app.mem0.ai/dashboard/memories&lt;/a&gt; and you'll see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0q9obroar4xuq5n1xfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0q9obroar4xuq5n1xfp.png" alt="Mem0 memories for every user_id in dashboard" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that every memory is associated with a &lt;strong&gt;user_id&lt;/strong&gt;. The memory "favorite color is blue" is associated with "demo-user".&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There's no doubt &lt;strong&gt;stateful&lt;/strong&gt; agents will become the standard in the near future. We'll stop seeing generic customer chat bots and instead, chat bots that remember everything about you from your past interactions will become the norm. &lt;br&gt;
This is still the beginning and the reason I like solutions like &lt;strong&gt;Mem0&lt;/strong&gt; so much is because how easy it is to use for beginners to build complex stateful agents in no time.&lt;/p&gt;

&lt;p&gt;As always, if you found this article useful, feel free to follow me here or on Linkedin (&lt;a href="https://www.linkedin.com/in/farhans-profile/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/farhans-profile/&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Cheers!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>node</category>
      <category>typescript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Step-by-Step Guide to Building Domain-Specific AI Agents with Phidata SDK</title>
      <dc:creator>Farhan Ahmad</dc:creator>
      <pubDate>Wed, 22 Jan 2025 09:21:03 +0000</pubDate>
      <link>https://forem.com/coding_farhan/step-by-step-guide-to-building-domain-specific-ai-agents-with-phidata-sdk-4l6f</link>
      <guid>https://forem.com/coding_farhan/step-by-step-guide-to-building-domain-specific-ai-agents-with-phidata-sdk-4l6f</guid>
      <description>&lt;p&gt;AI Agents are gaining a lot of popularity these days and businesses are rushing to build their own agents. Some prefer building an AI Agent from scratch, but what often bothers devs the most is the time is takes to build and test different AI Tools (for function calling). This can lead to a high development time.&lt;/p&gt;

&lt;p&gt;However as time passes we're seeing new solutions popping up every now and then to help develoeprs streamline the process of building AI Agents. One such solution is &lt;strong&gt;Phidata&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Phidata?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Phidata&lt;/strong&gt; SDK makes it super easy to build AI Agents in just a few lines of Python code. The best part is that it provides useful AI Tools right out of the box, so you don't need to write them from scratch yourself.&lt;/p&gt;

&lt;p&gt;Some of the AI Tools Phidata offers out of the box:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Search, Exa (for Web Search)&lt;/li&gt;
&lt;li&gt;Resend (to send Emails)&lt;/li&gt;
&lt;li&gt;Crawl4AI and Firecrawl (to crawl the web)&lt;/li&gt;
&lt;li&gt;DuckDB (for Data Analysis)&lt;/li&gt;
&lt;li&gt;Python Agent (to write and run Python code)&lt;/li&gt;
&lt;li&gt;Files (for reading files to build a RAG Agent)&lt;/li&gt;
&lt;li&gt;GitHub (to interact with GitHub)&lt;/li&gt;
&lt;li&gt;CalCom Agent (to schedule meetings using Cal.com)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and many more!&lt;br&gt;
You can see an exhaustive list of Tools provided by Phidata &lt;a href="https://docs.phidata.com/tools/toolkits" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using one or a combination of the above tools, we can build really complex and exciting AI Agents, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data Analyst Agent&lt;/li&gt;
&lt;li&gt;Research Agent&lt;/li&gt;
&lt;li&gt;Sales Agent&lt;/li&gt;
&lt;li&gt;Shopping Agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;just to name a few. &lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Advanced Agents using "Team Agent"
&lt;/h2&gt;

&lt;p&gt;Something cool about &lt;strong&gt;Phidata&lt;/strong&gt; SDK is that you have the option to combine multiple Tools into a team, known as a "&lt;strong&gt;Team Agent&lt;/strong&gt;". For example, you can create a team with the "DuckDuckGo" and "Yahoo Finance" Tools which can get the data from both sources, the &lt;strong&gt;web&lt;/strong&gt; as well as &lt;strong&gt;Yahoo Finance&lt;/strong&gt;. &lt;br&gt;
This Team Agent will work the following way:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The user gives the following command to the Agent: &lt;em&gt;"Summarize analyst recommendations and share the latest news for NVDA"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Our agent searches the web for the latest news on the company Nvidia&lt;/li&gt;
&lt;li&gt;Agent also searches for the ticker "NVDA" on Yahoo Finance to get the company's financial data&lt;/li&gt;
&lt;li&gt;Finally, our Agent presents the data from both sources (the &lt;strong&gt;Web&lt;/strong&gt; and &lt;strong&gt;Yahoo Finance&lt;/strong&gt;) in a nice table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pretty cool huh?&lt;/p&gt;

&lt;p&gt;So now that we have some idea of what's possible using the &lt;strong&gt;Phidata&lt;/strong&gt; SDK, let's go ahead and see how we can use it to create a simple Financial Analyst Agent.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started with Phidata SDK
&lt;/h2&gt;

&lt;p&gt;Let's start building our Financial Analyst Agent. It's going to be super beginner-friendly so don't worry about falling behind. &lt;/p&gt;

&lt;p&gt;We're going to create our Agent inside a Jupyter Notebook on &lt;strong&gt;Google Colab&lt;/strong&gt;, which is very interactive and easy to share. &lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1 - Create a new Notebook on Google Colab
&lt;/h2&gt;

&lt;p&gt;Go to Google Colab using by clicking &lt;a href="https://docs.phidata.com/tools/toolkits" rel="noopener noreferrer"&gt;here&lt;/a&gt; and you should see this screen:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsqlr2yzptw987tzn3eu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsqlr2yzptw987tzn3eu.png" alt="Go to Google Colab" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click on the "New Notebook" button:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fima46b8cux14xr1m9e5f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fima46b8cux14xr1m9e5f.png" alt="Click on New Notebook button" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It may load for a while, but after that you should arrive at the newly created notebook which will look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F75kl1sk44q7gjtaapiwc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F75kl1sk44q7gjtaapiwc.png" alt="New Notebook created on Google Colab" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great, let's move to the next step.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2 - Installing all required libraries in the Notebook
&lt;/h2&gt;

&lt;p&gt;Before we can start creating our AI agent, we need to make sure we have the required dependencies available inside the Notebook. Note that Google Colab comes with some common libraries pre-installed in the Notebook, but to make sure we have all the libraries we need, we'll install all of them anyway.&lt;/p&gt;

&lt;p&gt;We'll install the following libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;yfinance&lt;/strong&gt; - To get company's financial data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;openai&lt;/strong&gt; - To allow Phidata to use OpenAI's LLM to make the AI agent come to life&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;duckduckgo-search&lt;/strong&gt; - To search the web using DuckDuckGo&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phidata&lt;/strong&gt; - To load up the pre-written AI Tools for function calling and to create a Team Agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To install these libraries, copy the below command and paste it inside the first cell block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install openai yfinance duckduckgo-search phidata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should look like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdem7t4yxicn63vsk2e5b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdem7t4yxicn63vsk2e5b.png" alt="Installing all libraries inside Google Colab Notebook" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, click on the play icon on the left as shown below:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuntyhjt6yn4j68wh7kt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjuntyhjt6yn4j68wh7kt.png" alt="Run the cell" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now give it some time to install all dependencies. Once done installing, you should see a tiny green check mark on the left of the Run button like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoita1ksfjyxrtvsnn5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feoita1ksfjyxrtvsnn5v.png" alt="Image description" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's hide the cell's output since it's taking a lot of space in the Notebook. Click on the button right below the "Run" button and then click on "Show/hide output".&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4mpzhbl7cmy4wtz0kc9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4mpzhbl7cmy4wtz0kc9.png" alt="Hide the Cell output" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3 - Adding the OPENAI_API_KEY environment variable
&lt;/h2&gt;

&lt;p&gt;Now we need to add the OpenAI API key to our environment. Go ahead and add a new cell to the Notebook by clicking on the button as shown below:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmcdqlt02fpnj6xtgw1t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffmcdqlt02fpnj6xtgw1t.png" alt="Add a new cell to Notebook" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now inside this new cell paste the following code and Run it. Replace the &lt;strong&gt;your_api_key&lt;/strong&gt; value with your actual OpenAI API key that you can get from &lt;strong&gt;&lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;https://platform.openai.com/api-keys&lt;/a&gt;&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os

os.environ['OPENAI_API_KEY'] = "your_api_key"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should look something like this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqfzce969kh0us4qtz68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqfzce969kh0us4qtz68.png" alt="Setting the OPENAI_API_KEY environment variable" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4 - Write code for the Agent
&lt;/h2&gt;

&lt;p&gt;In this last step we'll write the actual code for the Agent. Since this is an "Agent Team" (which means that it is an AI agent made of multiple agents), we'll start by creating 2 agents using the Phidata SDK, namely &lt;strong&gt;web_agent&lt;/strong&gt; and &lt;strong&gt;finance_agent&lt;/strong&gt;. The web agent will search the web for news about the company and the finance agent will search Yahoo Finance for the company's financial data. Finally, we'll create a third Agent by passing these 2 agents to the "teams" array of this Agent, which will result in the creation of an "Agent Team". &lt;br&gt;
This third Agent will be the final Agent that we'll use for getting a company's data from web and Yahoo Finance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from phi.agent import Agent
from phi.model.openai import OpenAIChat
from phi.tools.duckduckgo import DuckDuckGo
from phi.tools.yfinance import YFinanceTools

web_agent = Agent(
    name="Web Agent",
    role="Search the web for information",
    model=OpenAIChat(id="gpt-4o"),
    tools=[DuckDuckGo()],
    instructions=["Always include sources"],
    show_tool_calls=True,
    markdown=True,
)

finance_agent = Agent(
    name="Finance Agent",
    role="Get financial data",
    model=OpenAIChat(id="gpt-4o"),
    tools=[YFinanceTools(stock_price=True, analyst_recommendations=True, company_info=True)],
    instructions=["Use tables to display data"],
    show_tool_calls=True,
    markdown=True,
)

agent_team = Agent(
    team=[web_agent, finance_agent],
    instructions=["Always include sources", "Use tables to display data"],
    show_tool_calls=True,
    markdown=True,
)

agent_team.print_response("Summarize analyst recommendations and share the latest news for NVDA", stream=True)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a new cell to your Notebook. Then copy the code above and paste it into the new cell. &lt;/p&gt;

&lt;p&gt;That's pretty much it! Go ahead and run the cell. It will take some time to finish running and once it's done you'll be able to see the output as follows (you'll need to scroll to the bottom):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihrt7cz3ns9jrhl2vtpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fihrt7cz3ns9jrhl2vtpv.png" alt="Financial Analysis done by AI Agent" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Output text looks really small because I had zoomed out in order to fit the entire output in a single screenshot.&lt;/p&gt;

&lt;p&gt;So we were able to build this Financial Analyst Agent in a very short amount of time. It's obvious the report is sort of basic and could be more detailed, but we can always improve our Agent to add more data from different sources by adding new Agents to the Team (or by building our own function Tools from scratch).&lt;/p&gt;

&lt;p&gt;You can &lt;strong&gt;&lt;a href="https://www.linkedin.com/in/farhans-profile/" rel="noopener noreferrer"&gt;Follow me on LinkedIn&lt;/a&gt;&lt;/strong&gt; to learn more about AI Agents!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>python</category>
      <category>openai</category>
    </item>
    <item>
      <title>Managing AI Tools for Function Calling with Toolhouse SDK</title>
      <dc:creator>Farhan Ahmad</dc:creator>
      <pubDate>Tue, 14 Jan 2025 20:13:46 +0000</pubDate>
      <link>https://forem.com/coding_farhan/managing-ai-tools-for-function-calling-with-toolhouse-sdk-2i6h</link>
      <guid>https://forem.com/coding_farhan/managing-ai-tools-for-function-calling-with-toolhouse-sdk-2i6h</guid>
      <description>&lt;p&gt;When building AI agents, one of the most powerful aspects is their ability to manage and execute tools (function calls). Tools can help an agent perform tasks like scraping data, summarizing content, or even solving complex workflows. But as your AI agent grows in size and capabilities, it becomes increasingly difficult to manage/maintain multiple tools.&lt;br&gt;
In this tutorial, we’ll focus on using the Toolhouse SDK to demonstrate how to use pre-built tools and how we can track every single tool call using the platform.&lt;/p&gt;

&lt;p&gt;For this example, we’ll build a very simple interface where a user can input a URL and a prompt, and an AI agent will use tools to scrape the webpage and process the data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Tool Management Matters in AI Agents
&lt;/h2&gt;

&lt;p&gt;AI agents are nothing without Tools. They're like arms and legs of the AI agent. Each Tool is a specialized skill or function that the AI relies on to complete a specific task. &lt;br&gt;
User-facing AI agents need to be flawless in their execution of different tasks. And writing AI tools from scratch to implement API integration or web scraping logic is like re-inventing the wheel that also requires maintenance over the long run by the dev team.&lt;/p&gt;

&lt;p&gt;These problems are taken care of by &lt;strong&gt;Toolhouse&lt;/strong&gt;. It helps you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose from a variety of specialized AI Tools for tasks such as web scraping, sending emails, taking screenshots, integrating APIs like the LinkedIn API for searching for profiles on LinkedIn, etc.&lt;/li&gt;
&lt;li&gt;Track you AI agent's tool calls on the &lt;strong&gt;Toolhouse&lt;/strong&gt; app.&lt;/li&gt;
&lt;li&gt;Use the Toolhouse SDK to implement powerful AI features in no time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These capabilities simplify your tool management and lets you focus on building smarter AI agents instead of worrying about building/maintaining Tools.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started with Toolhouse
&lt;/h2&gt;

&lt;p&gt;Alright so let's build an AI-powered web-scraper. Sounds fancy but it's just a single page app that lets you input a URL to scrape and an optional prompt that you want to execute along with the scraped data. &lt;br&gt;
Here's what you'll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Node.js (v16 or later).&lt;/li&gt;
&lt;li&gt;An &lt;a href="//openai.com"&gt;OpenAI API key&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;A &lt;a href="//toolhouse.ai"&gt;Toolhouse API key&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Step 1: Set Up Your React Project
&lt;/h2&gt;

&lt;p&gt;We’ll use React to create a simple frontend for managing tool calls. Make sure you have create-react-app installed which we'll use to initialize a new React application. If you don't have it installed, you can do so by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g create-react-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your favorite code editor and inside the terminal type the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app ai-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once it's done creating a new app, change into the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ai-scraper
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you expand the &lt;em&gt;ai-scraper&lt;/em&gt; folder, it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eiv2kx1nn68uu8iewco.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8eiv2kx1nn68uu8iewco.png" alt="AI Web Scraper project after initialization" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Let's now start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should automatically start a new app at &lt;em&gt;localhost:3000&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxq40k6p6stfn6lzjbsn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faxq40k6p6stfn6lzjbsn.png" alt="Image description" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Neat! Let's install all the essential libraries now.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Install Toolhouse and OpenAI SDKs
&lt;/h2&gt;

&lt;p&gt;These SDKs will let our app interact with the Toolhouse platform and OpenAI models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @toolhouseai/sdk openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Add the API keys
&lt;/h2&gt;

&lt;p&gt;Create a new &lt;strong&gt;.env&lt;/strong&gt; inside the project folder &lt;strong&gt;ai-scraper&lt;/strong&gt; and add the following API keys:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_TOOLHOUSE_API_KEY=your_toolhouse_api_key
REACT_APP_OPENAI_API_KEY=your_openai_api_key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find your OpenAI API key at &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;platform.openai.com/api-keys&lt;/a&gt;. In the &lt;strong&gt;.env&lt;/strong&gt; file replace "your_openai_api_key" with the actual OpenAI key.&lt;/p&gt;

&lt;p&gt;Let's now see how we can set-up our Toolhouse account for our AI web scraping app. In order to get your Toolhouse API key you'll first need to create an account at &lt;a href="https://toolhouse.ai" rel="noopener noreferrer"&gt;Toolhouse.ai&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotc0c6c9gc4bhf4ir9kh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotc0c6c9gc4bhf4ir9kh.png" alt="Sign up at Toolhouse.ai" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you've signed up, go to &lt;a href="https://app.toolhouse.ai/settings/api-keys" rel="noopener noreferrer"&gt;API Keys page&lt;/a&gt;. This page should look something like the following:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q0rev2jjg87owc4r4dt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q0rev2jjg87owc4r4dt.png" alt="Toolhouse API key" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clicking on the eye icon should reveal your API key. Copy this and paste it in your &lt;strong&gt;.env&lt;/strong&gt; file in the place of "your_toolhouse_api_key".&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 4: Creating and setting up your Bundle in Toolhouse
&lt;/h2&gt;

&lt;p&gt;This is how your Dashboard looks like:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fph43gyafglztgyk8fzdl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fph43gyafglztgyk8fzdl.png" alt="Toolhouse Dashboard" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the left menu click on "Bundles". This will take us to a new page where we can create a new Bundle. The purpose of Bundles is to organize our AI Tools into groups or packs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwavrc3trw25z1uwlfpg1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwavrc3trw25z1uwlfpg1.png" alt="Create a new Bundle in Toolhouse" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once created, you will then be taken to this page, where you can find different pre-made tools and add them to your Bundle:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcon5kc1nqknea2w65ux.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvcon5kc1nqknea2w65ux.png" alt="Successfully created a new Bundle in Toolhouse" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you scroll further down, you'll find a Tool named &lt;strong&gt;Tavily web search&lt;/strong&gt;. Enable this Tool and it will be added to your Bundle:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pmfws0n0ep71koo2ky7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pmfws0n0ep71koo2ky7.png" alt="Adding a web scraping tool to your Bundle in Toolhouse app" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5: Building the App.js Component
&lt;/h2&gt;

&lt;p&gt;Coming back to our app, we’ll now create a simple React component to showcase how tools are managed and executed. Go to your App.js file (or App.ts if you're using TypeScript) inside the &lt;strong&gt;src&lt;/strong&gt; folder and replace the entire code inside with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState } from "react";
import { Toolhouse } from "@toolhouseai/sdk";
import OpenAI from "openai";
import "./App.css";

const MODEL = "gpt-4o-mini";

function App() {
  const [url, setUrl] = useState("");
  const [prompt, setPrompt] = useState("");
  const [result, setResult] = useState("");
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState("");

  const handleSubmit = async (e) =&amp;gt; {
    e.preventDefault();
    setIsLoading(true);
    setError("");
    setResult("");

    try {
      const toolhouse = new Toolhouse({
        apiKey: process.env.REACT_APP_TOOLHOUSE_API_KEY,
        metadata: {
          id: "user_id",
          timezone: "0",
        },
      });

      const client = new OpenAI({
        apiKey: process.env.REACT_APP_OPENAI_API_KEY,
        dangerouslyAllowBrowser: true,
      });

      const messages = [
        {
          role: "user",
          content: `Get the contents of ${url} and ${prompt}`,
        },
      ];

      const tools = await toolhouse.getTools();

      const chatCompletion = await client.chat.completions.create({
        messages,
        model: MODEL,
        tools,
      });

      const openAiMessage = await toolhouse.runTools(chatCompletion);

      const newMessages = [...messages, ...openAiMessage];

      const chatCompleted = await client.chat.completions.create({
        messages: newMessages,
        model: MODEL,
        tools,
      });

      setResult(chatCompleted?.choices[0]?.message?.content);
    } catch (err) {
      console.error("Error occurred:", err);
      setError(
        `An error occurred while processing your request. ${
          err.message || JSON.stringify(err)
        }`
      );
    } finally {
      setIsLoading(false);
    }
  };

  return (
    &amp;lt;div className="container"&amp;gt;
      &amp;lt;h1&amp;gt;AI Scraper with Toolhouse&amp;lt;/h1&amp;gt;
      &amp;lt;form onSubmit={handleSubmit}&amp;gt;
        &amp;lt;div className="form-group"&amp;gt;
          &amp;lt;label htmlFor="url"&amp;gt;URL&amp;lt;/label&amp;gt;
          &amp;lt;input
            type="url"
            id="url"
            value={url}
            onChange={(e) =&amp;gt; setUrl(e.target.value)}
            placeholder="https://example.com"
            required
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="form-group"&amp;gt;
          &amp;lt;label htmlFor="prompt"&amp;gt;Prompt&amp;lt;/label&amp;gt;
          &amp;lt;textarea
            id="prompt"
            value={prompt}
            onChange={(e) =&amp;gt; setPrompt(e.target.value)}
            placeholder="Summarize the content..."
            required
          /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;button type="submit" disabled={isLoading}&amp;gt;
          {isLoading ? "Processing..." : "Scrape and Process"}
        &amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;

      {error &amp;amp;&amp;amp; &amp;lt;div className="error"&amp;gt;{error}&amp;lt;/div&amp;gt;}

      {result &amp;amp;&amp;amp; (
        &amp;lt;div className="result"&amp;gt;
          &amp;lt;h2&amp;gt;Result:&amp;lt;/h2&amp;gt;
          &amp;lt;pre&amp;gt;{result}&amp;lt;/pre&amp;gt;
        &amp;lt;/div&amp;gt;
      )}
    &amp;lt;/div&amp;gt;
  );
}

export default App;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Style our App
&lt;/h2&gt;

&lt;p&gt;To make the app look better, add some styles in &lt;strong&gt;App.css&lt;/strong&gt; file inside the src folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.container {
  max-width: 600px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}

h1 {
  text-align: center;
}

.form-group {
  margin-bottom: 15px;
}

label {
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

input, textarea {
  width: 100%;
  padding: 8px;
  margin-bottom: 10px;
  border: 1px solid #ccc;
  border-radius: 4px;
}

button {
  padding: 10px 15px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.error {
  color: red;
  margin-top: 10px;
}

.result {
  margin-top: 20px;
  padding: 10px;
  background-color: #f9f9f9;
  border: 1px solid #ddd;
  border-radius: 4px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Re-start the App
&lt;/h2&gt;

&lt;p&gt;Stop the React server if it's already running by typing &lt;strong&gt;Ctrl+C&lt;/strong&gt; inside the terminal. Run the following command to start the server again in order to load up the environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final App
&lt;/h2&gt;

&lt;p&gt;This is how your app should look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71yois6xeajb818ekvk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F71yois6xeajb818ekvk7.png" alt="AI Webscraper App using toolhouse" width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can enter any URL and then a prompt, then our AI agent will scrape the URL and summarize the webpage. Note that some websites like &lt;em&gt;microsoft.com&lt;/em&gt; don't allow scraping and hence our scraper will fail in those cases, so make sure the URLs you use allow scraping.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's me playing around with the scraper:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cmhoswovol3b3f784e8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cmhoswovol3b3f784e8.png" alt="AI Scraper giving information summarizing the URL of a technical tutorial" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc72h3oexnnh876cgwor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhc72h3oexnnh876cgwor.png" alt="Scraping OpenAI's landing page" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Monitoring Tool calls using the Execution Logger in Toolhouse
&lt;/h2&gt;

&lt;p&gt;You can also monitor every single Tool call made to the Tools hosted on Toolhouse. This can help you estimate the number of Tool calls and optimize your Tool calls to save time and money.&lt;br&gt;
Here's how the Execution Logs look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfvsry9dr4nhucp1e1aj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcfvsry9dr4nhucp1e1aj.png" alt="Image of Toolhouse Execution Logs" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see you'll find the exact time of each Tool call as well as the ouput of each Tool call in the Execution Logs.&lt;/p&gt;

&lt;p&gt;That's about it for this tutorial. If you want to learn more about building AI agents, feel free to follow me here or on &lt;a href="https://www.linkedin.com/in/farhans-profile/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>openai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Building AI-Powered Applications: Getting Started with Botpress Framework in React</title>
      <dc:creator>Farhan Ahmad</dc:creator>
      <pubDate>Sat, 11 Jan 2025 21:16:39 +0000</pubDate>
      <link>https://forem.com/coding_farhan/building-ai-powered-applications-getting-started-with-botpress-framework-in-react-3050</link>
      <guid>https://forem.com/coding_farhan/building-ai-powered-applications-getting-started-with-botpress-framework-in-react-3050</guid>
      <description>&lt;p&gt;Writing code for implementing LLM logic can be really tiring and this is what got me experimenting with different frameworks and tools to make my life easier. One such framework that I came across is &lt;strong&gt;Botpress&lt;/strong&gt;. It's an easy to use framework for building AI based apps quickly and it comes with a lot of flexibility as well. More importantly, it offers React components out of the box for you. And you can still customize the look and feel of the components as you wish.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Botpress though?
&lt;/h2&gt;

&lt;p&gt;Botpress is not just a framework, it's an all-in-one platform for building AI-powered apps. It greatly simplifies creating, deploying, and managing AI agents. So if you're looking for a complete package of scalable AI solutions, this is it.&lt;/p&gt;

&lt;p&gt;Some of the advanced things that you can do with Botpress:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visual Workflow Design&lt;/strong&gt;: Drag-and-drop interface for no-code bot creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code Flexibility&lt;/strong&gt;: Customizable tools and integrations for advanced logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-Channel Support&lt;/strong&gt;: Deploy bots on websites, WhatsApp, Slack, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Capabilities&lt;/strong&gt;: Includes NLU, knowledge integration, and personality customization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started with Botpress framework - The Webchat SDK
&lt;/h2&gt;

&lt;p&gt;To show you how you can use Botpress framework in your app, we're going to build a very basic AI chat application using Botpress' Webchat SDK which provides ready to use components. It offers a variety of different components that we'll need:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;The WebchatProvider&lt;/em&gt; - Needs to wrap all chat components and has to be initialized with a Botpress client. We can also customize the theme of the chat interfaces using this provider.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;FAB (Floating Action Button)&lt;/em&gt; - A fancy name for the small circle that upon clicking opens up the chat.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;WebChat&lt;/em&gt; - The main chat interface where you can see all messages.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Enough theory, let's get our hands dirty.&lt;/p&gt;

&lt;p&gt;We'll use &lt;em&gt;create-react-app&lt;/em&gt; to initialize a new React project. Open a folder in VS Code and in the integrated terminal write the following:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npx create-react-app botpress-chat&lt;br&gt;
or&lt;br&gt;
yarn create react-app botpress-chat&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will create a new project for you automatically. This is how your project structure will look like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssl8y35hl5mdkzxaiht5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssl8y35hl5mdkzxaiht5.png" alt="Project structure after running create-react-app" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool! Let's now run the server to make sure our project was initialized perfectly. Go inside the project directory:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd botpress-chat&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now run the server:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Voila, here's your app running on the default port, 3000:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hhm7a0yarp27tya9zpj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1hhm7a0yarp27tya9zpj.png" alt="App successfully running on localhost:3000" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Sometimes, you might get the following error upon running npm start:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6op313lqe5s6zwisern4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6op313lqe5s6zwisern4.png" alt="Common error while running npm start" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that case, you can overcome this by installing the latest ajv package:&lt;br&gt;
&lt;code&gt;npm install ajv@latest &lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up Botpress framework in React app
&lt;/h2&gt;

&lt;p&gt;We're now going to install the Botpress libraries, namely the Webchat SDK. These libraries will help us build the chat interface and interact with our chat bot.&lt;/p&gt;

&lt;p&gt;Type the following command in your terminal:&lt;br&gt;
&lt;code&gt;npm install @botpress/webchat @botpress/webchat-generator&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; At the time of this writing, Botpress' Webchat libraries are using react version 18, however latest version of create-react-app is using react version 19. Which means that you downgrade to version 18 for &lt;code&gt;react&lt;/code&gt; and &lt;code&gt;react-dom&lt;/code&gt; libraries. You can do this by running:&lt;br&gt;
&lt;code&gt;npm install react@18.2.0 react-dom@18.2.0&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once these libraries have been installed, we can start integrating Botpress into our app.&lt;br&gt;
Go to your App.js file (App.ts if you're using Typescript) inside the src folder and replace the code inside the file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Webchat, WebchatProvider, Fab, getClient } from "@botpress/webchat";
import { buildTheme } from "@botpress/webchat-generator";
import { useState } from "react";
const { theme, style } = buildTheme({
  themeName: "prism",
  themeColor: "#634433",
});
//Add your Client ID here ⬇️
const clientId = "YOUR_CLIENT_ID";
export default function App() {
  const client = getClient({ clientId });
  const [isWebchatOpen, setIsWebchatOpen] = useState(false);
  const toggleWebchat = () =&amp;gt; {
    setIsWebchatOpen((prevState) =&amp;gt; !prevState);
  };
  return (
    &amp;lt;div style={{ width: "100vw", height: "100vh" }}&amp;gt;
      &amp;lt;style&amp;gt;{style}&amp;lt;/style&amp;gt;
      &amp;lt;WebchatProvider
        theme={theme}
        client={client}
      &amp;gt;
        &amp;lt;Fab onClick={toggleWebchat} /&amp;gt;
        &amp;lt;div
          style={{
            display: isWebchatOpen ? "block" : "none",
          }}
        &amp;gt;
          &amp;lt;Webchat /&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/WebchatProvider&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the line no. 9 in this file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const clientId = "YOUR_CLIENT_ID";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constant "&lt;em&gt;clientId&lt;/em&gt;" has been assigned a dummy placeholder value. This is because we'll need to get the client id of the bot that we want to use in our app from the Botpress website.&lt;br&gt;
First, head over to Botpress.com and sign-up for free. Once you've created an account and filled some basic info you should land on the Dashboard (&lt;em&gt;app.botpress.cloud&lt;/em&gt;) which should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxlnl57j7cmudzce8cwe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmxlnl57j7cmudzce8cwe.png" alt="Botpress Dashboard" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, let's go ahead and create a new bot! Click on the button "Create Bot":&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx5biixfod2lgvv2fli53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx5biixfod2lgvv2fli53.png" alt="click on Create Bot button" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should see this next:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7ee79oj9nrkre0bkdyx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft7ee79oj9nrkre0bkdyx.png" alt="Give the bot a name" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And once you're done you'll see this:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzif9zktyot615cs55p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldzif9zktyot615cs55p.png" alt="Chatbot Created message" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, our bot hasn't been published yet. We will need to publish it from the Botpress studio. Go ahead and click the "Open in Studio" button.&lt;/p&gt;

&lt;p&gt;This will take you to a different page called the Botpress studio (notice that the URL has changed from &lt;em&gt;app.botpress.cloud&lt;/em&gt; to &lt;em&gt;studio.botpress.cloud&lt;/em&gt;). Over here we'll need to set-up one more thing before our bot is ready to use.&lt;br&gt;
We have to add the OpenAI integration so that we can use OpenAI's LLM through our bot. To do this follow the below steps.&lt;br&gt;
First, click on "installed integrations" on the left panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrlw6bbwgokokaak2qsc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcrlw6bbwgokokaak2qsc.png" alt="Click on " width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
This will open the Botpress hub explorer. Inside the search box type "openai" and click on the first result that appears.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4ky4e9epye5gnf5lzyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd4ky4e9epye5gnf5lzyt.png" alt="Click on the " width="800" height="452"&gt;&lt;/a&gt;&lt;br&gt;
After clicking you'll be taken to the OpenAI integration page. Click on the button "install integration".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsyr0hsct1gbekzkbewq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsyr0hsct1gbekzkbewq.png" alt="Install the OpenAI integration for Botpress" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great, the integration will get installed. You can close the popups. Now on the top right, click on the "Publish" button as the final step.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bqqna53g1ex573ht6zl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0bqqna53g1ex573ht6zl.png" alt="Publish the post" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it! Our new chatbot has been created and published. &lt;br&gt;
You can close the Botpress studio window and go back to your workspace (&lt;em&gt;app.botpress.cloud&lt;/em&gt;). Now in the workspace page on the left hand side, you will notice there is an option that says "Webchat" as shown below. Click on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mtvdrcf5xlgrvtqyxfp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3mtvdrcf5xlgrvtqyxfp.png" alt="Click on Webchat" width="800" height="454"&gt;&lt;/a&gt;&lt;br&gt;
This will open a bunch of customization options for our bot in the "&lt;em&gt;general&lt;/em&gt;" tab. You can give it a name, description, picture, color, etc. Once you're done customizing make sure to scroll down and click on "save" button to save your changes.&lt;/p&gt;

&lt;p&gt;Now let's get the client id of the bot we've just created. We will need to go to the "advanced settings" tab and copy the client id of the bot from there:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhikby8eycs8j9mzzlvj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhikby8eycs8j9mzzlvj2.png" alt="Get Botpress Client Id" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! Now go back to your codebase and find the below line (should be on line number 9) and replace the placeholder value "YOUR_CLIENT_ID" with your client id that you've just copied:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const clientId = "YOUR_CLIENT_ID";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool, now in your terminal type the following command to start the server:&lt;br&gt;
&lt;code&gt;npm start&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
Go to localhost:3000 and you should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1n7p6djmzsu8yyy6lcp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy1n7p6djmzsu8yyy6lcp.png" alt="FAB (floating action button) image" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the FAB (Floating Action Button) component on top left of the page and it will open up a chat interface. You can then try talking to the bot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwzan3yvwltk08sinfur.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwzan3yvwltk08sinfur.png" alt="Working version of Botpress' Webchat UI" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty cool! You can explore the official documentation on Botpress' website to further customize these chat UI components over &lt;a href="https://botpress.com/docs/react-js" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That's it for this tutorial, let me know if you'd like to learn more about Botpress!&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Set Up CopilotKit in Your React App: A Step-by-Step Guide</title>
      <dc:creator>Farhan Ahmad</dc:creator>
      <pubDate>Tue, 31 Dec 2024 13:06:24 +0000</pubDate>
      <link>https://forem.com/coding_farhan/how-to-set-up-copilotkit-in-your-react-app-a-step-by-step-guide-1cca</link>
      <guid>https://forem.com/coding_farhan/how-to-set-up-copilotkit-in-your-react-app-a-step-by-step-guide-1cca</guid>
      <description>&lt;p&gt;If you've ever built an AI based application, you may have noticed that developing an AI heavy feature for your app that uses the power of LLMs through APIs (like that of OpenAI, Anthropic etc) can be super time consuming and frustrating. It's not just about coding the API integration, it's the overall time spent writing the business logic thats on top of it that takes so much effort. &lt;/p&gt;

&lt;p&gt;This is where CopilotKit comes in. It allows you to build scalable LLM-powered applications with little to no time. It also offers endless ways of building cool, unique features for your app.&lt;/p&gt;

&lt;p&gt;In this article we'll cover how to get started the easy way with an example repo provided by CopilotKit and then later we'll also cover how to integrate CopilotKit into a new/existing React app from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's CopilotKit and why use it?
&lt;/h2&gt;

&lt;p&gt;CopilotKit is a framework that helps you integrate AI assistants and agents in your apps easily. If you're using React it especially helps to have hooks and functions for building complex components that interact with LLM APIs. &lt;br&gt;
By using CopilotKit you no longer have to write LLM API integration logic and it simplifies implementing business logic on top of it.&lt;/p&gt;

&lt;p&gt;Here are some features you can build using CopilotKit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI chatbots&lt;/li&gt;
&lt;li&gt;AI Agents&lt;/li&gt;
&lt;li&gt;AI Assistants&lt;/li&gt;
&lt;li&gt;Dynamically generated Components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...and much more!&lt;/p&gt;

&lt;p&gt;If you're not familiar with AI agents, think of them as autonomous digital workers that can perform tasks proactively. They don't require user inputs to execute a task as they make decisions independently based on their own understanding. AI assistants on the other hand are comparatively less powerful as they only perform specific actions whenever a user instructs them, like setting reminders, booking meetings, etc.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started with an Example Repo
&lt;/h2&gt;

&lt;p&gt;Lets go ahead and set up a simple React application with CopilotKit. The fastest way to see CopilotKit in action is by using one of the official example repositories.&lt;br&gt;
Head over to their GitHub homepage by clicking &lt;a href="https://github.com/CopilotKit" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You'll notice they have multiple example repos for you to explore their powerful framework.&lt;/p&gt;

&lt;p&gt;At the time of writing, they have the following example repos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/CopilotKit/demo-presentation" rel="noopener noreferrer"&gt;demo-presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CopilotKit/example-textarea" rel="noopener noreferrer"&gt;example-textarea&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CopilotKit/example-todos-app" rel="noopener noreferrer"&gt;example-todos-app&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CopilotKit/demo-spreadsheet" rel="noopener noreferrer"&gt;demo-spreadsheet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/CopilotKit/demo-banking" rel="noopener noreferrer"&gt;demo-banking&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each repo demonstrates the unique abilities of CopilotKit framework.&lt;/p&gt;

&lt;p&gt;Let's see how we can make these repos work locally with an example. We'll be cloning the repo named &lt;strong&gt;example-todos-app&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In your VS Code, open the terminal and type the following command to clone the &lt;strong&gt;example-todos-app&lt;/strong&gt; repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/CopilotKit/example-todos-app.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, once you have cloned the repo, go to the project directory by doing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd example-todos-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have the codebase locally we'll need to add an important environment variable to get the app fully set-up. That environment variable is &lt;em&gt;NEXT_PUBLIC_COPILOT_CLOUD_PUBLIC_API_KEY&lt;/em&gt; which requires us to create a new account at &lt;a href="//cloud.copilotkit.ai"&gt;&lt;em&gt;cloud.copilotkit.ai&lt;/em&gt;&lt;/a&gt; and then get the API key. &lt;/p&gt;

&lt;p&gt;Copilotkit offers a free trial which is more than enough to play around with it. Once you have signed up you should see this screen:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujdje7wd1r1s61hfrjab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujdje7wd1r1s61hfrjab.png" alt="Copilotkit Onboarding page" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After filling the form you'll be taken to the project dashboard page:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbtba80hd2919myhs614.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbtba80hd2919myhs614.png" alt="Copilotkit Project Dashboard" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can find important stuff like your Copilot Cloud API key, number of copilot cloud requests made, etc. Note that it says you can make up to 50 requests without providing an OpenAI API key, which is perfect for those who don't have an active OpenAI subscription!&lt;/p&gt;

&lt;p&gt;Ok moving on. Copy your Copilot Cloud API key and then go back to your VS Code and create a new &lt;strong&gt;.env&lt;/strong&gt; file in your project folder (inside example-todos-app) and add the following line inside the &lt;strong&gt;.env&lt;/strong&gt; file:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
NEXT_PUBLIC_COPILOT_CLOUD_PUBLIC_API_KEY="paste_your_copilot_cloud_api_key"&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Perfect, let's install all the required dependencies now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
or
yarn install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cool! Once the dependencies are done installing, lets go ahead and start the server to get our app running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
or
yarn dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's about it! You can see the app working in your browser at the URL &lt;strong&gt;localhost:3000&lt;/strong&gt;.&lt;br&gt;
It'll look something like the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi83zeb0jnqubxkph30q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbi83zeb0jnqubxkph30q.png" alt="Working Example CopilotKit Example Repo" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll notice on the bottom right there's a chat icon. If you click on that it'll open the chat interface. Here, you can command the AI to modify your To Do list as you want.&lt;/p&gt;

&lt;p&gt;Try sending these messages one by one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Delete all to do list items.&lt;/li&gt;
&lt;li&gt;Come up with 3 random business ideas and add them to the list.&lt;/li&gt;
&lt;li&gt;Mark all ideas as completed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Cool stuff huh? You can find more example repos on their GitHub homepage &lt;a href="https://github.com/CopilotKit" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Integrating CopilotKit into your React app
&lt;/h2&gt;

&lt;p&gt;For those who want to integrate CopilotKit into their existing or new React app, here’s how to set it up from scratch. Let's build a simple chat app that lets you talk to AI like chat gpt. Nothing big, but enough to show you the power of CopilotKit.&lt;/p&gt;

&lt;p&gt;I'll be using create-react-app for initializing a new project.&lt;br&gt;
So let's go ahead and make sure we actually have create-react-app installed globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g create-react-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now go ahead and open a new window in VS Code, open a folder and go to the VS Code terminal and type this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app chat-app
or
yarn create react-app chat-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should automatically create a new react project along with all the started files.&lt;br&gt;
Before we move forward make sure you are in the project directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd chat-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voila, we can now run the server to ensure our project is set up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that in some rare cases, you may get the following error when running npm start:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw2xlvwvi5gqeu45ljvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsw2xlvwvi5gqeu45ljvu.png" alt="Cannot find module ajv error" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix this, go ahead and install the missing dependency called "ajv" as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install ajv@latest 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now try running npm start again and it should work normally. It will start the server at the default port 3000. Go to &lt;em&gt;localhost:3000&lt;/em&gt; and it should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7khfo87c1otpzffnohx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7khfo87c1otpzffnohx.png" alt="Successfully running create-react-app" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cool, so let's go ahead and start modifying our react app. We will try implementing a "talk to AI" feature. CopilotKit provides a component to do this out of the box, so we just have to import and use it. Nothing too fancy, but it goes a long way in showing the power of CopilotKit.&lt;br&gt;
But first we need the CopilotKit framework installed and set up in order to use it.&lt;/p&gt;
&lt;h2&gt;
  
  
  Adding CopilotKit to your React app
&lt;/h2&gt;

&lt;p&gt;The first step is to install the CopilotKit libraries in our app. There are essentially 2 libraries that we're going to need. The first is copilotkit/react-ui which provides ready to use AI powered components right out of the box.&lt;br&gt;
The second library is copilotkit/react-core that contains the main logic for interacting with LLM APIs.&lt;/p&gt;

&lt;p&gt;Go to the terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @copilotkit/react-ui @copilotkit/react-core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;[To view CopilotKit's official Quickstart guide, go &lt;a href="https://docs.copilotkit.ai/quickstart" rel="noopener noreferrer"&gt;here&lt;/a&gt;]&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up CopilotKit
&lt;/h2&gt;

&lt;p&gt;Great, let's go ahead and modify the code so that we can use the capabilities of CopilotKit in our app.&lt;br&gt;
In order to use all features of the CopilotKit framework we need to add the &lt;strong&gt;CopilotKit Provider&lt;/strong&gt; to the app. This provider should wrap around all the components of your app, which is why we'll need to add it to the Parent component or at the top of the component tree. This parent component may differ depending on your app structure. For instance, if your app was initialised using create-react-app (like in our case) then the parent component is the &lt;strong&gt;index.js&lt;/strong&gt; component. On the other hand if you're using _Next.js _then you need to add the CopilotKit provider inside the &lt;strong&gt;layout.tsx&lt;/strong&gt; component.&lt;/p&gt;

&lt;p&gt;As we're using create-react-app for this example, we'll add the CopilotKit provider inside the &lt;strong&gt;&lt;em&gt;src/index.js&lt;/em&gt;&lt;/strong&gt; file.&lt;br&gt;
This is how your &lt;strong&gt;index.js&lt;/strong&gt; file should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { CopilotKit } from "@copilotkit/react-core";
import "@copilotkit/react-ui/styles.css";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;CopilotKit publicApiKey={process.env.REACT_APP_COPILOTKIT_API_KEY}&amp;gt;
      &amp;lt;App /&amp;gt;
    &amp;lt;/CopilotKit&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're done setting up the Copilotkit provider. All we need now is to host the CopilotKit runtime, and we can start using CopilotKit.&lt;br&gt;
There are 2 ways to use CopilotKit: Either by self-hosting the runtime or by using CopilotKit cloud.&lt;br&gt;
To keep this guide simple and straight-forward we'll use CopilotKit cloud to build the "talk to AI" page.&lt;/p&gt;

&lt;p&gt;We've already covered above how you can register for CopilotKit cloud and get the API key for your app. Its fairly easy and you can do it at &lt;em&gt;&lt;strong&gt;&lt;a href="//cloud.copilotkit.ai"&gt;cloud.copilotkit.ai&lt;/a&gt;&lt;/strong&gt;&lt;/em&gt;.&lt;br&gt;
Once you're done signing up, you'll find your API keys on the Dashboard which should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbtba80hd2919myhs614.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqbtba80hd2919myhs614.png" alt="Copilotkit Project Dashboard" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the Copilot Cloud Public API Key as we'll need to add it to our environment variable. Create a new file inside the &lt;em&gt;&lt;strong&gt;chat-app&lt;/strong&gt;&lt;/em&gt; folder called &lt;strong&gt;.env&lt;/strong&gt; and add the following value:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
REACT_APP_COPILOTKIT_API_KEY="paste_your_copilot_cloud_api_key"&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
And.. we're done setting up CopilotKit! All we need to do now is to import the CopilotKit functions/hooks inside any component and we can start building out LLM powered features supported by CopilotKit. Let's do just that.&lt;/p&gt;

&lt;p&gt;Since we're building a talk to AI feature we're going to use a React component called &lt;em&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/em&gt;. This is provided by CopilotKit and we just have to import it to start using it.&lt;/p&gt;

&lt;p&gt;Go to your &lt;strong&gt;src/App.js&lt;/strong&gt; file inside the src folder and make sure it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "./App.css";
import { CopilotChat } from "@copilotkit/react-ui";
function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;CopilotChat /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, we're done! Now let's run the command to start our server like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your server should start automatically at &lt;em&gt;&lt;strong&gt;localhost:3000&lt;/strong&gt;&lt;/em&gt;. Here is how it should look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxprny5wocokqt6eh4oly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxprny5wocokqt6eh4oly.png" alt="Talk to AI feature" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can now start talking to AI like you normally talk to chat GPT!&lt;/p&gt;

&lt;p&gt;As you saw, it was fairly simple to set everything up, because of the ready-made UI components provided by CopilotKit library and because the API calls to the OpenAI are being taken care of by CopilotKit as well. &lt;br&gt;
You can build LLM based applications quickly without re-writing the same API call logic and creating the UI components that update dynamically based on LLM responses.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
