Mission Chai

🔥 Create a Stateful Chat AI in 10 minutes 🎉

We’ve heard your feedback and have been working hard on allowing you to make your own stateful chais! Now your chat AI can store information and keep variables persistent within the same conversation. No more forgetful chais! 🎉

Getting set up (5 minutes):

  1. Head over to the Chai Developer Platform

  2. Sign in with Google

  3. Scroll to the bottom to see your “Developer Unique ID” (referred to as developer_uid in this tutorial) and your “Developer Keys”. These will come in handy later!

  4. Install the iOS or Android app by clicking “get chai” anywhere on https://chai.ml

Installation

Installing the chai_py package.

pip install --upgrade chaipy

Creating your quiz Chat AI

First, I’m making a file named bot.py, in a directory named bot. ```python

bot.py

from chai_py import ChaiBot, Update

class Bot(ChaiBot): def setup(self): self.logger.info("Setting up…") self.messages_count = 0 self.name = None

async def on_message(self, update: Update) -> str:
    self.messages_count += 1
    if self.messages_count == 1:
        return "Hey! Nice to meet you :) What’s your name?"
    if self.messages_count == 2:
      self.name = update.latest_message.text  
        return "Nice to meet you, {self.name}!"
    else:
        return "😁"

For more detailed information on the above, check out [https://chai.ml/docs](https://chai.ml/docs)

# Let’s make our bot more interesting

First, we’re going to write out our questions and answers in `_get_mapping`. To parse these into a list of tuples, we run `_get_questions`, splitting it up by line and then by commas. Finally, we shuffle our prompts.

```python
class Bot(ChaiBot):
    def setup(self):
        self.logger.info("Setting up...")
        self.correct = []
        self.incorrect = []
        self.questions = self._get_questions()
        self.count = 0

    async def on_message(self, update: Update) -> str:
        return

    def _get_questions(self):
        mapping = self._get_mapping()
        questions = {}
        for line in mapping.split('\n'):
            question, answer = line.split(',')
            questions[question.lower().strip()] = answer.lower().strip()
        questions = list(questions.items())
        random.shuffle(questions)
        return questions

    def _get_mapping(self):
        mapping = """Which is the smallest planet within our solar system?, Mercury
        Which is the second smallest planet within our solar system?, Mars
        The moon called Titan orbits which planet?, Saturn
        Which is the brightest planet in the night sky?, Venus
        Which planet is larger - Neptune or Saturn?, Saturn
        Uranus has only been visited by what spacecraft?, Voyager 2
        Which is the only planet not named after Greek gods or goddesses?, Earth
        There have been more missions to this planet versus any other planet., Mars
        Phobos and Deimos are the Moons of which planet?, Mars
        Which planet is closest in size to Earth?, Venus
        Olympus Mons is a large volcanic mountain on which planet?, Mars
        Ganymede is a moon of which planet?, Jupiter
        Which planet has supersonic winds?, Neptune
        Which planet has the fastest rotation?, Jupiter
        Which is the oldest planet in our solar system?, Jupiter
        Which is the densest planet in our solar system?, Earth
        Which planet is known as the Morning Star?, Venus
        Which planet is known as the Evening Star?, Venus
        Which planet has the most volcanoes?, Venus
        Which planet spins backward relative to the others?, Venus
        In what year did Pluto become reclassified as a dwarf planet?, 2006
        Which planet rotates on its side?, Uranus
        What color is Mars’ sunset?, Blue
        What is the name of the spacecraft that carried the first astronauts to the moon?, Apollo 11
        How many stars make up the Big Dipper?, 7
        Which constellation represents a hunter and weapons?, Orion
        """
        return mapping

