1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
from __future__ import annotations
import functools
import inspect
from typing import TYPE_CHECKING, Any, Callable, Literal, Optional, ParamSpec, TypeVar
if TYPE_CHECKING:
from autogpt.agents.base import BaseAgent
from autogpt.config import Config
from autogpt.core.utils.json_schema import JSONSchema
from autogpt.models.command import Command, CommandOutput, CommandParameter
# Unique identifier for AutoGPT commands
AUTO_GPT_COMMAND_IDENTIFIER = "auto_gpt_command"
P = ParamSpec("P")
CO = TypeVar("CO", bound=CommandOutput)
def command(
name: str,
description: str,
parameters: dict[str, JSONSchema],
enabled: Literal[True] | Callable[[Config], bool] = True,
disabled_reason: Optional[str] = None,
aliases: list[str] = [],
available: Literal[True] | Callable[[BaseAgent], bool] = True,
) -> Callable[[Callable[P, CO]], Callable[P, CO]]:
"""The command decorator is used to create Command objects from ordinary functions."""
def decorator(func: Callable[P, CO]) -> Callable[P, CO]:
typed_parameters = [
CommandParameter(
name=param_name,
spec=spec,
)
for param_name, spec in parameters.items()
]
cmd = Command(
name=name,
description=description,
method=func,
parameters=typed_parameters,
enabled=enabled,
disabled_reason=disabled_reason,
aliases=aliases,
available=available,
)
if inspect.iscoroutinefunction(func):
@functools.wraps(func)
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> Any:
return await func(*args, **kwargs)
else:
@functools.wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> Any:
return func(*args, **kwargs)
setattr(wrapper, "command", cmd)
setattr(wrapper, AUTO_GPT_COMMAND_IDENTIFIER, True)
return wrapper
return decorator
|