From 2d5b360505d82c810c020599310c6fbf1d5721c0 Mon Sep 17 00:00:00 2001 From: Xingyao Wang Date: Wed, 23 Oct 2024 05:10:03 -0500 Subject: [PATCH] refactor: re-organize different runtime implementations into an impl folder (#4346) Co-authored-by: Graham Neubig --- docs/modules/usage/architecture/runtime.md | 8 ++++---- evaluation/agent_bench/run_infer.py | 2 +- evaluation/aider_bench/run_infer.py | 2 +- evaluation/biocoder/run_infer.py | 2 +- evaluation/bird/run_infer.py | 2 +- evaluation/gaia/run_infer.py | 2 +- evaluation/humanevalfix/run_infer.py | 2 +- evaluation/integration_tests/run_infer.py | 2 +- evaluation/integration_tests/tests/base.py | 2 +- .../integration_tests/tests/t01_fix_simple_typo.py | 2 +- .../integration_tests/tests/t02_add_bash_hello.py | 2 +- .../tests/t03_jupyter_write_file.py | 2 +- .../integration_tests/tests/t04_git_staging.py | 2 +- .../integration_tests/tests/t05_simple_browsing.py | 2 +- evaluation/logic_reasoning/run_infer.py | 2 +- evaluation/miniwob/run_infer.py | 2 +- evaluation/mint/run_infer.py | 2 +- evaluation/ml_bench/run_infer.py | 2 +- evaluation/swe_bench/run_infer.py | 2 +- evaluation/toolqa/run_infer.py | 2 +- evaluation/webarena/run_infer.py | 2 +- openhands/core/cli.py | 2 +- openhands/core/main.py | 2 +- openhands/runtime/README.md | 14 +++++++------- openhands/runtime/__init__.py | 12 +++++++----- .../client.py => action_execution_server.py} | 8 ++++---- openhands/runtime/{runtime.py => base.py} | 0 openhands/runtime/{ => impl}/e2b/README.md | 0 .../{e2b/runtime.py => impl/e2b/e2b_runtime.py} | 6 +++--- openhands/runtime/{ => impl}/e2b/filestore.py | 0 openhands/runtime/{ => impl}/e2b/sandbox.py | 1 - .../eventstream/eventstream_runtime.py} | 4 ++-- .../runtime.py => impl/modal/modal_runtime.py} | 0 .../runtime.py => impl/remote/remote_runtime.py} | 4 ++-- openhands/server/listen.py | 2 +- openhands/server/session/agent_session.py | 2 +- openhands/server/session/conversation.py | 2 +- tests/runtime/conftest.py | 6 +++--- tests/runtime/test_bash.py | 4 ++-- tests/runtime/test_browsing.py | 2 +- tests/runtime/test_env_vars.py | 2 +- tests/runtime/test_images.py | 2 +- tests/runtime/test_ipython.py | 2 +- 43 files changed, 63 insertions(+), 62 deletions(-) rename openhands/runtime/{client/client.py => action_execution_server.py} (99%) rename openhands/runtime/{runtime.py => base.py} (100%) rename openhands/runtime/{ => impl}/e2b/README.md (100%) rename openhands/runtime/{e2b/runtime.py => impl/e2b/e2b_runtime.py} (93%) rename openhands/runtime/{ => impl}/e2b/filestore.py (100%) rename openhands/runtime/{ => impl}/e2b/sandbox.py (99%) rename openhands/runtime/{client/runtime.py => impl/eventstream/eventstream_runtime.py} (99%) rename openhands/runtime/{modal/runtime.py => impl/modal/modal_runtime.py} (100%) rename openhands/runtime/{remote/runtime.py => impl/remote/remote_runtime.py} (99%) diff --git a/docs/modules/usage/architecture/runtime.md b/docs/modules/usage/architecture/runtime.md index 98e3d11da8..8747f7c590 100644 --- a/docs/modules/usage/architecture/runtime.md +++ b/docs/modules/usage/architecture/runtime.md @@ -21,7 +21,7 @@ The OpenHands Runtime system uses a client-server architecture implemented with graph TD A[User-provided Custom Docker Image] --> B[OpenHands Backend] B -->|Builds| C[OH Runtime Image] - C -->|Launches| D[Runtime Client] + C -->|Launches| D[Action Executor] D -->|Initializes| E[Browser] D -->|Initializes| F[Bash Shell] D -->|Initializes| G[Plugins] @@ -49,10 +49,10 @@ graph TD 1. User Input: The user provides a custom base Docker image 2. Image Building: OpenHands builds a new Docker image (the "OH runtime image") based on the user-provided image. This new image includes OpenHands-specific code, primarily the "runtime client" 3. Container Launch: When OpenHands starts, it launches a Docker container using the OH runtime image -4. Client Initialization: The runtime client initializes inside the container, setting up necessary components like a bash shell and loading any specified plugins -5. Communication: The OpenHands backend (`runtime.py`) communicates with the runtime client over RESTful API, sending actions and receiving observations +4. Action Execution Server Initialization: The action execution server initializes an `ActionExecutor` inside the container, setting up necessary components like a bash shell and loading any specified plugins +5. Communication: The OpenHands backend (`openhands/runtime/impl/eventstream/eventstream_runtime.py`) communicates with the action execution server over RESTful API, sending actions and receiving observations 6. Action Execution: The runtime client receives actions from the backend, executes them in the sandboxed environment, and sends back observations -7. Observation Return: The client sends execution results back to the OpenHands backend as observations +7. Observation Return: The action execution server sends execution results back to the OpenHands backend as observations The role of the client: diff --git a/evaluation/agent_bench/run_infer.py b/evaluation/agent_bench/run_infer.py index b851f86fa4..f0ea180f4b 100644 --- a/evaluation/agent_bench/run_infer.py +++ b/evaluation/agent_bench/run_infer.py @@ -32,7 +32,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import AgentFinishAction, CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime def get_config( diff --git a/evaluation/aider_bench/run_infer.py b/evaluation/aider_bench/run_infer.py index 98e8f20888..c59de4f441 100644 --- a/evaluation/aider_bench/run_infer.py +++ b/evaluation/aider_bench/run_infer.py @@ -32,7 +32,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime # Configure visibility of unit tests to the Agent. USE_UNIT_TESTS = os.environ.get('USE_UNIT_TESTS', 'false').lower() == 'true' diff --git a/evaluation/biocoder/run_infer.py b/evaluation/biocoder/run_infer.py index 3574089291..9dcff6d6ef 100644 --- a/evaluation/biocoder/run_infer.py +++ b/evaluation/biocoder/run_infer.py @@ -29,7 +29,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = { 'CodeActAgent': functools.partial( diff --git a/evaluation/bird/run_infer.py b/evaluation/bird/run_infer.py index aae58cc7d5..0fba8c5c64 100644 --- a/evaluation/bird/run_infer.py +++ b/evaluation/bird/run_infer.py @@ -32,7 +32,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime def codeact_user_response(state: State) -> str: diff --git a/evaluation/gaia/run_infer.py b/evaluation/gaia/run_infer.py index 9f6f3884f5..f5794d3ad3 100644 --- a/evaluation/gaia/run_infer.py +++ b/evaluation/gaia/run_infer.py @@ -28,7 +28,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import AgentFinishAction, CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime DATASET_CACHE_DIR = os.path.join(os.path.dirname(__file__), 'data') diff --git a/evaluation/humanevalfix/run_infer.py b/evaluation/humanevalfix/run_infer.py index 002fdd1e42..9b0abbc298 100644 --- a/evaluation/humanevalfix/run_infer.py +++ b/evaluation/humanevalfix/run_infer.py @@ -37,7 +37,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime IMPORT_HELPER = { 'python': [ diff --git a/evaluation/integration_tests/run_infer.py b/evaluation/integration_tests/run_infer.py index 2c918b2ed8..ab631ab397 100644 --- a/evaluation/integration_tests/run_infer.py +++ b/evaluation/integration_tests/run_infer.py @@ -24,7 +24,7 @@ from openhands.core.config import ( from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import MessageAction -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime FAKE_RESPONSES = { 'CodeActAgent': codeact_user_response, diff --git a/evaluation/integration_tests/tests/base.py b/evaluation/integration_tests/tests/base.py index ac53cfcb91..bc98b884d2 100644 --- a/evaluation/integration_tests/tests/base.py +++ b/evaluation/integration_tests/tests/base.py @@ -3,7 +3,7 @@ from abc import ABC, abstractmethod from pydantic import BaseModel from openhands.events.event import Event -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime class TestResult(BaseModel): diff --git a/evaluation/integration_tests/tests/t01_fix_simple_typo.py b/evaluation/integration_tests/tests/t01_fix_simple_typo.py index ef9fe2edd0..4cfa331df1 100644 --- a/evaluation/integration_tests/tests/t01_fix_simple_typo.py +++ b/evaluation/integration_tests/tests/t01_fix_simple_typo.py @@ -4,7 +4,7 @@ import tempfile from evaluation.integration_tests.tests.base import BaseIntegrationTest, TestResult from openhands.events.action import CmdRunAction from openhands.events.event import Event -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime class Test(BaseIntegrationTest): diff --git a/evaluation/integration_tests/tests/t02_add_bash_hello.py b/evaluation/integration_tests/tests/t02_add_bash_hello.py index 5ac031e887..ac82e89bac 100644 --- a/evaluation/integration_tests/tests/t02_add_bash_hello.py +++ b/evaluation/integration_tests/tests/t02_add_bash_hello.py @@ -2,7 +2,7 @@ from evaluation.integration_tests.tests.base import BaseIntegrationTest, TestRes from evaluation.utils.shared import assert_and_raise from openhands.events.action import CmdRunAction from openhands.events.event import Event -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime class Test(BaseIntegrationTest): diff --git a/evaluation/integration_tests/tests/t03_jupyter_write_file.py b/evaluation/integration_tests/tests/t03_jupyter_write_file.py index 8e48106632..e1ed6c27c4 100644 --- a/evaluation/integration_tests/tests/t03_jupyter_write_file.py +++ b/evaluation/integration_tests/tests/t03_jupyter_write_file.py @@ -2,7 +2,7 @@ from evaluation.integration_tests.tests.base import BaseIntegrationTest, TestRes from evaluation.utils.shared import assert_and_raise from openhands.events.action import CmdRunAction from openhands.events.event import Event -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime class Test(BaseIntegrationTest): diff --git a/evaluation/integration_tests/tests/t04_git_staging.py b/evaluation/integration_tests/tests/t04_git_staging.py index 32638a289e..aadb861203 100644 --- a/evaluation/integration_tests/tests/t04_git_staging.py +++ b/evaluation/integration_tests/tests/t04_git_staging.py @@ -2,7 +2,7 @@ from evaluation.integration_tests.tests.base import BaseIntegrationTest, TestRes from evaluation.utils.shared import assert_and_raise from openhands.events.action import CmdRunAction from openhands.events.event import Event -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime class Test(BaseIntegrationTest): diff --git a/evaluation/integration_tests/tests/t05_simple_browsing.py b/evaluation/integration_tests/tests/t05_simple_browsing.py index 8462de9c38..8f08cb4e72 100644 --- a/evaluation/integration_tests/tests/t05_simple_browsing.py +++ b/evaluation/integration_tests/tests/t05_simple_browsing.py @@ -6,7 +6,7 @@ from evaluation.utils.shared import assert_and_raise from openhands.events.action import AgentFinishAction, CmdRunAction, MessageAction from openhands.events.event import Event from openhands.events.observation import AgentDelegateObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime HTML_FILE = """ diff --git a/evaluation/logic_reasoning/run_infer.py b/evaluation/logic_reasoning/run_infer.py index 7fa6a5bb50..b07af7b08c 100644 --- a/evaluation/logic_reasoning/run_infer.py +++ b/evaluation/logic_reasoning/run_infer.py @@ -29,7 +29,7 @@ from openhands.events.action import ( MessageAction, ) from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = { 'CodeActAgent': codeact_user_response, diff --git a/evaluation/miniwob/run_infer.py b/evaluation/miniwob/run_infer.py index 1df7dac028..ccd36f2d38 100644 --- a/evaluation/miniwob/run_infer.py +++ b/evaluation/miniwob/run_infer.py @@ -30,11 +30,11 @@ from openhands.events.action import ( MessageAction, ) from openhands.events.observation import CmdOutputObservation +from openhands.runtime.base import Runtime from openhands.runtime.browser.browser_env import ( BROWSER_EVAL_GET_GOAL_ACTION, BROWSER_EVAL_GET_REWARDS_ACTION, ) -from openhands.runtime.runtime import Runtime SUPPORTED_AGENT_CLS = {'BrowsingAgent'} diff --git a/evaluation/mint/run_infer.py b/evaluation/mint/run_infer.py index 481336d59d..80127420a4 100644 --- a/evaluation/mint/run_infer.py +++ b/evaluation/mint/run_infer.py @@ -32,7 +32,7 @@ from openhands.events.action import ( MessageAction, ) from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime def codeact_user_response_mint(state: State, task: Task, task_config: dict[str, int]): diff --git a/evaluation/ml_bench/run_infer.py b/evaluation/ml_bench/run_infer.py index 671c6350a4..0f1ba0ab95 100644 --- a/evaluation/ml_bench/run_infer.py +++ b/evaluation/ml_bench/run_infer.py @@ -41,7 +41,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime config = load_app_config() diff --git a/evaluation/swe_bench/run_infer.py b/evaluation/swe_bench/run_infer.py index e0539143de..18b7daac01 100644 --- a/evaluation/swe_bench/run_infer.py +++ b/evaluation/swe_bench/run_infer.py @@ -33,7 +33,7 @@ from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation, ErrorObservation from openhands.events.serialization.event import event_to_dict -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.runtime.utils.shutdown_listener import sleep_if_should_continue USE_HINT_TEXT = os.environ.get('USE_HINT_TEXT', 'false').lower() == 'true' diff --git a/evaluation/toolqa/run_infer.py b/evaluation/toolqa/run_infer.py index 8b3ebdc58b..85f565120a 100644 --- a/evaluation/toolqa/run_infer.py +++ b/evaluation/toolqa/run_infer.py @@ -25,7 +25,7 @@ from openhands.core.logger import openhands_logger as logger from openhands.core.main import create_runtime, run_controller from openhands.events.action import CmdRunAction, MessageAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime AGENT_CLS_TO_FAKE_USER_RESPONSE_FN = { 'CodeActAgent': codeact_user_response, diff --git a/evaluation/webarena/run_infer.py b/evaluation/webarena/run_infer.py index 26637e00be..2291aa08c8 100644 --- a/evaluation/webarena/run_infer.py +++ b/evaluation/webarena/run_infer.py @@ -30,11 +30,11 @@ from openhands.events.action import ( MessageAction, ) from openhands.events.observation import CmdOutputObservation +from openhands.runtime.base import Runtime from openhands.runtime.browser.browser_env import ( BROWSER_EVAL_GET_GOAL_ACTION, BROWSER_EVAL_GET_REWARDS_ACTION, ) -from openhands.runtime.runtime import Runtime SUPPORTED_AGENT_CLS = {'BrowsingAgent'} diff --git a/openhands/core/cli.py b/openhands/core/cli.py index b87674e751..73b11f30e8 100644 --- a/openhands/core/cli.py +++ b/openhands/core/cli.py @@ -30,7 +30,7 @@ from openhands.events.observation import ( ) from openhands.llm.llm import LLM from openhands.runtime import get_runtime_cls -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.storage import get_file_store diff --git a/openhands/core/main.py b/openhands/core/main.py index 0ebcde8527..3934349f0c 100644 --- a/openhands/core/main.py +++ b/openhands/core/main.py @@ -26,7 +26,7 @@ from openhands.events.observation import AgentStateChangedObservation from openhands.events.serialization.event import event_to_trajectory from openhands.llm.llm import LLM from openhands.runtime import get_runtime_cls -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.storage import get_file_store diff --git a/openhands/runtime/README.md b/openhands/runtime/README.md index 72c18f7896..ca084706fb 100644 --- a/openhands/runtime/README.md +++ b/openhands/runtime/README.md @@ -7,9 +7,9 @@ You can learn more about how the runtime works in the [EventStream Runtime](http ## Main Components -### 1. runtime.py +### 1. impl/*runtime.py -The `runtime.py` file defines the `Runtime` class, which serves as the primary interface for agent interactions with the external environment. It handles various operations including: +The `impl/*runtime.py` file defines the `Runtime` class, which serves as the primary [interface](./base.py) for agent interactions with the external environment. It handles various operations including: - Bash sandbox execution - Browser interactions @@ -23,11 +23,11 @@ Key features of the `Runtime` class: - Action execution methods for different types of actions (run, read, write, browse, etc.) - Abstract methods for file operations (to be implemented by subclasses) -### 2. client/client.py +### 2. action_execution_server.py -The `client.py` file contains the `RuntimeClient` class, which is responsible for executing actions received from the OpenHands backend and producing observations. This client runs inside a Docker sandbox. +The `action_executor_server.py` file contains the `ActionExecutor` class, which is responsible for executing actions received from the OpenHands backend and producing observations. This client runs inside a Docker sandbox. -Key features of the `RuntimeClient` class: +Key features of the `ActionExecutor` class: - Initialization of user environment and bash shell - Plugin management and initialization - Execution of various action types (bash commands, IPython cells, file operations, browsing) @@ -59,7 +59,7 @@ Key features of the `RuntimeClient` class: - Plugins like Jupyter and AgentSkills are initialized and integrated into the runtime. 6. **Sandbox Environment**: - - The `RuntimeClient` sets up a sandboxed environment inside a Docker container. + - The `ActionExecutor` sets up a sandboxed environment inside a Docker container. - User environment and bash shell are initialized. - Actions received from the OpenHands backend are executed in this sandboxed environment. @@ -96,7 +96,7 @@ This is the default runtime used within OpenHands. The Remote Runtime is designed for execution in a remote environment: -- Connects to a remote server running the RuntimeClient +- Connects to a remote server running the ActionExecutor - Executes actions by sending requests to the remote client - Supports distributed execution and cloud-based deployments - Ideal for production environments, scalability, and scenarios where local resource constraints are a concern diff --git a/openhands/runtime/__init__.py b/openhands/runtime/__init__.py index df73be9d83..f06121bb2a 100644 --- a/openhands/runtime/__init__.py +++ b/openhands/runtime/__init__.py @@ -1,24 +1,26 @@ from openhands.core.logger import openhands_logger as logger -from openhands.runtime.e2b.sandbox import E2BBox +from openhands.runtime.impl.e2b.sandbox import E2BBox def get_runtime_cls(name: str): # Local imports to avoid circular imports if name == 'eventstream': - from openhands.runtime.client.runtime import EventStreamRuntime + from openhands.runtime.impl.eventstream.eventstream_runtime import ( + EventStreamRuntime, + ) return EventStreamRuntime elif name == 'e2b': - from openhands.runtime.e2b.runtime import E2BRuntime + from openhands.runtime.impl.e2b.e2b_runtime import E2BRuntime return E2BRuntime elif name == 'remote': - from openhands.runtime.remote.runtime import RemoteRuntime + from openhands.runtime.impl.remote.remote_runtime import RemoteRuntime return RemoteRuntime elif name == 'modal': logger.info('Using ModalRuntime') - from openhands.runtime.modal.runtime import ModalRuntime + from openhands.runtime.impl.modal.modal_runtime import ModalRuntime return ModalRuntime else: diff --git a/openhands/runtime/client/client.py b/openhands/runtime/action_execution_server.py similarity index 99% rename from openhands/runtime/client/client.py rename to openhands/runtime/action_execution_server.py index 89fd230652..719d206e5a 100644 --- a/openhands/runtime/client/client.py +++ b/openhands/runtime/action_execution_server.py @@ -78,8 +78,8 @@ def verify_api_key(api_key: str = Depends(api_key_header)): return api_key -class RuntimeClient: - """RuntimeClient is running inside docker sandbox. +class ActionExecutor: + """ActionExecutor is running inside docker sandbox. It is responsible for executing actions received from OpenHands backend and producing observations. """ @@ -629,12 +629,12 @@ if __name__ == '__main__': raise ValueError(f'Plugin {plugin} not found') plugins_to_load.append(ALL_PLUGINS[plugin]()) # type: ignore - client: RuntimeClient | None = None + client: ActionExecutor | None = None @asynccontextmanager async def lifespan(app: FastAPI): global client - client = RuntimeClient( + client = ActionExecutor( plugins_to_load, work_dir=args.working_dir, username=args.username, diff --git a/openhands/runtime/runtime.py b/openhands/runtime/base.py similarity index 100% rename from openhands/runtime/runtime.py rename to openhands/runtime/base.py diff --git a/openhands/runtime/e2b/README.md b/openhands/runtime/impl/e2b/README.md similarity index 100% rename from openhands/runtime/e2b/README.md rename to openhands/runtime/impl/e2b/README.md diff --git a/openhands/runtime/e2b/runtime.py b/openhands/runtime/impl/e2b/e2b_runtime.py similarity index 93% rename from openhands/runtime/e2b/runtime.py rename to openhands/runtime/impl/e2b/e2b_runtime.py index d2988895ba..b5233574f0 100644 --- a/openhands/runtime/e2b/runtime.py +++ b/openhands/runtime/impl/e2b/e2b_runtime.py @@ -12,10 +12,10 @@ from openhands.events.observation import ( Observation, ) from openhands.events.stream import EventStream -from openhands.runtime.e2b.filestore import E2BFileStore -from openhands.runtime.e2b.sandbox import E2BSandbox +from openhands.runtime.base import Runtime +from openhands.runtime.impl.e2b.filestore import E2BFileStore +from openhands.runtime.impl.e2b.sandbox import E2BSandbox from openhands.runtime.plugins import PluginRequirement -from openhands.runtime.runtime import Runtime from openhands.runtime.utils.files import insert_lines, read_lines diff --git a/openhands/runtime/e2b/filestore.py b/openhands/runtime/impl/e2b/filestore.py similarity index 100% rename from openhands/runtime/e2b/filestore.py rename to openhands/runtime/impl/e2b/filestore.py diff --git a/openhands/runtime/e2b/sandbox.py b/openhands/runtime/impl/e2b/sandbox.py similarity index 99% rename from openhands/runtime/e2b/sandbox.py rename to openhands/runtime/impl/e2b/sandbox.py index a8f4c6de98..044a45d8ee 100644 --- a/openhands/runtime/e2b/sandbox.py +++ b/openhands/runtime/impl/e2b/sandbox.py @@ -7,7 +7,6 @@ from e2b import Sandbox as E2BSandbox from e2b.sandbox.exception import ( TimeoutException, ) - from openhands.core.config import SandboxConfig from openhands.core.logger import openhands_logger as logger diff --git a/openhands/runtime/client/runtime.py b/openhands/runtime/impl/eventstream/eventstream_runtime.py similarity index 99% rename from openhands/runtime/client/runtime.py rename to openhands/runtime/impl/eventstream/eventstream_runtime.py index 61d9a7a490..358e3c0907 100644 --- a/openhands/runtime/client/runtime.py +++ b/openhands/runtime/impl/eventstream/eventstream_runtime.py @@ -31,9 +31,9 @@ from openhands.events.observation import ( ) from openhands.events.serialization import event_to_dict, observation_from_dict from openhands.events.serialization.action import ACTION_TYPE_TO_CLASS +from openhands.runtime.base import Runtime from openhands.runtime.builder import DockerRuntimeBuilder from openhands.runtime.plugins import PluginRequirement -from openhands.runtime.runtime import Runtime from openhands.runtime.utils import find_available_tcp_port from openhands.runtime.utils.request import send_request_with_retry from openhands.runtime.utils.runtime_build import build_runtime_image @@ -304,7 +304,7 @@ class EventStreamRuntime(Runtime): command=( f'/openhands/micromamba/bin/micromamba run -n openhands ' f'poetry run ' - f'python -u -m openhands.runtime.client.client {self._container_port} ' + f'python -u -m openhands.runtime.action_execution_server {self._container_port} ' f'--working-dir "{sandbox_workspace_dir}" ' f'{plugin_arg}' f'--username {"openhands" if self.config.run_as_openhands else "root"} ' diff --git a/openhands/runtime/modal/runtime.py b/openhands/runtime/impl/modal/modal_runtime.py similarity index 100% rename from openhands/runtime/modal/runtime.py rename to openhands/runtime/impl/modal/modal_runtime.py diff --git a/openhands/runtime/remote/runtime.py b/openhands/runtime/impl/remote/remote_runtime.py similarity index 99% rename from openhands/runtime/remote/runtime.py rename to openhands/runtime/impl/remote/remote_runtime.py index 39134f5094..40779f2abd 100644 --- a/openhands/runtime/remote/runtime.py +++ b/openhands/runtime/impl/remote/remote_runtime.py @@ -28,9 +28,9 @@ from openhands.events.observation import ( ) from openhands.events.serialization import event_to_dict, observation_from_dict from openhands.events.serialization.action import ACTION_TYPE_TO_CLASS +from openhands.runtime.base import Runtime from openhands.runtime.builder.remote import RemoteRuntimeBuilder from openhands.runtime.plugins import PluginRequirement -from openhands.runtime.runtime import Runtime from openhands.runtime.utils.request import ( is_404_error, is_503_error, @@ -212,7 +212,7 @@ class RemoteRuntime(Runtime): 'command': ( f'/openhands/micromamba/bin/micromamba run -n openhands ' 'poetry run ' - f'python -u -m openhands.runtime.client.client {self.port} ' + f'python -u -m openhands.runtime.action_execution_server {self.port} ' f'--working-dir {self.config.workspace_mount_path_in_sandbox} ' f'{plugin_arg}' f'--username {"openhands" if self.config.run_as_openhands else "root"} ' diff --git a/openhands/server/listen.py b/openhands/server/listen.py index 34ac732f57..a082031205 100644 --- a/openhands/server/listen.py +++ b/openhands/server/listen.py @@ -54,7 +54,7 @@ from openhands.events.observation import ( ) from openhands.events.serialization import event_to_dict from openhands.llm import bedrock -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.server.auth import get_sid_from_token, sign_token from openhands.server.session import SessionManager diff --git a/openhands/server/session/agent_session.py b/openhands/server/session/agent_session.py index bbb568ee48..c408cfd921 100644 --- a/openhands/server/session/agent_session.py +++ b/openhands/server/session/agent_session.py @@ -11,7 +11,7 @@ from openhands.events.action.agent import ChangeAgentStateAction from openhands.events.event import EventSource from openhands.events.stream import EventStream from openhands.runtime import get_runtime_cls -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.security import SecurityAnalyzer, options from openhands.storage.files import FileStore from openhands.utils.async_utils import call_sync_from_async diff --git a/openhands/server/session/conversation.py b/openhands/server/session/conversation.py index dc2ca833ff..a15ec22f32 100644 --- a/openhands/server/session/conversation.py +++ b/openhands/server/session/conversation.py @@ -1,7 +1,7 @@ from openhands.core.config import AppConfig from openhands.events.stream import EventStream from openhands.runtime import get_runtime_cls -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime from openhands.security import SecurityAnalyzer, options from openhands.storage.files import FileStore diff --git a/tests/runtime/conftest.py b/tests/runtime/conftest.py index a20795d18d..7affbfc040 100644 --- a/tests/runtime/conftest.py +++ b/tests/runtime/conftest.py @@ -11,10 +11,10 @@ from pytest import TempPathFactory from openhands.core.config import load_app_config from openhands.core.logger import openhands_logger as logger from openhands.events import EventStream -from openhands.runtime.client.runtime import EventStreamRuntime +from openhands.runtime.base import Runtime +from openhands.runtime.impl.eventstream.eventstream_runtime import EventStreamRuntime +from openhands.runtime.impl.remote.remote_runtime import RemoteRuntime from openhands.runtime.plugins import AgentSkillsRequirement, JupyterRequirement -from openhands.runtime.remote.runtime import RemoteRuntime -from openhands.runtime.runtime import Runtime from openhands.storage import get_file_store TEST_IN_CI = os.getenv('TEST_IN_CI', 'False').lower() in ['true', '1', 'yes'] diff --git a/tests/runtime/test_bash.py b/tests/runtime/test_bash.py index b11e8093b1..cfe480102d 100644 --- a/tests/runtime/test_bash.py +++ b/tests/runtime/test_bash.py @@ -1,4 +1,4 @@ -"""Bash-related tests for the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox.""" +"""Bash-related tests for the EventStreamRuntime, which connects to the ActionExecutor running in the sandbox.""" import os @@ -13,7 +13,7 @@ from conftest import ( from openhands.core.logger import openhands_logger as logger from openhands.events.action import CmdRunAction from openhands.events.observation import CmdOutputObservation -from openhands.runtime.runtime import Runtime +from openhands.runtime.base import Runtime # ============================================================================================================================ # Bash-specific tests diff --git a/tests/runtime/test_browsing.py b/tests/runtime/test_browsing.py index 1d3a42131b..264d7c4803 100644 --- a/tests/runtime/test_browsing.py +++ b/tests/runtime/test_browsing.py @@ -1,4 +1,4 @@ -"""Browsing-related tests for the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox.""" +"""Browsing-related tests for the EventStreamRuntime, which connects to the ActionExecutor running in the sandbox.""" import json diff --git a/tests/runtime/test_env_vars.py b/tests/runtime/test_env_vars.py index 70740c96a2..79773457a5 100644 --- a/tests/runtime/test_env_vars.py +++ b/tests/runtime/test_env_vars.py @@ -1,4 +1,4 @@ -"""Env vars related tests for the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox.""" +"""Env vars related tests for the EventStreamRuntime, which connects to the ActionExecutor running in the sandbox.""" import os from unittest.mock import patch diff --git a/tests/runtime/test_images.py b/tests/runtime/test_images.py index 5ef099f47c..e5f3ded04a 100644 --- a/tests/runtime/test_images.py +++ b/tests/runtime/test_images.py @@ -1,4 +1,4 @@ -"""Image-related tests for the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox.""" +"""Image-related tests for the EventStreamRuntime, which connects to the ActionExecutor running in the sandbox.""" import pytest from conftest import _close_test_runtime, _load_runtime diff --git a/tests/runtime/test_ipython.py b/tests/runtime/test_ipython.py index 0d13fda2c3..c16baa7b0e 100644 --- a/tests/runtime/test_ipython.py +++ b/tests/runtime/test_ipython.py @@ -1,4 +1,4 @@ -"""Test the EventStreamRuntime, which connects to the RuntimeClient running in the sandbox.""" +"""Test the EventStreamRuntime, which connects to the ActionExecutor running in the sandbox.""" import pytest from conftest import (