Refactor module layout of command classes (#4706)

pull/4708/head
Erik Peterson 2023-06-15 11:34:41 -07:00 committed by GitHub
parent f0a5250da5
commit 195a7fcad8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 117 additions and 106 deletions

View File

@ -5,7 +5,6 @@ from datetime import datetime
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
@ -24,6 +23,7 @@ from autogpt.log_cycle.log_cycle import (
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

View File

@ -4,8 +4,9 @@ from typing import Dict, List, Union
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

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@ import json
import requests
from autogpt.agent.agent import Agent
from autogpt.commands.command import command
from autogpt.command_decorator import command
@command(

View File

@ -7,7 +7,7 @@ import docker
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

View File

@ -13,7 +13,7 @@ from confection import Config
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

View File

@ -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

View File

@ -8,7 +8,7 @@ from itertools import islice
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

View File

@ -10,7 +10,7 @@ import requests
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

View File

@ -3,7 +3,7 @@ from __future__ import annotations
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

View File

@ -4,7 +4,7 @@ from __future__ import annotations
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

View File

@ -28,7 +28,7 @@ from webdriver_manager.firefox import GeckoDriverManager
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

View File

@ -4,7 +4,7 @@ from __future__ import annotations
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

View File

@ -13,7 +13,7 @@ import distro
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)

View File

@ -6,11 +6,11 @@ from pathlib import Path
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 (

View File

41
autogpt/models/command.py Normal file
View File

@ -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}"

View File

@ -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:
@ -133,45 +92,3 @@ class CommandRegistry:
):
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

View File

@ -4,7 +4,7 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional
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:

View File

@ -7,12 +7,12 @@ import yaml
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

View File

@ -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

View File

@ -1,4 +1,4 @@
from autogpt.commands.command import command
from autogpt.command_decorator import command
@command(

View File

@ -5,7 +5,8 @@ from pathlib import Path
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"