diff --git a/containers/app/Dockerfile b/containers/app/Dockerfile index 5d52a0aa6f..7559af5908 100644 --- a/containers/app/Dockerfile +++ b/containers/app/Dockerfile @@ -37,7 +37,7 @@ ARG OPENHANDS_BUILD_VERSION #re-declare for this section ENV RUN_AS_OPENHANDS=true # A random number--we need this to be different from the user's UID on the host machine ENV OPENHANDS_USER_ID=42420 -ENV SANDBOX_API_HOSTNAME=host.docker.internal +ENV SANDBOX_LOCAL_RUNTIME_URL=http://host.docker.internal ENV USE_HOST_NETWORK=false ENV WORKSPACE_BASE=/opt/workspace_base ENV OPENHANDS_BUILD_VERSION=$OPENHANDS_BUILD_VERSION diff --git a/openhands/core/config/sandbox_config.py b/openhands/core/config/sandbox_config.py index 23a263684f..e6dc72d2cb 100644 --- a/openhands/core/config/sandbox_config.py +++ b/openhands/core/config/sandbox_config.py @@ -9,7 +9,8 @@ class SandboxConfig: """Configuration for the sandbox. Attributes: - api_hostname: The hostname for the EventStream Runtime API. + remote_runtime_api_url: The hostname for the Remote Runtime API. + local_runtime_url: The default hostname for the local runtime. You may want to change to http://host.docker.internal for DIND environments base_container_image: The base container image from which to build the runtime image. runtime_container_image: The runtime container image to use. user_id: The user ID for the sandbox. @@ -30,7 +31,8 @@ class SandboxConfig: Default is None for general purpose browsing. Check evaluation/miniwob and evaluation/webarena for examples. """ - api_hostname: str = 'localhost' + remote_runtime_api_url: str = 'http://localhost:8000' + local_runtime_url: str = 'http://localhost' api_key: str | None = None base_container_image: str = 'nikolaik/python-nodejs:python3.11-nodejs22' # default to nikolaik/python-nodejs:python3.11-nodejs22 for eventstream runtime runtime_container_image: str | None = None diff --git a/openhands/runtime/client/runtime.py b/openhands/runtime/client/runtime.py index 21124e3fce..dde4df680b 100644 --- a/openhands/runtime/client/runtime.py +++ b/openhands/runtime/client/runtime.py @@ -126,9 +126,7 @@ def __init__( self.config = config self._host_port = 30000 # initial dummy value self._container_port = 30001 # initial dummy value - self.api_url = ( - f'http://{self.config.sandbox.api_hostname}:{self._container_port}' - ) + self.api_url = f'{self.config.sandbox.local_runtime_url}:{self._container_port}' self.session = requests.Session() self.instance_id = ( sid + '_' + str(uuid.uuid4()) if sid is not None else str(uuid.uuid4()) @@ -226,7 +224,7 @@ def _init_container( self._host_port ) # in future this might differ from host port self.api_url = ( - f'http://{self.config.sandbox.api_hostname}:{self._container_port}' + f'{self.config.sandbox.local_runtime_url}:{self._container_port}' ) use_host_network = self.config.sandbox.use_host_network diff --git a/openhands/runtime/remote/runtime.py b/openhands/runtime/remote/runtime.py index 3e9a80ad20..cfda73476a 100644 --- a/openhands/runtime/remote/runtime.py +++ b/openhands/runtime/remote/runtime.py @@ -59,13 +59,6 @@ def __init__( status_message_callback: Optional[Callable] = None, ): self.config = config - if self.config.sandbox.api_hostname == 'localhost': - self.config.sandbox.api_hostname = 'api.all-hands.dev/v0/runtime' - logger.info( - 'Using localhost as the API hostname is not supported in the RemoteRuntime. Please set a proper hostname.\n' - 'Setting it to default value: api.all-hands.dev/v0/runtime' - ) - self.api_url = f'https://{self.config.sandbox.api_hostname.rstrip("/")}' if self.config.sandbox.api_key is None: raise ValueError( @@ -82,7 +75,7 @@ def __init__( ) self.runtime_builder = RemoteRuntimeBuilder( - self.api_url, self.config.sandbox.api_key + self.config.sandbox.remote_runtime_api_url, self.config.sandbox.api_key ) self.runtime_id: str | None = None self.runtime_url: str | None = None @@ -97,7 +90,11 @@ def __init__( self.container_image: str = self.config.sandbox.base_container_image self.container_name = 'oh-remote-runtime-' + self.instance_id logger.debug(f'RemoteRuntime `{sid}` config:\n{self.config}') - response = send_request(self.session, 'GET', f'{self.api_url}/registry_prefix') + response = send_request( + self.session, + 'GET', + f'{self.config.sandbox.remote_runtime_api_url}/registry_prefix', + ) response_json = response.json() registry_prefix = response_json['registry_prefix'] os.environ['OH_RUNTIME_RUNTIME_IMAGE_REPO'] = ( @@ -123,7 +120,7 @@ def __init__( response = send_request( self.session, 'GET', - f'{self.api_url}/image_exists', + f'{self.config.sandbox.remote_runtime_api_url}/image_exists', params={'image': self.container_image}, ) if response.status_code != 200 or not response.json()['exists']: @@ -157,7 +154,10 @@ def __init__( # Start the sandbox using the /start endpoint response = send_request( - self.session, 'POST', f'{self.api_url}/start', json=start_request + self.session, + 'POST', + f'{self.config.sandbox.remote_runtime_api_url}/start', + json=start_request, ) if response.status_code != 201: raise RuntimeError(f'Failed to start sandbox: {response.text}') @@ -215,7 +215,7 @@ def close(self): response = send_request( self.session, 'POST', - f'{self.api_url}/stop', + f'{self.config.sandbox.remote_runtime_api_url}/stop', json={'runtime_id': self.runtime_id}, ) if response.status_code != 200: