Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update bot driver and cli commands #39

Merged
merged 4 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ jobs:
- name: Windows CLI Package
if: ${{ matrix.os == 'windows-latest' }}
run: |
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-binary='discordai/bot/cogs;discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --collect-data=discordai_modelizer
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-binary='discordai/bot/cogs;discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --collect-data=better_profanity --collect-data=discordai_modelizer
Compress-Archive -Path dist\*discordai* -DestinationPath discordai-windows.zip
- name: Mac CLI Package
if: ${{ matrix.os == 'macos-latest' }}
run: |
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-data='discordai/bot/cogs:discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --hidden-import=configparser --collect-data=discordai_modelizer --collect-data=aiohttp --collect-data=certifi
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-data='discordai/bot/cogs:discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --collect-data=better_profanity --hidden-import=configparser --collect-data=discordai_modelizer --collect-data=aiohttp --collect-data=certifi
zip -j discordai-macos.zip dist/*discordai*
chmod +x dist/*discordai*
- name: Linux CLI Package
if: ${{ matrix.os == 'ubuntu-latest' }}
run: |
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-binary='discordai/bot/cogs:discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --collect-data=discordai_modelizer
pyinstaller discordai/command_line/command_line.py --console --onefile --name=discordai --add-binary='discordai/bot/cogs:discordai/bot/cogs' --hidden-import=openai --hidden-import=tiktoken --collect-data=better_profanity --collect-data=discordai_modelizer
zip -j discordai-linux.zip dist/*discordai*
chmod +x dist/*discordai*
# Upload
Expand Down
93 changes: 52 additions & 41 deletions discordai/bot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@

intents = discord.Intents.default()
intents.message_content = True
bot = Bot(command_prefix=commands.when_mentioned_or(
'/'), intents=intents, help_command=None)
bot = Bot(
command_prefix=commands.when_mentioned_or("/"), intents=intents, help_command=None
)


def start_bot(config, sync=False):
bot.config = config
def start_bot(discord_token: str, openai_key: str, sync=False):
bot.DISCORD_BOT_TOKEN = discord_token
bot.OPENAI_API_KEY = openai_key
bot.chat_messages = {}
bot.emoji_map = {}

Expand Down Expand Up @@ -72,10 +74,12 @@ async def on_command_completion(context: Context) -> None:
executed_command = str(split[0])
if context.guild is not None:
print(
f"Executed {executed_command} command in {context.guild.name} (ID: {context.guild.id}) by {context.author} (ID: {context.author.id})")
f"Executed {executed_command} command in {context.guild.name} (ID: {context.guild.id}) by {context.author} (ID: {context.author.id})"
)
else:
print(
f"Executed {executed_command} command by {context.author} (ID: {context.author.id}) in DMs")
f"Executed {executed_command} command by {context.author} (ID: {context.author.id}) in DMs"
)

@bot.event
async def on_command_error(context: Context, error) -> None:
Expand All @@ -91,31 +95,33 @@ async def on_command_error(context: Context, error) -> None:
embed = discord.Embed(
title="Hey, please slow down!",
description=f"You can use this command again in {f'{round(hours)} hours' if round(hours) > 0 else ''} {f'{round(minutes)} minutes' if round(minutes) > 0 else ''} {f'{round(seconds)} seconds' if round(seconds) > 0 else ''}.",
color=0xE02B2B
color=0xE02B2B,
)
await context.send(embed=embed)
elif isinstance(error, commands.MissingPermissions):
embed = discord.Embed(
title="Error!",
description="You are missing the permission(s) `" + ", ".join(
error.missing_permissions) + "` to execute this command!",
color=0xE02B2B
description="You are missing the permission(s) `"
+ ", ".join(error.missing_permissions)
+ "` to execute this command!",
color=0xE02B2B,
)
await context.send(embed=embed)
elif isinstance(error, commands.BotMissingPermissions):
embed = discord.Embed(
title="Error!",
description="I am missing the permission(s) `" + ", ".join(
error.missing_permissions) + "` to fully perform this command!",
color=0xE02B2B
description="I am missing the permission(s) `"
+ ", ".join(error.missing_permissions)
+ "` to fully perform this command!",
color=0xE02B2B,
)
await context.send(embed=embed)
elif isinstance(error, commands.MissingRequiredArgument):
embed = discord.Embed(
title="Error!",
# We need to capitalize because the command arguments have no capital letter in the code.
description=str(error).capitalize(),
color=0xE02B2B
color=0xE02B2B,
)
await context.send(embed=embed)
raise error
Expand All @@ -124,43 +130,48 @@ async def load_cogs() -> None:
"""
The code in this function is executed whenever the bot will start.
"""
if getattr(sys, 'frozen', False):
if getattr(sys, "frozen", False):
# The code is being run as a frozen executable
cogs_path = pathlib.Path(appdirs.user_data_dir(appname="discordai")) / "discordai" / "bot" / "cogs"
cogs_path = (
pathlib.Path(appdirs.user_data_dir(appname="discordai"))
/ "discordai"
/ "bot"
/ "cogs"
)
data_dir = pathlib.Path(sys._MEIPASS)
og_cogs_path = data_dir / "discordai" / "bot" / "cogs"
os.makedirs(cogs_path, exist_ok=True)
for file in og_cogs_path.glob("*"):
dest_file = cogs_path / file.name
shutil.copy2(file, dest_file)
for file in os.listdir(cogs_path):
if file.endswith(".py"):
extension = file[:-3]
if extension != "__init__":
try:
module_path = cogs_path / f'{extension}.py'
spec = importlib.util.spec_from_file_location(extension, module_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
await module.setup(bot=bot)
print(f"Loaded extension '{extension}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {extension}\n{exception}")
for file in cogs_path.glob("*.py"):
if file.stem != "__init__":
try:
module_path = cogs_path / file.name
spec = importlib.util.spec_from_file_location(
file.stem, module_path
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
await module.setup(bot=bot)
print(f"Loaded extension '{file.stem}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {file.stem}\n{exception}")
else:
# The code is being run normally
bot_dir = pathlib.Path(os.path.dirname(__file__))
cogs_path = bot_dir / "cogs"
for file in os.listdir(cogs_path):
if file.endswith(".py"):
extension = file[:-3]
if extension != "__init__":
try:
await bot.load_extension(f".cogs.{extension}", package="discordai.bot")
print(f"Loaded extension '{extension}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {extension}\n{exception}")
for file in cogs_path.glob("*.py"):
if file.stem != "__init__":
try:
await bot.load_extension(
f".cogs.{file.stem}", package="discordai.bot"
)
print(f"Loaded extension '{file.stem}'")
except Exception as e:
exception = f"{type(e).__name__}: {e}"
print(f"Failed to load extension {file.stem}\n{exception}")

asyncio.run(load_cogs())
bot.run(config["token"])
bot.run(bot.DISCORD_BOT_TOKEN)
10 changes: 5 additions & 5 deletions discordai/command_line/command_line.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,26 @@ def discordai():
command_line.read_modelizer_args(args, model_subcommand, job_subcommand)
elif args.command == "bot":
if args.subcommand == "start":
bot.start_bot(config, args.sync)
bot.start_bot(args.discord_token, args.openai_key, args.sync)
elif args.subcommand == "command":
if args.subsubcommand == "new":
if args.subsubcommand == "add":
template.gen_new_command(
args.model_id,
args.openai_key,
args.command_name,
args.temp_default,
args.pres_default,
args.freq_default,
args.max_tokens_default,
args.stop_default,
args.openai_key,
args.bold_default,
)
elif args.subsubcommand == "delete":
template.delete_command(args.command_name)
else:
raise argparse.ArgumentError(
bot_subsubcommand,
"Must choose a command from `new` or `delete`",
"Must choose a command from `add` or `delete`",
)
else:
raise argparse.ArgumentError(
Expand All @@ -77,7 +77,7 @@ def discordai():
config[args.key] = args.value
configuration.save(config)
config = configuration.get()
print("Config:")
print(f"{configuration.config_dir / 'config.json'}:")
command_line.display(config)


Expand Down
32 changes: 26 additions & 6 deletions discordai/command_line/subparsers.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,38 @@
from discordai_modelizer.command_line.subparsers import set_openai_help_str
from discordai_modelizer.command_line.subparsers import (
set_openai_help_str,
set_bot_key_help_str,
)


def setup_bot_start(bot_subcommand):
bot_cmd_start = bot_subcommand.add_parser("start", help="Start your discord bot")
bot_cmd_required_named = bot_cmd_start.add_argument_group(
"required named arguments"
)
bot_cmd_optional_named = bot_cmd_start.add_argument_group(
"optional named arguments"
)

bot_cmd_required_named.add_argument(
"-d",
"--discord-token",
type=str,
dest="discord_token",
help=f"The Discord token for your bot. Must either be passed in as an argument or set {set_bot_key_help_str(is_parent=True)}",
)
bot_cmd_required_named.add_argument(
"-o",
"--openai-key",
type=str,
dest="openai_key",
help=f"The OpenAI API key to use for various OpenAI operations. Must either be passed in as an argument or set {set_openai_help_str(is_parent=True)}",
)
bot_cmd_optional_named.add_argument(
"--sync",
action="store_true",
required=False,
dest="sync",
help="Sync discord commands gloablly on start up",
help="Sync Discord commands globally on start up",
)


Expand All @@ -25,15 +45,15 @@ def setup_add_bot_command(bot_cmd_commands_subcommand):
add_cmd_optional_named = add_cmd.add_argument_group("optional named arguments")

add_cmd_required_named.add_argument(
"-n",
"-c",
"--command-name",
type=str,
required=True,
dest="command_name",
help="The name you want to use for the command",
)
add_cmd_required_named.add_argument(
"-i",
"-m",
"--model-id",
type=str,
required=True,
Expand Down Expand Up @@ -76,7 +96,7 @@ def setup_add_bot_command(bot_cmd_commands_subcommand):
help="The default frequency penalty to use for completions: DEFAULT=0",
)
add_cmd_optional_named.add_argument(
"-m",
"-n",
"--max-tokens-default",
type=int,
default=125,
Expand Down Expand Up @@ -109,7 +129,7 @@ def setup_delete_bot_command(bot_cmd_commands_subcommand):
)

delete_cmd_required_named.add_argument(
"-n",
"-c",
"--command-name",
type=str,
required=True,
Expand Down
Loading