Fix bash timeout issue caused by interactive git clone prompts (#9148)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
Graham Neubig 2025-06-16 08:39:28 -04:00 committed by GitHub
parent 432d8829dc
commit cbe32a1a12
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 46 additions and 5 deletions

View File

@ -706,7 +706,9 @@ fi
# Get authenticated URL and do a shallow clone (--depth 1) for efficiency
remote_url = self._get_authenticated_git_url(org_openhands_repo)
clone_cmd = f'git clone --depth 1 {remote_url} {org_repo_dir}'
clone_cmd = (
f'GIT_TERMINAL_PROMPT=0 git clone --depth 1 {remote_url} {org_repo_dir}'
)
action = CmdRunAction(command=clone_cmd)
obs = self.run_action(action)

View File

@ -13,6 +13,7 @@ from daytona_sdk import (
from openhands.core.config.openhands_config import OpenHandsConfig
from openhands.events.stream import EventStream
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
@ -42,6 +43,8 @@ class DaytonaRuntime(ActionExecutionClient):
status_callback: Callable | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
):
assert config.daytona_api_key, 'Daytona API key is required'
@ -74,6 +77,8 @@ class DaytonaRuntime(ActionExecutionClient):
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
def _get_workspace(self) -> Workspace | None:

View File

@ -17,6 +17,7 @@ from openhands.core.exceptions import (
from openhands.core.logger import DEBUG, DEBUG_RUNTIME
from openhands.core.logger import openhands_logger as logger
from openhands.events import EventStream
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.builder import DockerRuntimeBuilder
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
@ -86,6 +87,8 @@ class DockerRuntime(ActionExecutionClient):
status_callback: Callable | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
main_module: str = DEFAULT_MAIN_MODULE,
):
if not DockerRuntime._shutdown_listener_id:
@ -132,6 +135,8 @@ class DockerRuntime(ActionExecutionClient):
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
# Log runtime_extra_deps after base class initialization so self.sid is available

View File

@ -12,29 +12,42 @@ from openhands.events.observation import (
Observation,
)
from openhands.events.stream import EventStream
from openhands.runtime.base import Runtime
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
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.utils.files import insert_lines, read_lines
class E2BRuntime(Runtime):
class E2BRuntime(ActionExecutionClient):
def __init__(
self,
config: OpenHandsConfig,
event_stream: EventStream,
sid: str = 'default',
plugins: list[PluginRequirement] | None = None,
sandbox: E2BSandbox | None = None,
env_vars: dict[str, str] | None = None,
status_callback: Callable | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
sandbox: E2BSandbox | None = None,
):
super().__init__(
config,
event_stream,
sid,
plugins,
status_callback=status_callback,
env_vars,
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
if sandbox is None:
self.sandbox = E2BSandbox()

View File

@ -25,6 +25,7 @@ from openhands.events.observation import (
Observation,
)
from openhands.events.serialization import event_to_dict, observation_from_dict
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
@ -145,6 +146,8 @@ class LocalRuntime(ActionExecutionClient):
status_callback: Callable[[str, str, str], None] | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
) -> None:
self.is_windows = sys.platform == 'win32'
if self.is_windows:
@ -194,6 +197,8 @@ class LocalRuntime(ActionExecutionClient):
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
# If there is an API key in the environment we use this in requests to the runtime

View File

@ -9,6 +9,7 @@ import tenacity
from openhands.core.config import OpenHandsConfig
from openhands.events import EventStream
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
@ -53,6 +54,8 @@ class ModalRuntime(ActionExecutionClient):
status_callback: Callable | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
):
assert config.modal_api_token_id, 'Modal API token id is required'
assert config.modal_api_token_secret, 'Modal API token secret is required'
@ -100,6 +103,8 @@ class ModalRuntime(ActionExecutionClient):
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
async def connect(self):

View File

@ -9,6 +9,7 @@ from runloop_api_client.types.shared_params import LaunchParameters
from openhands.core.config import OpenHandsConfig
from openhands.core.logger import openhands_logger as logger
from openhands.events import EventStream
from openhands.integrations.provider import PROVIDER_TOKEN_TYPE
from openhands.runtime.impl.action_execution.action_execution_client import (
ActionExecutionClient,
)
@ -36,6 +37,8 @@ class RunloopRuntime(ActionExecutionClient):
status_callback: Callable | None = None,
attach_to_existing: bool = False,
headless_mode: bool = True,
user_id: str | None = None,
git_provider_tokens: PROVIDER_TOKEN_TYPE | None = None,
):
assert config.runloop_api_key is not None, 'Runloop API key is required'
self.devbox: DevboxView | None = None
@ -53,6 +56,8 @@ class RunloopRuntime(ActionExecutionClient):
status_callback,
attach_to_existing,
headless_mode,
user_id,
git_provider_tokens,
)
# Buffer for container logs
self._vscode_url: str | None = None

View File

@ -366,6 +366,7 @@ class AgentSession:
headless_mode=False,
attach_to_existing=False,
env_vars=env_vars,
git_provider_tokens=git_provider_tokens,
)
# FIXME: this sleep is a terrible hack.