I need help with DB

Hello! Currently, I am in the process of developing an artificial intelligence bot, and one of the crucial aspects I’m working on is implementing a robust memory system. Specifically, my objective is to create a unique key for each user based on their ID and subsequently append their messages to this designated key. Unfortunately, I have encountered some errors during this process. If anyone has the expertise and can offer assistance, I would greatly appreciate it. Your input and guidance would be invaluable in overcoming these obstacles and ensuring the successful implementation of the memory system.

Code Snippet:

try:
  db[f"{uid}"]["messages"].append(
      {"role": role, "content": content}
  )
except Exception as e:
  db[f"{uid}"]["messages"] = {"role": role, "content": content}

Error:

KeyError: '<uid>'
1 Like

That snippet isn’t exactly enough. Can you send the link to your Repl? uid seems to be "<uid>", so we’ll need to see where you defined it. By the way, there’s no need for the f string.

1 Like

I did this because, I don’t believe you can set an int as a key raw.

The variable <uid> represents the unique identifier, which specifically corresponds to the user’s discord ID.

You can.

The variable isn’t called <uid>. The variable is called uid. The variable’s value is "<uid>". May I have the link to your Repl, or more code?

class Conversation:
    def __init__(self, max_memory=500):
        self.max_memory = max_memory

    def add_message(self, uid: int, role: str, content: str):
        if len(db[uid]["messages"]) >= self.max_memory:
            db[uid]["messages"].messages.pop(0)  # Remove the oldest message
        try:
          db[uid]["messages"].append(
            {"role": role, "content": content}
          )
        except Exception as e:
          db[uid]["messages"] = {"role": role, "content": content}

    def get_messages(self, uid: int):
        return db[uid]["messages"]
1 Like

Okay, where is Conversation.add_message called?

def ask(self, uid: int, prompt: str):
        openai.api_key = env["key"]
        openai.api_base = env["url"]
        self.add_message(uid, "user", prompt)
      
        response = openai.ChatCompletion.create(
          model="gpt-4-0613", 
          
          messages=[
            {"role": "assistant", "content": _contents["main_2"]},
            {"role": "user", "content": prompt},
            *self.get_messages(uid)
          ]
        )
        print(self.get_messages(uid))
        message = response.choices[0].message["content"]
        return message
1 Like

…and where is ask called?

@_bot.event
async def on_message(ctx):
    if _bot.user.mentioned_in(ctx):
        async with ctx.channel.typing():
            await asyncio.sleep(random.randint(5, 10))
        await ctx.reply(
          conversation.ask(ctx.author.id, ctx.content)
        )
    else:
        return

Just a question: is this a discord bot paired with OpenAI and ReplitDB?

1 Like

It’s a temporary choice for now yes, I’m planning to migrate to a better DB in the future once the bot is big enough.

I don’t know why the uid is showing up as <uid>, but where are you setting it? maybe try setting a default one in your except Exception

db[uid] = db.get(uid, {"messages": {"role": role, "content": content}})

Oh, I just put it as <uid> I didn’t show the ID.

ohh lol. well does the code snippet work?

I just did this:

def add_message(self, uid: int, role: str, content: str):
      try:
        if len(db[uid]["messages"]) >= self.max_memory:
            db[uid]["messages"].messages.pop(0)  # Remove the oldest message
        db[uid]["messages"].append(
          {"role": role, "content": content}
        )
      except:
        db[uid] = {"messages": {"role": role, "content": content}}

but now im getting:

Traceback (most recent call last):
  File "/home/runner/AI/.pythonlibs/lib/python3.10/site-packages/discord/client.py", line 441, in _run_event
    await coro(*args, **kwargs)
  File "main.py", line 84, in on_message
    conversation.ask(ctx.author.id, ctx.content)
  File "main.py", line 54, in ask
    *self.get_messages(uid)
  File "main.py", line 41, in get_messages
    return db[uid]["messages"]
  File "/home/runner/AI/.pythonlibs/lib/python3.10/site-packages/replit/database/database.py", line 464, in __getitem__
    raw_val = self.get_raw(key)
  File "/home/runner/AI/.pythonlibs/lib/python3.10/site-packages/replit/database/database.py", line 500, in get_raw
    r = self.sess.get(self.db_url + "/" + urllib.parse.quote(key))
  File "/nix/store/xf54733x4chbawkh1qvy9i1i4mlscy1c-python3-3.10.11/lib/python3.10/urllib/parse.py", line 869, in quote
    return quote_from_bytes(string, safe)
  File "/nix/store/xf54733x4chbawkh1qvy9i1i4mlscy1c-python3-3.10.11/lib/python3.10/urllib/parse.py", line 894, in quote_from_bytes
    raise TypeError("quote_from_bytes() expected bytes")
TypeError: quote_from_bytes() expected bytes

I fixed it on my own, thanks though.

1 Like

please provide an explanation to how you did, so that other people who have the same problem know the solution.

2 Likes

I lied, I didn’t solve it let me try yours.

Replit’s database keys must only be strings (or bytes I think).
So either convert your uid to a string when interacting with the database, or have all uids be strings instead of ints.

If your database key is not a string, it will give a very convoluted error message that’s hard to understand (which needs to be fixed).

1 Like