feat: Add examples,docs

Former-commit-id: 16c8103be9
discord-bot-framework
Zack 1 year ago
parent fe4119a1b0
commit 150015dee4

@ -44,3 +44,9 @@ REVGPT_DISABLE_HISTORY=True
REVGPT_PUID="your_puid_here" REVGPT_PUID="your_puid_here"
REVGPT_UNVERIFIED_PLUGIN_DOMAINS="showme.redstarplugin.com" REVGPT_UNVERIFIED_PLUGIN_DOMAINS="showme.redstarplugin.com"
CHATGPT_BASE_URL="" CHATGPT_BASE_URL=""
#Discord Bot
################################
SAVE_DIRECTORY=""
STORAGE_SERVICE=""
DISCORD_TOKEN=""

@ -1,92 +1,138 @@
import discord
from discord.ext import commands
from swarms.models import OpenAIChat
from swarms.agents import OmniModalAgent
import os import os
import asyncio
import dalle3
import discord
import responses
from invoke import Executor
from dotenv import load_dotenv from dotenv import load_dotenv
from discord.ext import commands from discord.ext import commands
load_dotenv() class Bot:
def __init__(self, agent, llm, command_prefix="!"):
intents = discord.Intents.default() load_dotenv()
intents.messages = True
intents.guilds = True intents = discord.intents.default()
intents.voice_states = True intents.messages = True
intents.message_content = True intents.guilds = True
intents.voice_states = True
bot = commands.Bot(command_prefix="!", intents=intents) intents.message_content = True
# Setup
# setup
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN") self.llm = llm
self.agent = agent
# Initialize the OmniModalAgent self. bot = commands.bot(command_prefix="!", intents=intents)
llm = OpenAIChat(model_name="gpt-4") self.discord_token = os.getenv("DISCORD_TOKEN")
agent = OmniModalAgent(llm) self.storage_service = os.getenv("STORAGE_SERVICE")
@bot.event @self.bot.event
async def on_ready(): async def on_ready():
print(f"We have logged in as {bot.user}") print(f"we have logged in as {self.bot.user}")
@bot.command() @self.bot.command()
async def greet(ctx): async def greet(ctx):
"""Greets the user.""" """greets the user."""
await ctx.send(f"Hello, {ctx.author.name}!") await ctx.send(f"hello, {ctx.author.name}!")
@bot.command() @self.bot.command()
async def run(ctx, *, description: str): async def help_me(ctx):
"""Generates a video based on the given description.""" """provides a list of commands and their descriptions."""
response = agent.run( help_text = """
description - `!greet`: greets you.
) # Assuming the response provides information or a link to the generated video - `!run [description]`: generates a video based on the given description.
await ctx.send(response) - `!help_me`: provides this list of commands and their descriptions.
"""
await ctx.send(help_text)
@bot.command()
async def help_me(ctx): @self.bot.event
"""Provides a list of commands and their descriptions.""" async def on_command_error(ctx, error):
help_text = """ """handles errors that occur while executing commands."""
- `!greet`: Greets you. if isinstance(error, commands.commandnotfound):
- `!run [description]`: Generates a video based on the given description. await ctx.send("that command does not exist!")
- `!help_me`: Provides this list of commands and their descriptions. else:
""" await ctx.send(f"an error occurred: {error}")
await ctx.send(help_text)
@self.bot.command()
@bot.event async def join(ctx):
async def on_command_error(ctx, error): """joins the voice channel that the user is in."""
"""Handles errors that occur while executing commands.""" if ctx.author.voice:
if isinstance(error, commands.CommandNotFound): channel = ctx.author.voice.channel
await ctx.send("That command does not exist!") await channel.connect()
else: else:
await ctx.send(f"An error occurred: {error}") await ctx.send("you are not in a voice channel!")
def setup(bot): @self.bot.command()
@bot.command() async def leave(ctx):
async def join(ctx): """leaves the voice channel that the self.bot is in."""
"""Joins the voice channel that the user is in.""" if ctx.voice_client:
if ctx.author.voice: await ctx.voice_client.disconnect()
channel = ctx.author.voice.channel else:
await channel.connect() await ctx.send("i am not in a voice channel!")
else:
await ctx.send("You are not in a voice channel!") # voice_transcription.py
@self.bot.command()
@bot.command() async def listen(ctx):
async def leave(ctx): """starts listening to voice in the voice channel that the bot is in."""
"""Leaves the voice channel that the bot is in.""" if ctx.voice_client:
if ctx.voice_client: # create a wavesink to record the audio
await ctx.voice_client.disconnect() sink = discord.sinks.wavesink('audio.wav')
else: # start recording
await ctx.send("I am not in a voice channel!") ctx.voice_client.start_recording(sink)
await ctx.send("started listening and recording.")
# voice_transcription.py else:
from discord.ext import commands await ctx.send("i am not in a voice channel!")
def setup(bot): # image_generator.py
@bot.command() @self.bot.command()
async def listen(ctx): async def generate_image(ctx, *, prompt: str):
"""Starts listening to voice in the voice channel that the bot is in.""" """generates images based on the provided prompt"""
# ... (code for listening to voice and transcribing it goes here) await ctx.send(f"generating images for prompt: `{prompt}`...")
loop = asyncio.get_event_loop()
bot.run("DISCORD_TOKEN")
# initialize a future object for the dalle instance
model_instance = dalle3()
future = loop.run_in_executor(Executor, model_instance.run, prompt)
try:
# wait for the dalle request to complete, with a timeout of 60 seconds
await asyncio.wait_for(future, timeout=300)
print("done generating images!")
# list all files in the save_directory
all_files = [os.path.join(root, file) for root, _, files in os.walk(os.environ("SAVE_DIRECTORY")) for file in files]
# sort files by their creation time (latest first)
sorted_files = sorted(all_files, key=os.path.getctime, reverse=True)
# get the 4 most recent files
latest_files = sorted_files[:4]
print(f"sending {len(latest_files)} images to discord...")
# send all the latest images in a single message
storage_service = os.environ("STORAGE_SERVICE") # "https://storage.googleapis.com/your-bucket-name/
await ctx.send(files=[storage_service.upload(filepath) for filepath in latest_files])
except asyncio.timeouterror:
await ctx.send("the request took too long! it might have been censored or you're out of boosts. please try entering the prompt again.")
except Exception as e:
await ctx.send(f"an error occurred: {e}")
@self.bot.command()
async def send_text(ctx, *, text: str, use_agent: bool = True):
"""sends the provided text to the worker and returns the response"""
if use_agent:
response = self.agent.run(text)
else:
response = self.llm.run(text)
await ctx.send(response)
def add_command(self, name, func):
@self.bot.command()
async def command(ctx, *args):
reponse = func(*args)
await ctx.send(responses)
def run(self) :
self.bot.run("DISCORD_TOKEN")

@ -0,0 +1,103 @@
## Usage Documentation: Discord Bot with Advanced Features
---
### Overview:
This code provides a structure for a Discord bot with advanced features such as voice channel interactions, image generation, and text-based interactions using OpenAI models.
---
### Setup:
1. Ensure that the necessary libraries are installed:
```bash
pip install discord.py python-dotenv dalle3 invoke openai
```
2. Create a `.env` file in the same directory as your bot script and add the following:
```
DISCORD_TOKEN=your_discord_bot_token
STORAGE_SERVICE=your_storage_service_endpoint
SAVE_DIRECTORY=path_to_save_generated_images
```
---
### Bot Class and its Methods:
#### `__init__(self, agent, llm, command_prefix="!")`:
Initializes the bot with the given agent, language model (`llm`), and a command prefix (default is `!`).
#### `add_command(self, name, func)`:
Allows you to dynamically add new commands to the bot. The `name` is the command's name and `func` is the function to execute when the command is called.
#### `run(self)`:
Starts the bot using the `DISCORD_TOKEN` from the `.env` file.
---
### Commands:
1. **!greet**: Greets the user.
2. **!help_me**: Provides a list of commands and their descriptions.
3. **!join**: Joins the voice channel the user is in.
4. **!leave**: Leaves the voice channel the bot is currently in.
5. **!listen**: Starts listening to voice in the current voice channel and records the audio.
6. **!generate_image [prompt]**: Generates images based on the provided prompt using the DALL-E3 model.
7. **!send_text [text] [use_agent=True]**: Sends the provided text to the worker (either the agent or the LLM) and returns the response.
---
### Usage:
Initialize the `llm` (Language Learning Model) with your OpenAI API key:
```python
from swarms.models import OpenAIChat
llm = OpenAIChat(
openai_api_key="Your_OpenAI_API_Key",
temperature=0.5,
)
```
Initialize the bot with the `llm`:
```python
from apps.discord import Bot
bot = Bot(llm=llm)
```
Send a task to the bot:
```python
task = "What were the winning Boston Marathon times for the past 5 years (ending in 2022)? Generate a table of the year, name, country of origin, and times."
bot.send_text(task)
```
Start the bot:
```python
bot.run()
```
---
### Additional Notes:
- The bot makes use of the `dalle3` library for image generation. Ensure you have the model and necessary setup for it.
- For the storage service, you might want to integrate with a cloud service like Google Cloud Storage or AWS S3 to store and retrieve generated images. The given code assumes a method `.upload()` for the storage service to upload files.
- Ensure that you've granted the bot necessary permissions on Discord, especially if you want to use voice channel features.
- Handle API keys and tokens securely. Avoid hardcoding them directly into your code. Use environment variables or secure secret management tools.

@ -0,0 +1,14 @@
from swarms.models import OpenAIChat
from apps.discord import Bot
llm = OpenAIChat(
openai_api_key="Enter in your key",
temperature=0.5,
)
bot = Bot(llm=llm)
task = "What were the winning boston marathon times for the past 5 years (ending in 2022)? Generate a table of the year, name, country of origin, and times."
bot.send_text(task)
bot.run()
Loading…
Cancel
Save