Skip to content

Commit

Permalink
Refactor module layout of command classes
Browse files Browse the repository at this point in the history
  • Loading branch information
erik-megarad committed Jun 15, 2023
1 parent f0a5250 commit 6470e44
Show file tree
Hide file tree
Showing 24 changed files with 117 additions and 106 deletions.
2 changes: 1 addition & 1 deletion autogpt/agent/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from colorama import Fore, Style

from autogpt.commands.command import CommandRegistry
from autogpt.config import Config
from autogpt.config.ai_config import AIConfig
from autogpt.json_utils.utilities import extract_json_from_response, validate_json
Expand All @@ -24,6 +23,7 @@
from autogpt.logs import logger, print_assistant_thoughts
from autogpt.memory.message_history import MessageHistory
from autogpt.memory.vector import VectorMemory
from autogpt.models.command_registry import CommandRegistry
from autogpt.speech import say_text
from autogpt.spinner import Spinner
from autogpt.utils import clean_input
Expand Down
3 changes: 2 additions & 1 deletion autogpt/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

from autogpt.agent.agent import Agent
from autogpt.agent.agent_manager import AgentManager
from autogpt.commands.command import CommandRegistry, command
from autogpt.command_decorator import command
from autogpt.commands.web_requests import scrape_links, scrape_text
from autogpt.models.command_registry import CommandRegistry
from autogpt.processing.text import summarize_text
from autogpt.speech import say_text
from autogpt.url_utils.validators import validate_url
Expand Down
51 changes: 51 additions & 0 deletions autogpt/command_decorator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import functools
from typing import Any, Callable, Optional

from autogpt.config import Config
from autogpt.logs import logger
from autogpt.models.command import Command

# Unique identifier for auto-gpt commands
AUTO_GPT_COMMAND_IDENTIFIER = "auto_gpt_command"


def command(
name: str,
description: str,
signature: str,
enabled: bool | Callable[[Config], bool] = True,
disabled_reason: Optional[str] = None,
) -> Callable[..., Any]:
"""The command decorator is used to create Command objects from ordinary functions."""

# TODO: Remove this in favor of better command management
CFG = Config()

if callable(enabled):
enabled = enabled(CFG)
if not enabled:
if disabled_reason is not None:
logger.debug(f"Command '{name}' is disabled: {disabled_reason}")
return lambda func: func

def decorator(func: Callable[..., Any]) -> Command:
cmd = Command(
name=name,
description=description,
method=func,
signature=signature,
enabled=enabled,
disabled_reason=disabled_reason,
)

@functools.wraps(func)
def wrapper(*args, **kwargs) -> Any:
return func(*args, **kwargs)

wrapper.command = cmd

setattr(wrapper, AUTO_GPT_COMMAND_IDENTIFIER, True)

return wrapper

return decorator
2 changes: 1 addition & 1 deletion autogpt/commands/analyze_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from __future__ import annotations

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.llm.utils import call_ai_function


Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/audio_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import requests

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command


