| import asyncio |
| import os |
| import threading |
| from threading import Event |
| from typing import Optional |
|
|
| import discord |
| import gradio as gr |
| from discord.ext import commands |
| import gradio_client as grc |
| from gradio_client.utils import QueueError |
|
|
| event = Event() |
|
|
| DISCORD_TOKEN = os.getenv("DISCORD_TOKEN") |
|
|
|
|
| async def wait(job): |
| while not job.done(): |
| await asyncio.sleep(0.2) |
|
|
|
|
| def get_client(session: Optional[str] = None) -> grc.Client: |
| client = grc.Client("https://lunarflu-falcon-180b-demo-duplicate.hf.space", hf_token=os.getenv("HF_TOKEN")) |
| if session: |
| client.session_hash = session |
| return client |
|
|
|
|
| def truncate_response(response: str) -> str: |
| ending = "...\nTruncating response to 2000 characters due to discord api limits." |
| if len(response) > 2000: |
| return response[: 2000 - len(ending)] + ending |
| else: |
| return response |
|
|
|
|
| intents = discord.Intents.default() |
| intents.message_content = True |
| bot = commands.Bot(command_prefix="/", intents=intents) |
|
|
|
|
| @bot.event |
| async def on_ready(): |
| print(f"Logged in as {bot.user} (ID: {bot.user.id})") |
| synced = await bot.tree.sync() |
| print(f"Synced commands: {', '.join([s.name for s in synced])}.") |
| event.set() |
| print("------") |
|
|
|
|
| thread_to_client = {} |
| thread_to_user = {} |
|
|
|
|
| @bot.hybrid_command( |
| name="falcon180", |
| description="Enter some text to chat with the bot! Like this: /falcon180 Hello, how are you?", |
| ) |
| async def chat(ctx, prompt: str): |
| if ctx.author.id == bot.user.id: |
| return |
| try: |
| if ctx.guild.id == 879548962464493619: |
| if ctx.channel.id != 1119313248056004729: |
| return |
| message = await ctx.send("Creating thread...") |
|
|
| thread = await message.create_thread(name=prompt[:100]) |
| loop = asyncio.get_running_loop() |
| client = await loop.run_in_executor(None, get_client, None) |
| job = client.submit(prompt, "", 0.9, 256, 0.95, 1.0, api_name="/chat") |
| await wait(job) |
|
|
| try: |
| job.result() |
| response = job.outputs()[-1] |
| await thread.send(truncate_response(response)) |
| thread_to_client[thread.id] = client |
| thread_to_user[thread.id] = ctx.author.id |
| except QueueError: |
| await thread.send("The gradio space powering this bot is really busy! Please try again later!") |
|
|
| except Exception as e: |
| print(f"{e}") |
|
|
|
|
| async def continue_chat(message): |
| """Continues a given conversation based on chathistory""" |
| try: |
| client = thread_to_client[message.channel.id] |
| prompt = message.content |
| job = client.submit(prompt, "", 0.9, 256, 0.95, 1.0, api_name="/chat") |
| await wait(job) |
| try: |
| job.result() |
| response = job.outputs()[-1] |
| await message.reply(truncate_response(response)) |
| except QueueError: |
| await message.reply("The gradio space powering this bot is really busy! Please try again later!") |
|
|
| except Exception as e: |
| print(f"Error: {e}") |
|
|
|
|
| @bot.event |
| async def on_message(message): |
| """Continue the chat""" |
| try: |
| if not message.author.bot: |
| if message.channel.id in thread_to_user: |
| if thread_to_user[message.channel.id] == message.author.id: |
| await continue_chat(message) |
| else: |
| await bot.process_commands(message) |
|
|
| except Exception as e: |
| print(f"Error: {e}") |
|
|
|
|
| |
| def run_bot(): |
| if not DISCORD_TOKEN: |
| print("DISCORD_TOKEN NOT SET") |
| event.set() |
| else: |
| bot.run(DISCORD_TOKEN) |
|
|
|
|
| threading.Thread(target=run_bot).start() |
|
|
| event.wait() |
|
|
|
|
| welcome_message = """ |
| ## Add this bot to your server by clicking this link: |
| |
| https://discord.com/api/oauth2/authorize?client_id=1155169841276260546&permissions=326417516544&scope=bot |
| |
| ## How to use it? |
| |
| The bot can be triggered via `/falcon180` followed by your text prompt. |
| |
| This will create a thread with the bot's response to your text prompt. |
| You can reply in the thread (without `/falcon180`) to continue the conversation. |
| In the thread, the bot will only reply to the original author of the command. |
| |
| ⚠️ Note ⚠️: Please make sure this bot's command does have the same name as another command in your server. |
| |
| ⚠️ Note ⚠️: Bot commands do not work in DMs with the bot as of now. |
| """ |
|
|
|
|
| with gr.Blocks() as demo: |
| gr.Markdown(f""" |
| # Discord bot of https://tiiuae-falcon-180b-demo.hf.space |
| {welcome_message} |
| """) |
|
|
| demo.launch() |
|
|