From 6f24c1c30fc80e15a3fc798c69e822860b95f52e Mon Sep 17 00:00:00 2001 From: A-Baji Date: Mon, 1 Jul 2024 20:05:07 -0500 Subject: [PATCH 1/4] update bot driver and cli commands --- discordai/bot/__init__.py | 95 ++++++++++++++------------ discordai/command_line/command_line.py | 10 +-- discordai/command_line/subparsers.py | 32 +++++++-- 3 files changed, 84 insertions(+), 53 deletions(-) diff --git a/discordai/bot/__init__.py b/discordai/bot/__init__.py index 07185c3..76a33bf 100644 --- a/discordai/bot/__init__.py +++ b/discordai/bot/__init__.py @@ -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 = {} @@ -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: @@ -91,23 +95,25 @@ 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): @@ -115,7 +121,7 @@ async def on_command_error(context: Context, error) -> None: 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 @@ -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) + cogs_path.mkdir(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) diff --git a/discordai/command_line/command_line.py b/discordai/command_line/command_line.py index 7349f81..17ec20e 100644 --- a/discordai/command_line/command_line.py +++ b/discordai/command_line/command_line.py @@ -45,18 +45,18 @@ 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": @@ -64,7 +64,7 @@ def discordai(): 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( @@ -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) diff --git a/discordai/command_line/subparsers.py b/discordai/command_line/subparsers.py index 2e25844..ed37aa7 100644 --- a/discordai/command_line/subparsers.py +++ b/discordai/command_line/subparsers.py @@ -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", ) @@ -25,7 +45,7 @@ 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, @@ -33,7 +53,7 @@ def setup_add_bot_command(bot_cmd_commands_subcommand): help="The name you want to use for the command", ) add_cmd_required_named.add_argument( - "-i", + "-m", "--model-id", type=str, required=True, @@ -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, @@ -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, From 47526395d45492923830cc86a8b85d3d8afd293a Mon Sep 17 00:00:00 2001 From: A-Baji Date: Mon, 1 Jul 2024 20:18:10 -0500 Subject: [PATCH 2/4] add better_profanity hidden import --- .github/workflows/package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 78f3393..21e496e 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -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 --hidden-import=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 --hidden-import=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 --hidden-import=better_profanity --collect-data=discordai_modelizer zip -j discordai-linux.zip dist/*discordai* chmod +x dist/*discordai* # Upload From ad39b4534cdfa9e488538854ab9272fcb5a74f7c Mon Sep 17 00:00:00 2001 From: A-Baji Date: Mon, 1 Jul 2024 20:22:06 -0500 Subject: [PATCH 3/4] collect data --- .github/workflows/package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 21e496e..388d38b 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -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 --hidden-import=better_profanity --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=better_profanity --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 --hidden-import=better_profanity --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 From 1f99439fee30362e769174de8cef3314db9a245d Mon Sep 17 00:00:00 2001 From: A-Baji Date: Mon, 1 Jul 2024 22:26:48 -0500 Subject: [PATCH 4/4] revert to makedirs --- discordai/bot/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/discordai/bot/__init__.py b/discordai/bot/__init__.py index 76a33bf..0a3f599 100644 --- a/discordai/bot/__init__.py +++ b/discordai/bot/__init__.py @@ -140,7 +140,7 @@ async def load_cogs() -> None: ) data_dir = pathlib.Path(sys._MEIPASS) og_cogs_path = data_dir / "discordai" / "bot" / "cogs" - cogs_path.mkdir(exist_ok=True) + 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)