@command(
Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/execute_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from docker.errors import ImageNotFound

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.config import Config
from autogpt.logs import logger
from autogpt.setup import CFG
Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/file_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from requests.adapters import HTTPAdapter, Retry

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.commands.file_operations_utils import read_textual_file
from autogpt.logs import logger
from autogpt.memory.vector import MemoryItem, VectorMemory
Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/git_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from git.repo import Repo

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.url_utils.validators import validate_url


Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/google_search.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from duckduckgo_search import DDGS

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command

DUCKDUCKGO_MAX_ATTEMPTS = 3

Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/image_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from PIL import Image

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.logs import logger


Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/improve_code.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import json

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.llm.utils import call_ai_function


Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/task_statuses.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from typing import NoReturn

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.logs import logger


Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/web_selenium.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from webdriver_manager.microsoft import EdgeChromiumDriverManager as EdgeDriverManager

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.logs import logger
from autogpt.memory.vector import MemoryItem, get_memory
from autogpt.processing.html import extract_hyperlinks, format_hyperlinks
Expand Down
2 changes: 1 addition & 1 deletion autogpt/commands/write_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import json

from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
from autogpt.llm.utils import call_ai_function


Expand Down
2 changes: 1 addition & 1 deletion autogpt/config/ai_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import yaml

if TYPE_CHECKING:
from autogpt.commands.command import CommandRegistry
from autogpt.models.command_registry import CommandRegistry
from autogpt.prompts.generator import PromptGenerator

# Soon this will go in a folder where it remembers more stuff about the run(s)
Expand Down
2 changes: 1 addition & 1 deletion autogpt/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
from colorama import Fore, Style

from autogpt.agent import Agent
from autogpt.commands.command import CommandRegistry
from autogpt.config import Config, check_openai_api_key
from autogpt.configurator import create_config
from autogpt.logs import logger
from autogpt.memory.vector import get_memory
from autogpt.models.command_registry import CommandRegistry
from autogpt.plugins import scan_plugins
from autogpt.prompts.prompt import DEFAULT_TRIGGERING_PROMPT, construct_main_ai_config
from autogpt.utils import (
Expand Down
Empty file added autogpt/models/__init__.py
Empty file.
41 changes: 41 additions & 0 deletions autogpt/models/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from typing import Any, Callable, Optional

from autogpt.config import Config


class Command:
"""A class representing a command.
Attributes:
name (str): The name of the command.
description (str): A brief description of what the command does.
signature (str): The signature of the function that the command executes. Defaults to None.
"""

def __init__(
self,
name: str,
description: str,
method: Callable[..., Any],
signature: str = "",
enabled: bool | Callable[[Config], bool] = True,
disabled_reason: Optional[str] = None,
):
self.name = name
self.description = description
self.method = method
self.signature = signature
self.enabled = enabled
self.disabled_reason = disabled_reason

def __call__(self, *args, **kwargs) -> Any:
if hasattr(kwargs, "config") and callable(self.enabled):
self.enabled = self.enabled(kwargs["config"])
if not self.enabled:
if self.disabled_reason:
return f"Command '{self.name}' is disabled: {self.disabled_reason}"
return f"Command '{self.name}' is disabled"
return self.method(*args, **kwargs)

def __str__(self) -> str:
return f"{self.name}: {self.description}, args: {self.signature}"
89 changes: 3 additions & 86 deletions autogpt/commands/command.py → autogpt/models/command_registry.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,10 @@
import functools
import importlib
import inspect
from typing import Any, Callable, Optional
from typing import Any, Callable

from autogpt.config import Config
from autogpt.command_decorator import AUTO_GPT_COMMAND_IDENTIFIER
from autogpt.logs import logger

# Unique identifier for auto-gpt commands
AUTO_GPT_COMMAND_IDENTIFIER = "auto_gpt_command"


class Command:
"""A class representing a command.
Attributes:
name (str): The name of the command.
description (str): A brief description of what the command does.
signature (str): The signature of the function that the command executes. Defaults to None.
"""

def __init__(
self,
name: str,
description: str,
method: Callable[..., Any],
signature: str = "",
enabled: bool | Callable[[Config], bool] = True,
disabled_reason: Optional[str] = None,
):
self.name = name
self.description = description
self.method = method
self.signature = signature
self.enabled = enabled
self.disabled_reason = disabled_reason

def __call__(self, *args, **kwargs) -> Any:
if hasattr(kwargs, "config") and callable(self.enabled):
self.enabled = self.enabled(kwargs["config"])
if not self.enabled:
if self.disabled_reason:
return f"Command '{self.name}' is disabled: {self.disabled_reason}"
return f"Command '{self.name}' is disabled"
return self.method(*args, **kwargs)

def __str__(self) -> str:
return f"{self.name}: {self.description}, args: {self.signature}"
from autogpt.models.command import Command


class CommandRegistry:
Expand Down Expand Up @@ -133,45 +92,3 @@ def import_commands(self, module_name: str) -> None:
):
cmd_instance = attr()
self.register(cmd_instance)


def command(
name: str,
description: str,
signature: str,
enabled: bool | Callable[[Config], bool] = True,
disabled_reason: Optional[str] = None,
) -> Callable[..., Any]:
"""The command decorator is used to create Command objects from ordinary functions."""

# TODO: Remove this in favor of better command management
CFG = Config()

if callable(enabled):
enabled = enabled(CFG)
if not enabled:
if disabled_reason is not None:
logger.debug(f"Command '{name}' is disabled: {disabled_reason}")
return lambda func: func

def decorator(func: Callable[..., Any]) -> Command:
cmd = Command(
name=name,
description=description,
method=func,
signature=signature,
enabled=enabled,
disabled_reason=disabled_reason,
)

@functools.wraps(func)
def wrapper(*args, **kwargs) -> Any:
return func(*args, **kwargs)

wrapper.command = cmd

setattr(wrapper, AUTO_GPT_COMMAND_IDENTIFIER, True)

return wrapper

return decorator
2 changes: 1 addition & 1 deletion autogpt/prompts/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from autogpt.json_utils.utilities import llm_response_schema

if TYPE_CHECKING:
from autogpt.commands.command import CommandRegistry
from autogpt.models.command_registry import CommandRegistry


class PromptGenerator:
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from pytest_mock import MockerFixture

from autogpt.agent.agent import Agent
from autogpt.commands.command import CommandRegistry
from autogpt.config.ai_config import AIConfig
from autogpt.config.config import Config
from autogpt.llm.api_manager import ApiManager
from autogpt.logs import TypingConsoleHandler
from autogpt.memory.vector import get_memory
from autogpt.models.command_registry import CommandRegistry
from autogpt.prompts.prompt import DEFAULT_TRIGGERING_PROMPT
from autogpt.workspace import Workspace

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/agent_factory.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import pytest

from autogpt.agent import Agent
from autogpt.commands.command import CommandRegistry
from autogpt.config import AIConfig, Config
from autogpt.main import COMMAND_CATEGORIES
from autogpt.memory.vector import NoMemory, get_memory
from autogpt.models.command_registry import CommandRegistry
from autogpt.prompts.prompt import DEFAULT_TRIGGERING_PROMPT
from autogpt.workspace import Workspace

Expand Down
2 changes: 1 addition & 1 deletion tests/mocks/mock_commands.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from autogpt.commands.command import command
from autogpt.command_decorator import command


@command(
Expand Down
3 changes: 2 additions & 1 deletion tests/unit/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

import pytest

from autogpt.commands.command import Command, CommandRegistry
from autogpt.models.command import Command
from autogpt.models.command_registry import CommandRegistry

SIGNATURE = "(arg1: int, arg2: str) -> str"

Expand Down

0 comments on commit 6470e44

Please sign in to comment.