mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2025-12-25 18:04:28 +01:00
Co-authored-by: merwanehamadi <merwanehamadi@gmail.com> Co-authored-by: Reinier van der Leer <github@pwuts.nl>
97 lines
3.4 KiB
Python
97 lines
3.4 KiB
Python
import importlib
|
|
import inspect
|
|
from typing import Any, Callable
|
|
|
|
from autogpt.command_decorator import AUTO_GPT_COMMAND_IDENTIFIER
|
|
from autogpt.logs import logger
|
|
from autogpt.models.command import Command
|
|
|
|
|
|
class CommandRegistry:
|
|
"""
|
|
The CommandRegistry class is a manager for a collection of Command objects.
|
|
It allows the registration, modification, and retrieval of Command objects,
|
|
as well as the scanning and loading of command plugins from a specified
|
|
directory.
|
|
"""
|
|
|
|
commands: dict[str, Command]
|
|
|
|
def __init__(self):
|
|
self.commands = {}
|
|
|
|
def _import_module(self, module_name: str) -> Any:
|
|
return importlib.import_module(module_name)
|
|
|
|
def _reload_module(self, module: Any) -> Any:
|
|
return importlib.reload(module)
|
|
|
|
def register(self, cmd: Command) -> None:
|
|
if cmd.name in self.commands:
|
|
logger.warn(
|
|
f"Command '{cmd.name}' already registered and will be overwritten!"
|
|
)
|
|
self.commands[cmd.name] = cmd
|
|
|
|
def unregister(self, command_name: str):
|
|
if command_name in self.commands:
|
|
del self.commands[command_name]
|
|
else:
|
|
raise KeyError(f"Command '{command_name}' not found in registry.")
|
|
|
|
def reload_commands(self) -> None:
|
|
"""Reloads all loaded command plugins."""
|
|
for cmd_name in self.commands:
|
|
cmd = self.commands[cmd_name]
|
|
module = self._import_module(cmd.__module__)
|
|
reloaded_module = self._reload_module(module)
|
|
if hasattr(reloaded_module, "register"):
|
|
reloaded_module.register(self)
|
|
|
|
def get_command(self, name: str) -> Callable[..., Any]:
|
|
return self.commands[name]
|
|
|
|
def call(self, command_name: str, **kwargs) -> Any:
|
|
if command_name not in self.commands:
|
|
raise KeyError(f"Command '{command_name}' not found in registry.")
|
|
command = self.commands[command_name]
|
|
return command(**kwargs)
|
|
|
|
def command_prompt(self) -> str:
|
|
"""
|
|
Returns a string representation of all registered `Command` objects for use in a prompt
|
|
"""
|
|
commands_list = [
|
|
f"{idx + 1}. {str(cmd)}" for idx, cmd in enumerate(self.commands.values())
|
|
]
|
|
return "\n".join(commands_list)
|
|
|
|
def import_commands(self, module_name: str) -> None:
|
|
"""
|
|
Imports the specified Python module containing command plugins.
|
|
|
|
This method imports the associated module and registers any functions or
|
|
classes that are decorated with the `AUTO_GPT_COMMAND_IDENTIFIER` attribute
|
|
as `Command` objects. The registered `Command` objects are then added to the
|
|
`commands` dictionary of the `CommandRegistry` object.
|
|
|
|
Args:
|
|
module_name (str): The name of the module to import for command plugins.
|
|
"""
|
|
|
|
module = importlib.import_module(module_name)
|
|
|
|
for attr_name in dir(module):
|
|
attr = getattr(module, attr_name)
|
|
# Register decorated functions
|
|
if hasattr(attr, AUTO_GPT_COMMAND_IDENTIFIER) and getattr(
|
|
attr, AUTO_GPT_COMMAND_IDENTIFIER
|
|
):
|
|
self.register(attr.command)
|
|
# Register command classes
|
|
elif (
|
|
inspect.isclass(attr) and issubclass(attr, Command) and attr != Command
|
|
):
|
|
cmd_instance = attr()
|
|
self.register(cmd_instance)
|