The Upstreet Agents SDK is now in public beta 🎉 Get started →

Stateful Agent

This section describes how to build an Agent capable of maintaining its own state.

In this guide, we build a simple guessing game which can maintain its own state, and uses NPM libraries to enhance the game's experience.

We define a Stateful Agent as an Agent which can take maintain its own memory and event lifecycle.

The source code for this example is available on GitHub.

Video Tutorial

You can follow along this example by watching the video below:

Guide

Step 1: Setup usdk

Follow Setup the SDK to set up NodeJS and usdk.

Make sure you are logged in.

Step 2: Initialize your agent

Create a new agent:

usdk create <your-agent-directory> -y

This will directly scaffold an agent for you in <your-agent-directory>. Learn more

Your agent directory now contains the Node application and git repository for your agent, should you choose to use git.

The -y flag means to skip the Agent Interview process, which we don't need here. You can also omit the agent directory. In that case, a directory will be created for you.

Step 3: Start the agentic developer environment

Start a chat with your agent in the terminal:

cd <your-agent-directory>
usdk chat

To edit your agent, open agent.tsx in any IDE or text editor.

Hot reloading is supported by default, so when you save your code the agent will automatically reload so you can test out your changes immediately in the chat terminal.

Step 4: Add the Guessing Game logic

Our guessing game will work like this:

The Agent will choose a random animal, and then give slight hints to the user until the user guesses the word.

We can use unique-names-generator, an NPM library, to get the random animal name generation logic.

Install this library to your agent:

cd <your-agent-directory>
npm install unique-names-generator

Note: You can also install any library from npm.

Edit your agent.tsx by adding the following code stub:

agent.tsx
import React from "react";
import { uniqueNamesGenerator, animals } from 'unique-names-generator'
const generateRandomName = () =>
  uniqueNamesGenerator({ 

    dictionaries: [animals], 
    separator: ' '
  }) 
 
const GuessingGame = () => {

  // Guessing game logic goes here
  return <></>
}
 
export default function MyAgent() {
  return (
    <Agent>

    </Agent>
  )
}

Next, let's write up our guessing game logic! To maintain state, we'll use useState in React - for the sake of simplicity.

agent.tsx
import React from "react";
import { Agent, Prompt, Action } from "react-agents"; 
import { useState } from "react"; 
import { uniqueNamesGenerator, animals } from "unique-names-generator";
import { z } from "zod"; 
 
const generateRandomName = () => uniqueNamesGenerator({
  dictionaries: [animals],
  separator: ' ',
}); // big red donkey
 
const GuessingGame = () => {
  const [secretWord, setSecretWord] = useState(generateRandomName); 
 
  return (

    <>

      <Prompt>

        Play a guessing game with the user.

        The secret word that the user is must guess is {secretWord}.

        You can give them very subtle hints about the phrase, e.g. "this animal really likes treats".

        You can also answer general questions if they don't give too much away.

        However, be cryptic. Don't make the game so easy.

        When the user guesses the secret word or gives up, call the "guessingGameDone" action with an apppropriate message to reset the secret word.

      </Prompt>
      <Action
        name="guessingGameDone"
        description="The user has guessed the secret word"
        schema={z.object({ 
          congratulationsMessage: z.string(), 
        })} 
        examples={[ 
          { 
            congratulationsMessage: 'Whoa, you guessed it!', 
          }, 
        ]} 
        handler={async (e) => { 
          const { agent, message } = e.data; 
          const { args } = message; 
          const { congratulationsMessage } = args; 
          agent.say(congratulationsMessage); 
          setSecretWord(generateRandomName); 
        }} 
      />
    </>
  );
};

Step 4: Import the GuessingGame component in our agent.

agent.tsx
 
// ... all the other code
 
export default function MyAgent() {
  return (
    <Agent>

      <GuessingGame />
    </Agent>
  )
}

Step 5: (optional) Test the Guessing Game Agent

Run usdk chat to test the Agent in your CLI.

You can start the game by asking:

I want to play!

How long does it take you to guess your first animal? Join our Discord community and tell us; we'd love to know!

Further Challenges

  • "20 questions": Put a limit on the number of questions, and have the AI answer only YES or NO. If the user makes a guess, the game is considered done!

On this page

Facing an issue? Add a ticket.