mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2025-12-29 20:04:30 +01:00
Rough sketching out of a hello world using our refactored autogpt library. See the tracking issue here: #4770. # Run instructions There are two client applications for Auto-GPT included. ## CLI Application 🌟 **This is the reference application I'm working with for now** 🌟 The first app is a straight CLI application. I have not done anything yet to port all the friendly display stuff from the `logger.typewriter_log` logic. - [Entry Point](https://github.com/Significant-Gravitas/Auto-GPT/blob/re-arch/hello-world/autogpt/core/runner/cli_app/cli.py) - [Client Application](https://github.com/Significant-Gravitas/Auto-GPT/blob/re-arch/hello-world/autogpt/core/runner/cli_app/main.py) To run, you first need a settings file. Run ``` python REPOSITORY_ROOT/autogpt/core/runner/cli_app/cli.py make-settings ``` where `REPOSITORY_ROOT` is the root of the Auto-GPT repository on your machine. This will write a file called `default_agent_settings.yaml` with all the user-modifiable configuration keys to `~/auto-gpt/default_agent_settings.yml` and make the `auto-gpt` directory in your user directory if it doesn't exist). At a bare minimum, you'll need to set `openai.credentials.api_key` to your OpenAI API Key to run the model. You can then run Auto-GPT with ``` python REPOSITORY_ROOT/autogpt/core/runner/cli_app/cli.py make-settings ``` to launch the interaction loop. ## CLI Web App The second app is still a CLI, but it sets up a local webserver that the client application talks to rather than invoking calls to the Agent library code directly. This application is essentially a sketch at this point as the folks who were driving it have had less time (and likely not enough clarity) to proceed. - [Entry Point](https://github.com/Significant-Gravitas/Auto-GPT/blob/re-arch/hello-world/autogpt/core/runner/cli_web_app/cli.py) - [Client Application](https://github.com/Significant-Gravitas/Auto-GPT/blob/re-arch/hello-world/autogpt/core/runner/cli_web_app/client/client.py) - [Server API](https://github.com/Significant-Gravitas/Auto-GPT/blob/re-arch/hello-world/autogpt/core/runner/cli_web_app/server/api.py) To run, you still need to generate a default configuration. You can do ``` python REPOSITORY_ROOT/autogpt/core/runner/cli_web_app/cli.py make-settings ``` It invokes the same command as the bare CLI app, so follow the instructions above about setting your API key. To run, do ``` python REPOSITORY_ROOT/autogpt/core/runner/cli_web_app/cli.py client ``` This will launch a webserver and then start the client cli application to communicate with it. ⚠️ I am not actively developing this application. It is a very good place to get involved if you have web application design experience and are looking to get involved in the re-arch. --------- Co-authored-by: David Wurtz <davidjwurtz@gmail.com> Co-authored-by: Media <12145726+rihp@users.noreply.github.com> Co-authored-by: Richard Beales <rich@richbeales.net> Co-authored-by: Daryl Rodrigo <darylrodrigo@gmail.com> Co-authored-by: Daryl Rodrigo <daryl@orkestro.com> Co-authored-by: Swifty <craigswift13@gmail.com> Co-authored-by: Nicholas Tindle <nick@ntindle.com> Co-authored-by: Merwane Hamadi <merwanehamadi@gmail.com>
194 lines
5.6 KiB
Python
194 lines
5.6 KiB
Python
import json
|
|
import logging
|
|
import typing
|
|
from pathlib import Path
|
|
|
|
from pydantic import SecretField
|
|
|
|
from autogpt.core.configuration import (
|
|
Configurable,
|
|
SystemConfiguration,
|
|
SystemSettings,
|
|
UserConfigurable,
|
|
)
|
|
from autogpt.core.workspace.base import Workspace
|
|
|
|
if typing.TYPE_CHECKING:
|
|
# Cyclic import
|
|
from autogpt.core.agent.simple import AgentSettings
|
|
|
|
|
|
class WorkspaceConfiguration(SystemConfiguration):
|
|
root: str
|
|
parent: str = UserConfigurable()
|
|
restrict_to_workspace: bool = UserConfigurable()
|
|
|
|
|
|
class WorkspaceSettings(SystemSettings):
|
|
configuration: WorkspaceConfiguration
|
|
|
|
|
|
class SimpleWorkspace(Configurable, Workspace):
|
|
default_settings = WorkspaceSettings(
|
|
name="workspace",
|
|
description="The workspace is the root directory for all agent activity.",
|
|
configuration=WorkspaceConfiguration(
|
|
root="",
|
|
parent="~/auto-gpt/agents",
|
|
restrict_to_workspace=True,
|
|
),
|
|
)
|
|
|
|
NULL_BYTES = ["\0", "\000", "\x00", "\u0000", "%00"]
|
|
|
|
def __init__(
|
|
self,
|
|
settings: WorkspaceSettings,
|
|
logger: logging.Logger,
|
|
):
|
|
self._configuration = settings.configuration
|
|
self._logger = logger.getChild("workspace")
|
|
|
|
@property
|
|
def root(self) -> Path:
|
|
return Path(self._configuration.root)
|
|
|
|
@property
|
|
def debug_log_path(self) -> Path:
|
|
return self.root / "logs" / "debug.log"
|
|
|
|
@property
|
|
def cycle_log_path(self) -> Path:
|
|
return self.root / "logs" / "cycle.log"
|
|
|
|
@property
|
|
def configuration_path(self) -> Path:
|
|
return self.root / "configuration.yml"
|
|
|
|
@property
|
|
def restrict_to_workspace(self) -> bool:
|
|
return self._configuration.restrict_to_workspace
|
|
|
|
def get_path(self, relative_path: str | Path) -> Path:
|
|
"""Get the full path for an item in the workspace.
|
|
|
|
Parameters
|
|
----------
|
|
relative_path
|
|
The relative path to resolve in the workspace.
|
|
|
|
Returns
|
|
-------
|
|
Path
|
|
The resolved path relative to the workspace.
|
|
|
|
"""
|
|
return self._sanitize_path(
|
|
relative_path,
|
|
root=self.root,
|
|
restrict_to_root=self.restrict_to_workspace,
|
|
)
|
|
|
|
def _sanitize_path(
|
|
self,
|
|
relative_path: str | Path,
|
|
root: str | Path = None,
|
|
restrict_to_root: bool = True,
|
|
) -> Path:
|
|
"""Resolve the relative path within the given root if possible.
|
|
|
|
Parameters
|
|
----------
|
|
relative_path
|
|
The relative path to resolve.
|
|
root
|
|
The root path to resolve the relative path within.
|
|
restrict_to_root
|
|
Whether to restrict the path to the root.
|
|
|
|
Returns
|
|
-------
|
|
Path
|
|
The resolved path.
|
|
|
|
Raises
|
|
------
|
|
ValueError
|
|
If the path is absolute and a root is provided.
|
|
ValueError
|
|
If the path is outside the root and the root is restricted.
|
|
|
|
"""
|
|
|
|
# Posix systems disallow null bytes in paths. Windows is agnostic about it.
|
|
# Do an explicit check here for all sorts of null byte representations.
|
|
|
|
for null_byte in self.NULL_BYTES:
|
|
if null_byte in str(relative_path) or null_byte in str(root):
|
|
raise ValueError("embedded null byte")
|
|
|
|
if root is None:
|
|
return Path(relative_path).resolve()
|
|
|
|
self._logger.debug(f"Resolving path '{relative_path}' in workspace '{root}'")
|
|
root, relative_path = Path(root).resolve(), Path(relative_path)
|
|
self._logger.debug(f"Resolved root as '{root}'")
|
|
|
|
if relative_path.is_absolute():
|
|
raise ValueError(
|
|
f"Attempted to access absolute path '{relative_path}' in workspace '{root}'."
|
|
)
|
|
full_path = root.joinpath(relative_path).resolve()
|
|
|
|
self._logger.debug(f"Joined paths as '{full_path}'")
|
|
|
|
if restrict_to_root and not full_path.is_relative_to(root):
|
|
raise ValueError(
|
|
f"Attempted to access path '{full_path}' outside of workspace '{root}'."
|
|
)
|
|
|
|
return full_path
|
|
|
|
###################################
|
|
# Factory methods for agent setup #
|
|
###################################
|
|
|
|
@staticmethod
|
|
def setup_workspace(settings: "AgentSettings", logger: logging.Logger) -> Path:
|
|
workspace_parent = settings.workspace.configuration.parent
|
|
workspace_parent = Path(workspace_parent).expanduser().resolve()
|
|
workspace_parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
agent_name = settings.agent.name
|
|
|
|
workspace_root = workspace_parent / agent_name
|
|
workspace_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
settings.workspace.configuration.root = str(workspace_root)
|
|
|
|
with (workspace_root / "agent_settings.json").open("w") as f:
|
|
settings_json = settings.json(
|
|
encoder=lambda x: x.get_secret_value()
|
|
if isinstance(x, SecretField)
|
|
else x,
|
|
)
|
|
f.write(settings_json)
|
|
|
|
# TODO: What are all the kinds of logs we want here?
|
|
log_path = workspace_root / "logs"
|
|
log_path.mkdir(parents=True, exist_ok=True)
|
|
(log_path / "debug.log").touch()
|
|
(log_path / "cycle.log").touch()
|
|
|
|
return workspace_root
|
|
|
|
@staticmethod
|
|
def load_agent_settings(workspace_root: Path) -> "AgentSettings":
|
|
# Cyclic import
|
|
from autogpt.core.agent.simple import AgentSettings
|
|
|
|
with (workspace_root / "agent_settings.json").open("r") as f:
|
|
agent_settings = json.load(f)
|
|
|
|
return AgentSettings.parse_obj(agent_settings)
|