Skip to content

Refactor monolithic bot into modular cog system with hot-reloading capabilities#3

Draft
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-76c89549-fafc-42cc-b05a-17d85778ceba
Draft

Refactor monolithic bot into modular cog system with hot-reloading capabilities#3
Copilot wants to merge 3 commits intomasterfrom
copilot/fix-76c89549-fafc-42cc-b05a-17d85778ceba

Conversation

Copy link
Copy Markdown

Copilot AI commented Sep 24, 2025

This PR completely restructures the 7xBot from a monolithic 1954-line file into a modular cog system that enables runtime reloading and selective feature toggling without requiring full bot restarts.

Problem Solved

The original 7xbot.py was a single massive file that required restarting the entire Python process for any code changes or bug fixes. This caused downtime and made development difficult, especially when testing changes or temporarily disabling problematic features.

Solution Overview

New Architecture

  • bot_main.py: New modular entry point with cog management system
  • cogs/: Organized modules for different bot functionality
  • restart_bot.sh: External monitoring script for emergency full restarts
  • Comprehensive documentation: Setup guides, migration instructions, and examples

Cog Organization

  • admin.py: Owner commands (shutdown, eval, repl, debug)
  • utility.py: Basic commands (tc, echo, man, beta management)
  • points.py: Points system and shop functionality
  • events.py: Event handlers (on_ready, on_message, status rotation)
  • database.py: Shared database utilities
  • Placeholder cogs: Structure ready for AI, moderation, and channel management

New Management Commands

7/load_cog <name>      # Load a cog
7/unload_cog <name>    # Unload a cog  
7/reload_cog <name>    # Hot-reload a cog (zero downtime!)
7/list_cogs            # Show loaded cogs
7/restart_bot          # Emergency full restart

Key Benefits

For Development

  • Hot-reloading: Fix bugs and test changes without bot downtime using 7/reload_cog
  • Isolated development: Work on individual components without affecting others
  • Better organization: Related functionality grouped into logical modules

For Production

  • Zero-downtime updates: Most bug fixes can be applied instantly
  • Feature toggles: Disable problematic features immediately with 7/unload_cog
  • Emergency restart: Full process restart capability via external monitoring script
  • Improved stability: Issues in one cog don't crash the entire bot

Example Workflow

# Developer makes changes to admin.py
# Test instantly without downtime:
7/reload_cog admin

# Temporarily disable AI if it's causing issues:
7/unload_cog ai

# Re-enable when fixed:
7/load_cog ai

# Emergency full restart if needed:
7/restart_bot

Backward Compatibility

The original 7xbot.py file is preserved unchanged as a backup. All existing commands continue to function identically, but now benefit from the modular architecture.

Files Added/Modified

  • Added: bot_main.py - New modular bot entry point
  • Added: cogs/ directory with 7 cog modules
  • Added: restart_bot.sh - External restart monitoring
  • Added: start_bot.sh - Convenient startup script
  • Added: .env.example - Environment configuration template
  • Added: Documentation files with setup and migration guides
  • Modified: .gitignore - Added restart files and environment config

Testing

Includes demo_cog_system.py that demonstrates all functionality without requiring Discord credentials, and test_cogs.py for development testing.

This transformation enables the bot to be "effectively rebooted" in portions as requested, while also providing the backup full restart capability via the external shell script monitoring system.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: UN7X <163171152+UN7X@users.noreply.github.com>
Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New security issues found

try:
# Attempt to compile and evaluate as an expression.
code_obj = compile(code_str, "<stdin>", "eval")
result = eval(code_obj, globals())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

code_obj = compile(code_str, "<stdin>", "exec")
with io.StringIO() as buffer:
with contextlib.redirect_stdout(buffer):
exec(code_obj, globals())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

try:
# First, try to compile as an expression.
compiled = compile(code, "<eval>", "eval")
result = eval(compiled, global_env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

compiled = compile(code, "<exec>", "exec")
with io.StringIO() as buffer:
with contextlib.redirect_stdout(buffer):
exec(compiled, global_env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

try:
# try expression first, then statements
compiled = compile(src, "<repl>", "eval")
result = eval(compiled, env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

result = await result
except SyntaxError:
compiled = compile(src, "<repl>", "exec")
exec(compiled, env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New security issues found

try:
# Attempt to compile and evaluate as an expression.
code_obj = compile(code_str, "<stdin>", "eval")
result = eval(code_obj, globals())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

code_obj = compile(code_str, "<stdin>", "exec")
with io.StringIO() as buffer:
with contextlib.redirect_stdout(buffer):
exec(code_obj, globals())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

try:
# First, try to compile as an expression.
compiled = compile(code, "<eval>", "eval")
result = eval(compiled, global_env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

compiled = compile(code, "<exec>", "exec")
with io.StringIO() as buffer:
with contextlib.redirect_stdout(buffer):
exec(compiled, global_env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

try:
# try expression first, then statements
compiled = compile(src, "<repl>", "eval")
result = eval(compiled, env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.eval-detected): Detected the use of eval(). eval() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

result = await result
except SyntaxError:
compiled = compile(src, "<repl>", "exec")
exec(compiled, env)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security (python.lang.security.audit.exec-detected): Detected the use of exec(). exec() can be dangerous if used to evaluate dynamic content. If this content can be input from outside the program, this may be a code injection vulnerability. Ensure evaluated content is not definable by external sources.

Source: opengrep

Co-authored-by: UN7X <163171152+UN7X@users.noreply.github.com>
Copilot AI changed the title [WIP] Split up the monolithic file into cogs that can be reloaded and toggled off and on with commands on run time, to effectively reboot certain portions of the bot, without having to rerun the python command everytime. Also, make a back up reboot command t... Refactor monolithic bot into modular cog system with hot-reloading capabilities Sep 24, 2025
Copilot AI requested a review from UN7X September 24, 2025 17:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants