From 3fe7894966cb0cbad81ff7cb6470ff5bbc454978 Mon Sep 17 00:00:00 2001 From: Robert Brennan Date: Tue, 20 Aug 2024 19:57:48 -0400 Subject: [PATCH] update docs for headless mode (#3508) * update docs for headless mode * fix newline * fix command parsing * add docs * Update README.md * Update headless-mode.md * empty commit * update integration tests --------- Co-authored-by: tobitege <10787084+tobitege@users.noreply.github.com> Co-authored-by: Xingyao Wang --- README.md | 2 +- containers/app/entrypoint.sh | 2 +- docs/modules/usage/how-to/headless-mode.md | 41 +++++++++++++++++++ .../test_ipython_module/prompt_002.log | 2 +- .../test_ipython_module/prompt_003.log | 2 +- .../test_ipython_module/prompt_004.log | 2 +- .../test_ipython_module/prompt_002.log | 4 +- .../test_ipython_module/prompt_003.log | 4 +- .../test_ipython_module/prompt_004.log | 4 +- 9 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 docs/modules/usage/how-to/headless-mode.md diff --git a/README.md b/README.md index a92f910523..4c06456cef 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ docker run -it \ ``` > [!NOTE] -> By default, this command pulls the `latest` tag, which represents the most recent release of OpenHands. You have other options as well: +> This command pulls the `0.8` tag, which represents the most recent stable release of OpenHands. You have other options as well: > - For a specific release version, use `ghcr.io/all-hands-ai/openhands:` (replace with the desired version number). > - For the most up-to-date development version, use `ghcr.io/all-hands-ai/openhands:main`. This version may be **(unstable!)** and is recommended for testing or development purposes only. > diff --git a/containers/app/entrypoint.sh b/containers/app/entrypoint.sh index bda45a5978..9b74d628dd 100644 --- a/containers/app/entrypoint.sh +++ b/containers/app/entrypoint.sh @@ -60,5 +60,5 @@ else usermod -aG $DOCKER_SOCKET_GID enduser echo "Running as enduser" - su enduser /bin/bash -c "$*" + su enduser /bin/bash -c "${*@Q}" # This magically runs any arguments passed to the script as a command fi diff --git a/docs/modules/usage/how-to/headless-mode.md b/docs/modules/usage/how-to/headless-mode.md new file mode 100644 index 0000000000..ce045dfdd3 --- /dev/null +++ b/docs/modules/usage/how-to/headless-mode.md @@ -0,0 +1,41 @@ +# Running in Headless Mode + +You can run OpenHands via a CLI, without starting the web application. This makes it easy +to automate tasks with OpenHands. + +## With Python +To run OpenHands in headless mode with Python, +[follow the Development setup instructions](https://github.com/All-Hands-AI/OpenHands/blob/main/Development.md), +and then run: + +```bash +poetry run python -m openhands.core.main -t "write a bash script that prints hi" +``` + +## With Docker +To run OpenHands in headless mode with Docker, run: + +```bash +# Set WORKSPACE_BASE to the directory you want OpenHands to edit +WORKSPACE_BASE=$(pwd)/workspace + +# Set LLM_API_KEY to an API key, e.g. for OpenAI or Anthropic +LLM_API_KEY="abcde" + +# Set LLM_MODEL to the model you want to use +LLM_MODEL="gpt-4o" + +docker run -it \ + --pull=always \ + -e SANDBOX_USER_ID=$(id -u) \ + -e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \ + -e LLM_API_KEY=$LLM_API_KEY \ + -e LLM_MODEL=$LLM_MODEL \ + -v $WORKSPACE_BASE:/opt/workspace_base \ + -v /var/run/docker.sock:/var/run/docker.sock \ + --add-host host.docker.internal:host-gateway \ + --name openhands-app-$(date +%Y%m%d%H%M%S) \ + ghcr.io/all-hands-ai/openhands:main \ # TODO: pin a version here + python -m openhands.core.main \ + -t "Write a bash script that prints Hello World" +``` diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log index eb2305faa1..b63b43f5e7 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_002.log @@ -415,7 +415,7 @@ Collecting pymsgbox==1.0.9 [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=10124432a16b7de8a901b653e237d2051d1f2cad56ede4efef1e8fe5847dad43 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=aca10c2c34795d92bcf85b43c34a0f7eb39d1cf3a4edf8f69f65ed206619ae51 Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log index 440aa5b2bb..2d37e60bdc 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_003.log @@ -415,7 +415,7 @@ Collecting pymsgbox==1.0.9 [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=10124432a16b7de8a901b653e237d2051d1f2cad56ede4efef1e8fe5847dad43 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=aca10c2c34795d92bcf85b43c34a0f7eb39d1cf3a4edf8f69f65ed206619ae51 Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox diff --git a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log index 625aac9148..15f9fcaf41 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log +++ b/tests/integration/mock/eventstream_runtime/CodeActAgent/test_ipython_module/prompt_004.log @@ -415,7 +415,7 @@ Collecting pymsgbox==1.0.9 [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=10124432a16b7de8a901b653e237d2051d1f2cad56ede4efef1e8fe5847dad43 +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=aca10c2c34795d92bcf85b43c34a0f7eb39d1cf3a4edf8f69f65ed206619ae51 Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log index bddaa6a359..4064f3602a 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_002.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | done + Installing build dependencies ... [?25l- \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=be36b3efa774cde835b0dd6e5839825cbb4dfe740798f5be111a0ade675d35dd +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=65f1e9e680d728456ab0dc9e66affd01d7ade89ec5a2a8c3aa80ab24a71247ac Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log index f9f9f62a2a..47b0ce5adf 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_003.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | done + Installing build dependencies ... [?25l- \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=be36b3efa774cde835b0dd6e5839825cbb4dfe740798f5be111a0ade675d35dd +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=65f1e9e680d728456ab0dc9e66affd01d7ade89ec5a2a8c3aa80ab24a71247ac Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox diff --git a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log index 7dfc061b92..7ebb442b3c 100644 --- a/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log +++ b/tests/integration/mock/eventstream_runtime/CodeActSWEAgent/test_ipython_module/prompt_004.log @@ -603,12 +603,12 @@ Understood. Let's start by installing the `pymsgbox` package. OBSERVATION: Collecting pymsgbox==1.0.9 Downloading PyMsgBox-1.0.9.tar.gz (18 kB) - Installing build dependencies ... [?25l- \ | / - \ | done + Installing build dependencies ... [?25l- \ | / - done [?25h Getting requirements to build wheel ... [?25l- done [?25h Preparing metadata (pyproject.toml) ... [?25l- done [?25hBuilding wheels for collected packages: pymsgbox Building wheel for pymsgbox (pyproject.toml) ... [?25l- done -[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7404 sha256=be36b3efa774cde835b0dd6e5839825cbb4dfe740798f5be111a0ade675d35dd +[?25h Created wheel for pymsgbox: filename=PyMsgBox-1.0.9-py3-none-any.whl size=7407 sha256=65f1e9e680d728456ab0dc9e66affd01d7ade89ec5a2a8c3aa80ab24a71247ac Stored in directory: /home/openhands/.cache/pip/wheels/85/92/63/e126ee5f33d8f2ed04f96e43ef5df7270a2f331848752e8662 Successfully built pymsgbox Installing collected packages: pymsgbox