121 lines
3.2 KiB
Python
121 lines
3.2 KiB
Python
"""
|
|
=========
|
|
Workspace
|
|
=========
|
|
|
|
The workspace is a directory containing configuration and working files for an AutoGPT
|
|
agent.
|
|
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
class Workspace:
|
|
"""A class that represents a workspace for an AutoGPT agent."""
|
|
|
|
def __init__(self, workspace_root: str | Path, restrict_to_workspace: bool):
|
|
self._root = self._sanitize_path(workspace_root)
|
|
self._restrict_to_workspace = restrict_to_workspace
|
|
|
|
@property
|
|
def root(self) -> Path:
|
|
"""The root directory of the workspace."""
|
|
return self._root
|
|
|
|
@property
|
|
def restrict_to_workspace(self):
|
|
"""Whether to restrict generated paths to the workspace."""
|
|
return self._restrict_to_workspace
|
|
|
|
@classmethod
|
|
def make_workspace(cls, workspace_directory: str | Path, *args, **kwargs) -> Path:
|
|
"""Create a workspace directory and return the path to it.
|
|
|
|
Parameters
|
|
----------
|
|
workspace_directory
|
|
The path to the workspace directory.
|
|
|
|
Returns
|
|
-------
|
|
Path
|
|
The path to the workspace directory.
|
|
|
|
"""
|
|
# TODO: have this make the env file and ai settings file in the directory.
|
|
workspace_directory = cls._sanitize_path(workspace_directory)
|
|
workspace_directory.mkdir(exist_ok=True, parents=True)
|
|
return workspace_directory
|
|
|
|
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,
|
|
)
|
|
|
|
@staticmethod
|
|
def _sanitize_path(
|
|
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.
|
|
|
|
"""
|
|
|
|
if root is None:
|
|
return Path(relative_path).resolve()
|
|
|
|
root, relative_path = Path(root), Path(relative_path)
|
|
|
|
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()
|
|
|
|
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
|