diff --git a/autogen/coding/docker_commandline_code_executor.py b/autogen/coding/docker_commandline_code_executor.py index 143b241c2cf..0828786a64f 100644 --- a/autogen/coding/docker_commandline_code_executor.py +++ b/autogen/coding/docker_commandline_code_executor.py @@ -45,6 +45,7 @@ def __init__( container_name: Optional[str] = None, timeout: int = 60, work_dir: Union[Path, str] = Path("."), + bind_dir: Optional[Union[Path, str]] = None, auto_remove: bool = True, stop_container: bool = True, ): @@ -67,6 +68,9 @@ def __init__( timeout (int, optional): The timeout for code execution. Defaults to 60. work_dir (Union[Path, str], optional): The working directory for the code execution. Defaults to Path("."). + bind_dir (Union[Path, str], optional): The directory that will be bound + to the code executor container. Useful for cases where you want to spawn + the container from within a container. Defaults to work_dir. auto_remove (bool, optional): If true, will automatically remove the Docker container when it is stopped. Defaults to True. stop_container (bool, optional): If true, will automatically stop the @@ -85,6 +89,11 @@ def __init__( work_dir.mkdir(exist_ok=True) + if bind_dir is None: + bind_dir = work_dir + elif isinstance(bind_dir, str): + bind_dir = Path(bind_dir) + client = docker.from_env() # Check if the image exists @@ -105,7 +114,7 @@ def __init__( entrypoint="/bin/sh", tty=True, auto_remove=auto_remove, - volumes={str(work_dir.resolve()): {"bind": "/workspace", "mode": "rw"}}, + volumes={str(bind_dir.resolve()): {"bind": "/workspace", "mode": "rw"}}, working_dir="/workspace", ) self._container.start() @@ -132,6 +141,7 @@ def cleanup() -> None: self._timeout = timeout self._work_dir: Path = work_dir + self._bind_dir: Path = bind_dir @property def timeout(self) -> int: @@ -143,6 +153,11 @@ def work_dir(self) -> Path: """(Experimental) The working directory for the code execution.""" return self._work_dir + @property + def bind_dir(self) -> Path: + """(Experimental) The binding directory for the code execution container.""" + return self._bind_dir + @property def code_extractor(self) -> CodeExtractor: """(Experimental) Export a code extractor that can be used by an agent.""" diff --git a/website/docs/topics/code-execution/cli-code-executor.ipynb b/website/docs/topics/code-execution/cli-code-executor.ipynb index d8b45bfe6a0..69df79754d0 100644 --- a/website/docs/topics/code-execution/cli-code-executor.ipynb +++ b/website/docs/topics/code-execution/cli-code-executor.ipynb @@ -73,7 +73,9 @@ "-v /var/run/docker.sock:/var/run/docker.sock\n", "```\n", "\n", - "This will allow the AutoGen container to spawn and control sibling containers on the host." + "This will allow the AutoGen container to spawn and control sibling containers on the host.\n", + "\n", + "If you need to bind a working directory to the AutoGen container but the directory belongs to your host machine, use the `bind_dir` parameter. This will allow the main AutoGen container to bind the *host* directory to the new spawned containers and allow it to access the files within the said directory. If the `bind_dir` is not specified, it will fallback to `work_dir`." ] }, {