mirror of
https://github.com/wassname/Open-Assistant.git
synced 2026-07-14 01:00:05 +08:00
Adding a slash command based discord bot
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
.env
|
||||
*.egg-info/
|
||||
__pycache__/
|
||||
@@ -0,0 +1,13 @@
|
||||
install:
|
||||
python -m pip install -U pip
|
||||
python -m pip install -e .
|
||||
|
||||
lint: ## [Local development] Run pylint and black
|
||||
python -m pylint app
|
||||
python -m black --check -l 120 app
|
||||
|
||||
black: ## [Local development] Auto-format python code using black
|
||||
python -m black -l 120 .
|
||||
|
||||
run:
|
||||
python -m bot
|
||||
@@ -0,0 +1,11 @@
|
||||
# open-chat-gpt
|
||||
This is the github repo for the open-chat-gpt project.
|
||||
We are currently building a discord bot in order to make everyone contribute with great prompts and answers.
|
||||
Join us!
|
||||
https://discord.gg/ZUfPw6jP
|
||||
|
||||
## Project description
|
||||
We are calling the community for help to collect ChatGPT-like Instruction-Fulfillment datasamples via Discord. People can post Instructions they think would make sense for ChatGPT-like systems & also provide a good reference answer for it.
|
||||
|
||||
## Todo
|
||||
Figure out ouath flow for the app to work inside the open-chat-gpt testing channel here. https://discord.gg/JJSKtRhv
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
bot_url = "https://discord.com/api/oauth2/authorize?client_id=1051614245940375683&permissions=8&scope=bot"
|
||||
|
||||
import discord
|
||||
import json
|
||||
import os
|
||||
import requests
|
||||
|
||||
from discord import app_commands
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load up all the important environment variables.
|
||||
load_dotenv()
|
||||
|
||||
# For authentication.
|
||||
TOKEN = os.getenv("DISCORD_TOKEN")
|
||||
|
||||
# For Backends.
|
||||
API_SERVER_URL = os.getenv("API_SERVER_URL")
|
||||
API_SERVER_KEY = os.getenv("API_SERVER_KEY")
|
||||
|
||||
labelers_url = f"{API_SERVER_URL}/api/v1/labelers/"
|
||||
prompts_url = f"{API_SERVER_URL}/api/v1/prompts/"
|
||||
headers = {"X-API-Key": API_SERVER_KEY}
|
||||
|
||||
# For testing only.
|
||||
TEST_GUILD = os.getenv("TEST_GUILD")
|
||||
|
||||
# Initiate the client and command tree to create slash commands.
|
||||
class OpenChatGPTClient(discord.Client):
|
||||
def __init__(self, *, intents: discord.Intents):
|
||||
super().__init__(intents=intents)
|
||||
self.tree = app_commands.CommandTree(self)
|
||||
|
||||
async def setup_hook(self):
|
||||
if TEST_GUILD:
|
||||
# When testing the bot it's handy to run in a single server (called a
|
||||
# Guide in the API). This is relatively fast.
|
||||
guild = discord.Object(id=TEST_GUILD)
|
||||
self.tree.copy_global_to(guild=guild)
|
||||
await self.tree.sync(guild=guild)
|
||||
else:
|
||||
# This can take up to an hour for the commands to be registered.
|
||||
await tree.sync()
|
||||
print("Ready!")
|
||||
|
||||
|
||||
# List the set of intents needed for commands to operate properly.
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
client = OpenChatGPTClient(intents=intents)
|
||||
|
||||
|
||||
@client.tree.command()
|
||||
async def register(interaction: discord.Interaction):
|
||||
"""Registers the user for submissions."""
|
||||
labeler = {
|
||||
"discord_username": f"{interaction.user.id}",
|
||||
"display_name": interaction.user.name,
|
||||
"is_enabled": True,
|
||||
}
|
||||
response = requests.post(labelers_url, headers=headers, json=labeler)
|
||||
if response.status_code == 200:
|
||||
await interaction.response.send_message(f"Added you {interaction.user.name}")
|
||||
else:
|
||||
print(response)
|
||||
await interaction.response.send_message(f"Failed to add you")
|
||||
|
||||
|
||||
@client.tree.command()
|
||||
async def list_participants(interaction: discord.Interaction):
|
||||
"""Reports the set of registered participants."""
|
||||
response = requests.get(labelers_url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
names = ",".join([labeler["display_name"] for labeler in response.json()])
|
||||
await interaction.response.send_message(f"Found these users: {names}")
|
||||
else:
|
||||
await interaction.response.send_message(f"Failed to fetch participants")
|
||||
|
||||
|
||||
@client.tree.command()
|
||||
async def add_prompt(
|
||||
interaction: discord.Interaction, prompt: str, response: str, language: str = "en"
|
||||
):
|
||||
"""Uploads a single prompt to the server."""
|
||||
prompt = {
|
||||
"discord_username": f"{interaction.user.id}",
|
||||
"labeler_id": 5,
|
||||
"prompt": prompt,
|
||||
"response": response,
|
||||
"lang": language,
|
||||
}
|
||||
response = requests.post(prompts_url, headers=headers, json=prompt)
|
||||
if response.status_code == 200:
|
||||
await interaction.response.send_message(f"Added your prompt")
|
||||
else:
|
||||
await interaction.response.send_message(f"Failed to add the prompt")
|
||||
|
||||
|
||||
@client.tree.command()
|
||||
async def add_prompts_set(
|
||||
interaction: discord.Interaction, prompts: discord.Attachment
|
||||
):
|
||||
"""Uploads a batch of prompts to the server."""
|
||||
# Loading a bunch of prompts from a file can take a while. So first defer
|
||||
# the response to ensure we're able to later tell the user what happened.
|
||||
await interaction.response.defer(ephemeral=True)
|
||||
|
||||
# Read the prompts and load them one by one.
|
||||
# TODO: Upload a batch when the API supports it.
|
||||
# TODO: Handle incorrect file types and parsing errors.
|
||||
prompts_raw = await prompts.read()
|
||||
prompts_loaded = json.loads(prompts_raw)
|
||||
count = 0
|
||||
for entry in prompts_loaded:
|
||||
for response in entry["responses"]:
|
||||
prompt = {
|
||||
"discord_username": f"{interaction.user.id}",
|
||||
"labeler_id": 5,
|
||||
"prompt": entry["prompt"],
|
||||
"response": response,
|
||||
"lang": "en",
|
||||
}
|
||||
response = requests.post(prompts_url, headers=headers, json=prompt)
|
||||
if response.status_code != 200:
|
||||
await interaction.followup.send(f"Failed to upload")
|
||||
return
|
||||
count += 1
|
||||
await interaction.followup.send(f"Loaded up {count} prompts")
|
||||
|
||||
|
||||
client.run(TOKEN)
|
||||
@@ -0,0 +1,2 @@
|
||||
discord.py==2.1.0
|
||||
python-dotenv==0.21.0
|
||||
@@ -0,0 +1,34 @@
|
||||
from setuptools import setup, find_packages
|
||||
from pathlib import Path
|
||||
import os
|
||||
|
||||
if __name__ == "__main__":
|
||||
import os
|
||||
|
||||
def _read_reqs(relpath):
|
||||
fullpath = os.path.join(os.path.dirname(__file__), relpath)
|
||||
with open(fullpath) as f:
|
||||
return [
|
||||
s.strip()
|
||||
for s in f.readlines()
|
||||
if (s.strip() and not s.startswith("#"))
|
||||
]
|
||||
|
||||
REQUIREMENTS = _read_reqs("requirements.txt")
|
||||
|
||||
setup(
|
||||
name="open-chat-gpt",
|
||||
packages=find_packages(),
|
||||
version="0.0.1",
|
||||
license="Apache 2.0",
|
||||
description="A Discord Bot for collecting and ranking prompts to train an Open ChatGPT",
|
||||
keywords=["machine learning", "natural language processing", "discord"],
|
||||
install_requires=REQUIREMENTS,
|
||||
classifiers=[
|
||||
"Development Status :: Alpha",
|
||||
"Intended Audience :: Developers",
|
||||
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
||||
"License :: OSI Approved :: Apache License",
|
||||
"Programming Language :: Python :: 3.6",
|
||||
],
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"prompt": "tell me the name of two dogs",
|
||||
"responses": ["Charles", "bobby"]
|
||||
},
|
||||
{
|
||||
"prompt": "Name one type of cheese made in france",
|
||||
"responses": ["Munster", "Gouda"]
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user