Next, we will add our on_message function. This is how we will interact with the user.

    async def on_message(self, update: Update) -> str:
        msg = ''
        if self.count > 0:
            question, capitol = self.questions[user_count - 1]
            answer = update.latest_message.text.lower().strip().replace('.','')

            if capitol in answer:
                self.correct.append(question)
                msg = '🎉 🎉 \nCorrect: '
            else:
                self.incorrect.append(question)
                msg = 'Incorrect: '

            msg += 'the answer to {} is {}.'.format(question, capitol)
            num_correct = len(self.correct)
            num_incorrect = len(self.incorrect)
            msg += '\nYour score is {}/{}.'.format(num_correct, num_correct + num_incorrect)

        question, answer = self.questions[self.count]
        self.count += 1
        if msg:
            msg = msg + "\n" + question
        else:
            msg = question
        return msg

You can see that here we are taking their answer from update.latest_message.text and comparing it with our questions and answers.

Next, we can add a bit of feedback! Lets give our user some encouragement when they answer correctly or if they answer all the questions in the quiz.

    async def on_message(self, update: Update) -> str:
        user_count = self.count

        if user_count == len(self.questions):
            return self._get_conversation_end_response()

        msg = ''
        if self.count > 0:
            question, capitol = self.questions[user_count - 1]
            answer = update.latest_message.text.lower().strip().replace('.','')

            if capitol in answer:
                self.correct.append(question)
                msg = '🎉 🎉 \nCorrect: '
            else:
                self.incorrect.append(question)
                msg = 'Incorrect: '

            msg += 'the answer to {} is {}.'.format(question, capitol)
            num_correct = len(self.correct)
            num_incorrect = len(self.incorrect)
            msg += '\nYour score is {}/{}.'.format(num_correct, num_correct + num_incorrect)

            # GET BANTER
            banter = ''
            if capitol in answer:
                if num_correct == 1:
                    banter = 'Well Done!!'
                if num_correct == 2:
                    banter = 'Well done, you are now in the top 5% of users!!'
                if num_correct == 3:
                    banter = 'Well done, you are now in the top 1% of users!! You genius.'
            else:
                if num_incorrect == 2:
                    banter = 'You wally!'
                if num_incorrect == 3:
                    banter = 'Your IQ is very low!'
                if num_incorrect == 4:
                    banter = 'You really should just give up!'
                if num_incorrect > 4:
                    banter = '🤪'

            msg = banter + '\n' + msg


        question, answer = self.questions[self.count]
        self.count += 1
        if msg:
            msg = msg + "\n" + question
        else:
            msg = question
        return msg

    def _get_conversation_end_response(self):
        num_correct = len(self.correct)
        num_incorrect = len(self.incorrect)
        total = num_correct + num_incorrect
        msg = 'Well done for completing the quiz. ' \
              'You scored {}/{}'.format(num_correct, total)
        return msg

Chatting with the bot

Let’s test this out!

from chai_py import TRoom

t_room = TRoom([Bot()])
t_room.start()

Packaging

Now, we’re going to package the class we just made into a zip so that it’s ready to upload.

This is where your developer_uid and developer_key will come in handy 🔧 from chai_py import package, Metadata

from chai_py import (Metadata, package, share_bot, upload_and_deploy, wait_for_deployment)
from chai_py.auth import set_auth

from bot import Bot

DEVELOPER_UID = “get_this_from_chai_developer_platform”
DEVELOPER_KEY = “and_get_this_from_chai_developer_platform”
set_auth(uid=DEVELOPER_UID, key=DEVELOPER_KEY)


PIC_URL = “https://upload.wikimedia.org/wikipedia/commons/thumb/9/91/Bruce_McCandless_II_during_EVA_in_1984.jpg/440px-Bruce_McCandless_II_during_EVA_in_1984.jpg”


package(
    Metadata(
        name=“Space Quiz”,
        image_url=PIC_URL,
        color=“f1a2b3”,
        description=“🚀🚀🚀”,
        input_class=Bot,
    )
)
uid = upload_and_deploy("_package.zip")
wait_for_deployment(uid)
share_bot(uid)

You’ll see some pretty spinners and colourful logs, letting you know your upload was a success!

bot_url will look something like this: chai://chai.ml/_bot_really-long-code-8910

This is a deep link, and it’ll take you to your bot’s page in our mobile app.

Thanks for reading, have fun quizzing!


5 months ago

Christie-Carol Beauchamp