ehristoforu freddyaboulton HF Staff commited on
Commit
f914bbe
·
0 Parent(s):

Duplicate from freddyaboulton/llama2-70b-discord-bot

Browse files

Co-authored-by: Freddy Boulton <[email protected]>

Files changed (4) hide show
  1. .gitattributes +35 -0
  2. README.md +15 -0
  3. app.py +206 -0
  4. requirements.txt +1 -0
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Llama2 70b Discord Bot
3
+ emoji: 🏆
4
+ colorFrom: green
5
+ colorTo: green
6
+ sdk: gradio
7
+ sdk_version: 3.38.0
8
+ app_file: app.py
9
+ pinned: false
10
+ tags:
11
+ - gradio-discord-bot
12
+ duplicated_from: freddyaboulton/llama2-70b-discord-bot
13
+ ---
14
+
15
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app.py ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import os
3
+ import threading
4
+ from threading import Event
5
+ from typing import Optional
6
+
7
+ import discord
8
+ import gradio as gr
9
+ from discord import Permissions
10
+ from discord.ext import commands
11
+ from discord.utils import oauth_url
12
+
13
+ import gradio_client as grc
14
+ from gradio_client.utils import QueueError
15
+
16
+ event = Event()
17
+
18
+ DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
19
+
20
+
21
+ async def wait(job):
22
+ while not job.done():
23
+ await asyncio.sleep(0.2)
24
+
25
+
26
+ def get_client(session: Optional[str] = None) -> grc.Client:
27
+ client = grc.Client("https://ysharma-explore-llamav2-with-tgi.hf.space", hf_token=os.getenv("HF_TOKEN"))
28
+ if session:
29
+ client.session_hash = session
30
+ return client
31
+
32
+
33
+ def truncate_response(response: str) -> str:
34
+ ending = "...\nTruncating response to 2000 characters due to discord api limits."
35
+ if len(response) > 2000:
36
+ return response[: 2000 - len(ending)] + ending
37
+ else:
38
+ return response
39
+
40
+
41
+ intents = discord.Intents.default()
42
+ intents.message_content = True
43
+ bot = commands.Bot(command_prefix="!", intents=intents)
44
+
45
+
46
+ @bot.event
47
+ async def on_ready():
48
+ print(f"Logged in as {bot.user} (ID: {bot.user.id})")
49
+ event.set()
50
+ print("------")
51
+
52
+
53
+ thread_to_client = {}
54
+ thread_to_user = {}
55
+
56
+
57
+ @bot.command()
58
+ @commands.is_owner()
59
+ async def sync(ctx) -> None:
60
+ synced = await bot.tree.sync()
61
+ await ctx.send(f"Synced commands: {', '.join([s.name for s in synced])}.")
62
+
63
+
64
+ @bot.hybrid_command(
65
+ name="llama70b",
66
+ description="Enter some text to chat with the bot! Like this: /llama70b Hello, how are you?",
67
+ )
68
+ async def chat(ctx, prompt: str):
69
+ if ctx.author.id == bot.user.id:
70
+ return
71
+ try:
72
+ message = await ctx.send("Creating thread...")
73
+
74
+ # User triggered bot via !llama70b
75
+ if ctx.message.content:
76
+ prompt = ctx.message.content.replace(
77
+ f"{bot.command_prefix}llama70b", ""
78
+ ).strip()
79
+
80
+ thread = await message.create_thread(name=prompt)
81
+ loop = asyncio.get_running_loop()
82
+ client = await loop.run_in_executor(None, get_client, None)
83
+ job = client.submit(prompt, api_name="/chat")
84
+ await wait(job)
85
+
86
+ try:
87
+ job.result()
88
+ response = job.outputs()[-1]
89
+ print(response)
90
+ await thread.send(truncate_response(response))
91
+ thread_to_client[thread.id] = client
92
+ thread_to_user[thread.id] = ctx.author.id
93
+ except QueueError:
94
+ await thread.send(
95
+ "The gradio space powering this bot is really busy! Please try again later!"
96
+ )
97
+
98
+ except Exception as e:
99
+ print(f"{e}")
100
+
101
+
102
+ async def continue_chat(message):
103
+ """Continues a given conversation based on chathistory"""
104
+ try:
105
+ client = thread_to_client[message.channel.id]
106
+ prompt = message.content
107
+ job = client.submit(prompt, api_name="/chat")
108
+ await wait(job)
109
+ try:
110
+ job.result()
111
+ response = job.outputs()[-1]
112
+ await message.reply(truncate_response(response))
113
+ except QueueError:
114
+ await message.reply(
115
+ "The gradio space powering this bot is really busy! Please try again later!"
116
+ )
117
+
118
+ except Exception as e:
119
+ print(f"Error: {e}")
120
+
121
+
122
+ @bot.event
123
+ async def on_message(message):
124
+ """Continue the chat"""
125
+ try:
126
+ if not message.author.bot:
127
+ if message.channel.id in thread_to_user:
128
+ if thread_to_user[message.channel.id] == message.author.id:
129
+ await continue_chat(message)
130
+ else:
131
+ await bot.process_commands(message)
132
+
133
+ except Exception as e:
134
+ print(f"Error: {e}")
135
+
136
+
137
+ # running in thread
138
+ def run_bot():
139
+ if not DISCORD_TOKEN:
140
+ print("DISCORD_TOKEN NOT SET")
141
+ event.set()
142
+ else:
143
+ bot.run(DISCORD_TOKEN)
144
+
145
+
146
+ threading.Thread(target=run_bot).start()
147
+
148
+ event.wait()
149
+
150
+ if not DISCORD_TOKEN:
151
+ welcome_message = """
152
+
153
+ ## You have not specified a DISCORD_TOKEN, which means you have not created a bot account. Please follow these steps:
154
+
155
+ ### 1. Go to https://discord.com/developers/applications and click 'New Application'
156
+
157
+ ### 2. Give your bot a name 🤖
158
+
159
+ ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/BotName.png)
160
+
161
+ ## 3. In Settings > Bot, click the 'Reset Token' button to get a new token. Write it down and keep it safe 🔐
162
+
163
+ ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/ResetToken.png)
164
+
165
+ ## 4. Optionally make the bot public if you want anyone to be able to add it to their servers
166
+
167
+ ## 5. Scroll down and enable 'Message Content Intent' under 'Priviledged Gateway Intents'
168
+
169
+ ![](https://gradio-builds.s3.amazonaws.com/demo-files/discordbots/MessageContentIntent.png)
170
+
171
+ ## 6. Save your changes!
172
+
173
+ ## 7. The token from step 3 is the DISCORD_TOKEN. Rerun the deploy_discord command, e.g client.deploy_discord(discord_bot_token=DISCORD_TOKEN, ...), or add the token as a space secret manually.
174
+ """
175
+ else:
176
+ permissions = Permissions(326417525824)
177
+ url = oauth_url(bot.user.id, permissions=permissions)
178
+ welcome_message = f"""
179
+ ## Add this bot to your server by clicking this link:
180
+
181
+ {url}
182
+
183
+ ## How to use it?
184
+
185
+ The bot can be triggered via `!llama70b` followed by your text prompt.
186
+
187
+ ## Enabling slash commands
188
+
189
+ If you are the owner of this bot, call the `!sync` command from your discord server.
190
+ This will allow anyone in your server to call the bot via `/llama70b`.
191
+ This is known as a slash command and is a nicer experience than calling the bot via `!llama70b`.
192
+
193
+ After calling `!sync`, it may take a few minutes for `/llama70b` to be recognized as a valid command
194
+ in your server.
195
+ """
196
+
197
+
198
+ with gr.Blocks() as demo:
199
+ gr.Markdown(
200
+ f"""
201
+ # Discord bot of https://ysharma-explore-llamav2-with-tgi.hf.space
202
+ {welcome_message}
203
+ """
204
+ )
205
+
206
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ discord.py==2.3.1