chatrpg-cs / chatrpg-be Goto Github PK
View Code? Open in Web Editor NEWRPG Discord bot powered by GPT models
License: GNU General Public License v3.0
RPG Discord bot powered by GPT models
License: GNU General Public License v3.0
Implement both general and specific policies for API call retries when something goes wrong. Specify the number of retries for each one of these cases.
Sometimes the API fails to generate outputs (HTTP 400, 500, 502 and 503 are relatively common), as well as empty responses (which has its own internal exception thrown). We should have a retry mechanic for those cases, and then any of them happens, the API is called again up to a number of retries set in the config.
The same could apply for outputs that the filter blocks. If something the AI generated goes against OpenAI's policies, instead of just getting flagged and notifying the user, it tries again up to X times and only notifies the user about the problem when the allowed attempts have been exhausted.
Limit lore entry descriptions and names by tokens instead of characters.
When we deal with these models, characters are always meaningless, as they deal with tokens. Currently, we have a limit of 250 characters in entry descriptions, which is almost nothing. With 250 tokens, one would be able to create very details descriptions of people, while 250 characters is barely anything.
We can work with HuggingFace's Transformer library for Java and use their tokenizer to do this internally. When someone writes something that goes beyond the token limit for descriptions, the bot notifies them to try again through an ephemeral message.
Unfortunately Discord modals are very limited and we can't add buttons to it or create a modal from another modal, so we'd need to ask for the person to really use the slash command again in case something needs correction. We can also keep with JDA and Discord API in case they improve on modal usability.
Doesn't need a description, this one's self-explanatory. We've been doing tests with the bot itself but there are no JUnits. Code coverage reports are here: https://codeclimate.com/github/thaalesalves/malaquias
We spoke about using Ada, Curie or Babbage to help with content summarization so Davinci has more context to work with which would lead to better generations. Which model will we use? What should be used as the prompt? How many messages for context? What settings should we use?
CI pipeline is failing, and also needs proper steps.
Questions:
The bot is currently under the MIT license. Should we reconsider that?
The creation command, after being used, should return a JSON object with character data. It's returning only the placeholder, though, and leaves the user without their ID.
Entry deletion command doesn't work and throws errors.
Type: Feature
OpenAI has guidelines on what can be fed to the AI and what the AI can generate as a response. To avoid issues with problematic inferences by the AI or sensitive prompts being sent to it, we need to implement a call to OAI's filter API before a prompt is sent to the AI and before the AI's generated text is sent to Discord.
reactor.core.Exceptions$ErrorCallbackNotImplemented: java.lang.NullPointerException: messageEventData not set
Caused by: java.lang.NullPointerException: messageEventData not set
at es.thalesalv.gptbot.adapters.data.ContextDatastore.lambda$1(ContextDatastore.java:36)
at java.base/java.util.Optional.orElseThrow(Optional.java:403)
at es.thalesalv.gptbot.adapters.data.ContextDatastore.getMessageEventData(ContextDatastore.java:36)
at es.thalesalv.gptbot.application.service.ChatGptModelService.generate(ChatGptModelService.java:37)
Bot currently responds when a post is pinned - generally responding to it's own nudge or the last post. It shouldn't do this.
Type: Bug
Malaquias is able to retrieve a player's character's profile when either the player is directly mentioned or when their nickname shows on the message list sent to the AI. This problem occurs during this stage, and after converting the derived query method name into an actual SQL query, the select hangs and the bot stops responding.
Dice rolls are a must-have for RPG mode. We must implement a mechanic for dice rolling and successes for this mode.
Use other bots and different intents to interpret dice rolls and feed the storytelling AI the results
Currently, persona configuration is only doable from the YAML, which means that any change to them requires a full reboot of the application. We should make it so the YAML configs act more as "default" configs that will be ingested into a persona table that can be modified while the bot is running.
Map YAML contents into a DB entity object and insert all default configs to DB. This makes the default configs more flexible before starting the bot for the first time, and just as flexible after it has started; this allows changes to be made to the persona while the bot runs.
/persona
for this to be functionalA GM-assist mode where a GM (or the player tagging the bot) get's a popup modal containing the text of the AI response where they can accept (possibly after editing or completely rewriting), request a retry, or even just cancel to go back and edit previous messages before summoning again
In this mode, summoning the bot would actually invoke a modal which would be populated by the contents of the AI reply.
Lore entries are a way of giving the AI context on places, characters and details of a the story it's telling, creating a "world" for it to describe when the entries are mentioned. But only when they're mentioned.
Entries are always in the context, which means they're being pulled from the database even when they're not mentioned. This not only clogs the context with unnecessary tokens, but could also cause leaks and break of format since the items in the entries are not being talked about in the current story/chat context.
Given that a user has a lorebook entry called "John Doe", when that entry is mentioned by its regex tag, then it should be pulled from the DB and added into the top of the AI's memory context.
Entries are always pulled into the context regardless of mentions of their regex tag. This clogs up context and adds risk of leaking and adding info of items that are not there in the current point of its context, and also wastes available tokens leading to more expensive bills on API usage.
Simplify intents chatbot
and dungeonMaster
to just chat
and rpg
to make usage simpler.
Separation of input and output mechanics for proper processing.
The current architecture the bot has is very simplistic, so it doesn't have separated flows for inputs and outputs. We need top refactor the entire thing so it works in a more flow-friendly and flexible way that is easier to implement changes, maintain and debug. We should also properly document and diagram everything so we always know what's what.
Following of single-use principle is a must here, so we need to pay attention to those.
A UI dashboard for managing the bot. This will give us more flexibility to use the bot and simplify commands on Discord.
Commands have become bloated and hard to use. Keeping all of these functionalities on Discord itself is hard, and besides bloating the code limits the usage way too much. To circumvent this, we're implementing an UI to manage the bot. Creation of channel configs, worlds, lorebooks, lore entries, configurations and all of that will be done from the UI, and the commands related to these functionalities will be removed from Discord.
This will also allows to have a more flexible control over tokens, and we will be able to change configurations on the go without restarting the app.
Useful commands to assist game masters/players drive the AIs context in the direction they want.0
Discord's limited way of dealing with messages makes it hard to drive the AIs outputs into a direction that is generally more compatible with what we want. Commands for DM assistance would be useful because they would allow players to edit AI outputs either generally (right after output is generated) or specifically (by choosing which message exactly to edit). From then on, the content sent to the AI for future completions would be more compatible with the general idea of the story.
Commands that could help drive the course of the story. Examples proposed
/codm generate
: sends content to the AI as per usual, but after generation shows a modal with the AI's output so that the player is allowed to edit things out and modify it the way they want to/codm edit <MESSAGE-ID>
: to edit a specific message so that the future content sent to the AI is more compatible with what's expected/codm retry
: deletes the last output and generates a new oneWe can discuss on both what other actions would be useful for this command, as well as the command name itself.
Worlds have a custom prompt that can be used much like scenarios on AI Dungeon, but for now they're just a dummy property that is not used for anything.
Implement mechanics to use the prompt provided for a world when either the user issues a command for that or right after a world being assigned to a channel config.
For now, we have the command /dmassist prompt
. This command is used for speaking as the bot and allows for extra generation after a message is set as the bot. This command could have another option that would, instead of opening a modal to type a custom prompt, just use the world's own prompt and send it for the AI for generation on top of that prompt.
Another mechanic could be implemented. A channel config is assigned to a channel using /chconfig set <config-id>
, and a world is assigned to that channel config by using /chconfig set <world-id>
. We could add, besides the command, a config that spits the prompt right after the current channel is assigned a world.
We should discuss the continuation of that command once we change how those work. Since commands are bloated and long, when we go about simplifying them we should study how to do this for worlds as well.
Add support for custom scenarios (or worlds) that will expand on usage of the bot.
Worlds are detached from each other. They have their own lorebooks, with their own characters and places and things. They would be created, maintained and chosen by slash commands.
lorebook
table (so each world has its own lorebook)ChannelConfig
sAnything else that would be important to discuss about?
For now, the only way to insert data into the bot's table is by connecting to the database manually since there is no function or method to insert data. To make usage of the bot simpler and more fluid, creating commands for the but is necessary; the first command to be added should be the creation of characters.
Although we won't add functionality for world and config management on Discord, a retrieval command should be available.
Implement commands for these functions with the suggested syntax:
/world get
-> returns all worlds saved in DB and channel configs linked
/world get <id>
-> returns the world with specified ids and channel configs linked
/chconf get
-> returns all chconfigs along with their linked worlds
/chconf get <id>
-> returns the specified chconfig along with its linked worlds
The overall structure of the application is a little confusing or at least the architectural intent is unclear.
Including package-info.java along with a bit of Javadoc can help clarify the intent of each package and make sure features find their right home. This needn't be done all at once (and not all packages need it), but can start at the top level and add on as clarity is required. Relevant stack overflow
Alternatively, this could be documented in a separate README, but should be intended for a more technical audience and shouldn't be part of the main README.
The AI could interpret certain reactions as directives. For example ๐ might tell the AI to ignore a message (which you don't want to delete for some reason). A โญ might tell the AI to flag something as important in the memory.
Expand on this idea.
๐ Ignore this message and all previous messages. Leave out of context.
๐ Ignore this message (maybe pick a different icon so it doesn't seem judgmental of the comment)
โญ Make this message important somehow (move closer to front of context?)
Filter AI outputs to make sure they are compatible with OpenAI's policies
For now, the bot only passes the contents of inputs and lorebook entries through the moderation filter. Although that is the bare minimum required for things to work in compatibility with OAI's policies, we should also filter the AI outputs, as it may generate inappropriate content, which breaks functionality of the entire Discord channel being used by the AI until the bad messages are found and deleted.
A permission check system to make the sure the bot has the correct permissions to delete messages from a channel. This permission check should also be made for editing and retrying generations with the bot, as leaving those commands free can cause problems with trolling.
When something goes wrong (i.e., filter is triggered or a fail in response generation), the bot deletes the message sent and asks the user to send a new one. For now, the only way to know the bot doesn't have the necessary permissions for that is when it tries to delete a message and an error is thrown. We should improve on this system by implementing a check (preferably before the bot starts listening to messages) and notify the bot owner/server admin that the permission is lacking.
Implement compatibility with ChatGPT (GPT-3.5-turbo) for the bot.
Now that GPT-3.5 has been release, we need to add support for it and for the entire ChatGPT models. Their API is different, so we need to take that into consideration and re-format the request payload sent to the API.
Differences in API
/v1/completions
payload (GPT-3)
{
"model": "text-davinci-003",
"prompt": "Say this is a test",
"max_tokens": 7,
"temperature": 1,
"stop": "\n"
}
/v1/chat/completions
payload (GPT-3.5)
{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "General bot instructions or details on persona"
},
{
"role": "user",
"content": "Message sent by the user"
},
{
"role": "assistant",
"content": "Reply made by the bot"
}
],
"max_tokens": 7,
"temperature": 1,
"stop": "\n"
}
The main difference there is that there is no prompt concept as it's a chat model. We need to break our message list into an array that follows the specific format OpenAI requires. The role
prop in the messages
array has fixed values, and can be one of these three: system
, user
or assistant
. Other than that, all other props in the payloads are the same. The ersponse payload seems to be basically the same for both model families, it's easier to format. More details:
Use AI to tell a continuous story with direction from user
This is essentially chat mode but with some unneeded things stripped out that aren't needed.
In this mode, there is no need to identify different users or retain previous direction, so we reclaim some room for context by passing only the most recent user message. We also strip out any "foo said:" that gets injected elsewhere and identify assistant/user by whether the bot said the message or someone else.
ChatGPT/chatbot is stripping the bot name out of messages
Example:
Sent by User: "Good morning, Selkie," the text reads.
Send to OAI: ChatGptMessage(role=user, content=Shel said: "Good morning, ," the text reads.)
Moderation of outputs is supposed to either try to generate a less problematic output or not post the one generated at all and notify the user about the problem. It is deleting the input and flagging it as problematic instead.
Implement a fix that forces the bot to generate a new output in case the one generated is problematic. It should only notify the user about the problems after the re-attempts have been exhausted and problematic generations kept coming.
Implementation of NanoID instead of UUID to keep things just as safe and without risk of repetition while having smaller IDs that are easier to save.
NanoID is a mechanic of ID that is just as safe and repetition risk-free as UUID, but we have more control over format and characters used, which makes them easier to use.
DM assist commands help the player/user/DM drive the story in a way that's more compatible with their ideas. This would expand on that by letting people speak as the bot or add a prompt that the bot will then elaborate on.
Implement commands that allow people to speak as the bot or give a pre-made prompt for the bot to expand on and make adventure starts more convenient and natural. This would also help users drive the story in a more specialized way.
For now, the only way to add lore entries to the lorebook is by doing it directly into the DB. We need to implement slash commands for the bot so it's able to add entries to the DB in a friendlier way.
Implementation of basic CRUD commands for the lorebook.
Slash command /lorebook ACTION UUID
create
, retrieve
, update
or delete
. Basic actions for the bot to be able to use.create
and retrieve
but required for delete
and update
./lorebook create
: Opens a modal window asking for entry name, regex (optional) and description. It should also ask whether the entry is a player character. Replies with an ephemeral message containing the JSON object of the entry created, along with its ID (that should be saved by the user).
/lorebook update <UUID>
: Using the UUID provided when creating an entry, the user should be able to modify said entry. Shows a modal with all current data already filled, and lets the user modify what they need to modify there. Replies with the modified character JSON.
/lorebook delete <UUID>
: Deletes that entry from the lorebook. Replies with a message saying the operation was successful (or not).
/lorebook retrieve
: Retrieves all lorebook entries from the lorebook and reply with an ephemeral message containing a JSON file with all entries.
/lorebook retrieve <UUID>
: Retrieves that specific entry from the lorebook and reply to the user with its JSON.
Now that we have fixed the problem with regex and the database hangs, we can expand on the concept of a lorebook. Instead of just saving player characters, we will now save general entries that can be added to the context when mentioned in the story. This will come with commands to manage these entries.
Currently the DungeonMasterUseCase adds database entries to the message queue, which results in them being assigned the user
role when sent to ChatGPT. These entries might work better if they were assigned a system
role.
I think we might want to create an internal Message object. We don't want to have another Message object on top of the JDA Message object, so let's call it MessageData for now and hopefully think up a better name.
MessageData fields:
assistant
message. If other discordId, this would be a user
message. If empty a system
message.After the restructure of commands, lorebook commands work mostly but the create function modal returns an error
When a modal is filled with the details, the app should proceed to detecting the proper service and have it add the into to the DB. But that's not happening.
Modal is filled -> service catches the content -> builds the object -> inserts into DB
After modal is filled and submitted, bot returns an error saying the command was not found. Check the behavior for other lorebook commands.
Generate command calls for completion from the API but allows the player to edit the output before posting it to Discord.
The command is not showing the modal that is supposed to allow users to edit the output, and sometimes doesn't even generate an output at all.
Upon using /dmassist generate
, the output generate is posted to Discord but a modal with the possibility of editing the output is shown right away. Upon submitting the text, the posted output is edited with whatever is in the text box.
Either nothing happens and an error is throw or the output is posted to Discord without the possibility of editing it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.