aboutsummaryrefslogtreecommitdiff
path: root/autogpts/autogpt/autogpt/command_decorator.py
diff options
context:
space:
mode:
Diffstat (limited to 'autogpts/autogpt/autogpt/command_decorator.py')
-rw-r--r--autogpts/autogpt/autogpt/command_decorator.py70
1 files changed, 70 insertions, 0 deletions
diff --git a/autogpts/autogpt/autogpt/command_decorator.py b/autogpts/autogpt/autogpt/command_decorator.py
new file mode 100644
index 000000000..70a519a42
--- /dev/null
+++ b/autogpts/autogpt/autogpt/command_decorator.py
@@ -0,0 +1,70 @@
+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