Fixes to unblock frontend (#11488)

Co-authored-by: Ray Myers <ray.myers@gmail.com>
This commit is contained in:
Tim O'Farrell 2025-10-23 14:43:45 -06:00 committed by GitHub
parent eb954164a5
commit 4b303ec9b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 56 additions and 46 deletions

View File

@ -46,7 +46,7 @@ jobs:
else
json=$(jq -n -c '[
{ image: "nikolaik/python-nodejs:python3.12-nodejs22", tag: "nikolaik" },
{ image: "ghcr.io/all-hands-ai/python-nodejs:python3.13-nodejs22-trixie", tag: "trixie" },
{ image: "ghcr.io/openhands/python-nodejs:python3.13-nodejs22-trixie", tag: "trixie" },
{ image: "ubuntu:24.04", tag: "ubuntu" }
]')
fi

View File

@ -159,7 +159,7 @@ poetry run pytest ./tests/unit/test_*.py
To reduce build time (e.g., if no changes were made to the client-runtime component), you can use an existing Docker
container image by setting the SANDBOX_RUNTIME_CONTAINER_IMAGE environment variable to the desired Docker image.
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:0.59-nikolaik`
Example: `export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/openhands/runtime:0.59-nikolaik`
## Develop inside Docker container

View File

@ -12,7 +12,7 @@ services:
- SANDBOX_API_HOSTNAME=host.docker.internal
- DOCKER_HOST_ADDR=host.docker.internal
#
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/all-hands-ai/runtime:0.59-nikolaik}
- SANDBOX_RUNTIME_CONTAINER_IMAGE=${SANDBOX_RUNTIME_CONTAINER_IMAGE:-ghcr.io/openhands/runtime:0.59-nikolaik}
- SANDBOX_USER_ID=${SANDBOX_USER_ID:-1234}
- WORKSPACE_MOUNT_PATH=${WORKSPACE_BASE:-$PWD/workspace}
ports:

View File

@ -1,5 +1,5 @@
ARG OPENHANDS_VERSION=latest
ARG BASE="ghcr.io/all-hands-ai/openhands"
ARG BASE="ghcr.io/openhands/openhands"
FROM ${BASE}:${OPENHANDS_VERSION}
# Datadog labels

View File

@ -64,7 +64,7 @@ python enterprise_local/convert_to_env.py
You'll also need to set up the runtime image, so that the dev server doesn't try to rebuild it.
```
export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/all-hands-ai/runtime:main-nikolaik
export SANDBOX_RUNTIME_CONTAINER_IMAGE=ghcr.io/openhands/runtime:main-nikolaik
docker pull $SANDBOX_RUNTIME_CONTAINER_IMAGE
```
@ -203,7 +203,7 @@ And then invoking `printenv`. NOTE: _DO NOT DO THIS WITH PROD!!!_ (Hopefully by
"REDIS_HOST": "localhost:6379",
"OPENHANDS": "<YOUR LOCAL OSS OPENHANDS DIR>",
"FRONTEND_DIRECTORY": "<YOUR LOCAL OSS OPENHANDS DIR>/frontend/build",
"SANDBOX_RUNTIME_CONTAINER_IMAGE": "ghcr.io/all-hands-ai/runtime:main-nikolaik",
"SANDBOX_RUNTIME_CONTAINER_IMAGE": "ghcr.io/openhands/runtime:main-nikolaik",
"FILE_STORE_PATH": "<YOUR HOME DIRECTORY>>/.openhands-state",
"OPENHANDS_CONFIG_CLS": "server.config.SaaSServerConfig",
"GITHUB_APP_ID": "1062351",
@ -237,7 +237,7 @@ And then invoking `printenv`. NOTE: _DO NOT DO THIS WITH PROD!!!_ (Hopefully by
"REDIS_HOST": "localhost:6379",
"OPENHANDS": "<YOUR LOCAL OSS OPENHANDS DIR>",
"FRONTEND_DIRECTORY": "<YOUR LOCAL OSS OPENHANDS DIR>/frontend/build",
"SANDBOX_RUNTIME_CONTAINER_IMAGE": "ghcr.io/all-hands-ai/runtime:main-nikolaik",
"SANDBOX_RUNTIME_CONTAINER_IMAGE": "ghcr.io/openhands/runtime:main-nikolaik",
"FILE_STORE_PATH": "<YOUR HOME DIRECTORY>>/.openhands-state",
"OPENHANDS_CONFIG_CLS": "server.config.SaaSServerConfig",
"GITHUB_APP_ID": "1062351",

View File

@ -12,7 +12,7 @@ git clone -b $OH_SWE_BENCH_REPO_BRANCH $OH_SWE_BENCH_REPO_PATH $EVAL_WORKSPACE/O
# 2. Prepare DATA
echo "==== Prepare SWE-bench data ===="
EVAL_IMAGE=ghcr.io/all-hands-ai/eval-swe-bench:builder_with_conda
EVAL_IMAGE=ghcr.io/openhands/eval-swe-bench:builder_with_conda
EVAL_WORKSPACE=$(realpath $EVAL_WORKSPACE)
chmod +x $EVAL_WORKSPACE/OH-SWE-bench/swebench/harness/prepare_data.sh
if [ -d $EVAL_WORKSPACE/eval_data ]; then

View File

@ -12,7 +12,7 @@ git clone -b $OH_SWE_BENCH_REPO_BRANCH $OH_SWE_BENCH_REPO_PATH $EVAL_WORKSPACE/O
# 2. Prepare DATA
echo "==== Prepare SWE-bench data ===="
EVAL_IMAGE=ghcr.io/all-hands-ai/eval-swe-bench:builder_with_conda
EVAL_IMAGE=ghcr.io/openhands/eval-swe-bench:builder_with_conda
EVAL_WORKSPACE=$(realpath $EVAL_WORKSPACE)
chmod +x $EVAL_WORKSPACE/OH-SWE-bench/swebench/harness/prepare_data.sh
if [ -d $EVAL_WORKSPACE/eval_data ]; then

View File

@ -12,7 +12,7 @@ git clone -b $OH_SWE_BENCH_REPO_BRANCH $OH_SWE_BENCH_REPO_PATH $EVAL_WORKSPACE/O
# 2. Prepare DATA
echo "==== Prepare SWE-bench data ===="
EVAL_IMAGE=ghcr.io/all-hands-ai/eval-swe-bench:builder_with_conda
EVAL_IMAGE=ghcr.io/openhands/eval-swe-bench:builder_with_conda
EVAL_WORKSPACE=$(realpath $EVAL_WORKSPACE)
chmod +x $EVAL_WORKSPACE/OH-SWE-bench/swebench/harness/prepare_data.sh
if [ -d $EVAL_WORKSPACE/eval_data ]; then

View File

@ -162,7 +162,7 @@ while IFS= read -r task_image; do
# Prune unused images and volumes
docker image rm "$task_image"
docker images "ghcr.io/all-hands-ai/runtime" -q | xargs -r docker rmi -f
docker images "ghcr.io/openhands/runtime" -q | xargs -r docker rmi -f
docker volume prune -f
docker system prune -f
done < "$temp_file"

View File

@ -88,7 +88,10 @@ class AppConversationService(ABC):
@abstractmethod
async def run_setup_scripts(
self, task: AppConversationStartTask, workspace: Workspace
self,
task: AppConversationStartTask,
workspace: Workspace,
working_dir: str,
) -> AsyncGenerator[AppConversationStartTask, None]:
"""Run the setup scripts for the project and yield status updates"""
yield task

View File

@ -36,23 +36,25 @@ class GitAppConversationService(AppConversationService, ABC):
self,
task: AppConversationStartTask,
workspace: AsyncRemoteWorkspace,
working_dir: str,
) -> AsyncGenerator[AppConversationStartTask, None]:
task.status = AppConversationStartTaskStatus.PREPARING_REPOSITORY
yield task
await self.clone_or_init_git_repo(task, workspace)
await self.clone_or_init_git_repo(task, workspace, working_dir)
task.status = AppConversationStartTaskStatus.RUNNING_SETUP_SCRIPT
yield task
await self.maybe_run_setup_script(workspace)
await self.maybe_run_setup_script(workspace, working_dir)
task.status = AppConversationStartTaskStatus.SETTING_UP_GIT_HOOKS
yield task
await self.maybe_setup_git_hooks(workspace)
await self.maybe_setup_git_hooks(workspace, working_dir)
async def clone_or_init_git_repo(
self,
task: AppConversationStartTask,
workspace: AsyncRemoteWorkspace,
working_dir: str,
):
request = task.request
@ -61,7 +63,7 @@ class GitAppConversationService(AppConversationService, ABC):
_logger.debug('Initializing a new git repository in the workspace.')
await workspace.execute_command(
'git init && git config --global --add safe.directory '
+ workspace.working_dir
+ working_dir
)
else:
_logger.info('Not initializing a new git repository.')
@ -77,7 +79,7 @@ class GitAppConversationService(AppConversationService, ABC):
# Clone the repo - this is the slow part!
clone_command = f'git clone {remote_repo_url} {dir_name}'
await workspace.execute_command(clone_command, workspace.working_dir)
await workspace.execute_command(clone_command, working_dir)
# Checkout the appropriate branch
if request.selected_branch:
@ -87,14 +89,15 @@ class GitAppConversationService(AppConversationService, ABC):
random_str = base62.encodebytes(os.urandom(16))
openhands_workspace_branch = f'openhands-workspace-{random_str}'
checkout_command = f'git checkout -b {openhands_workspace_branch}'
await workspace.execute_command(checkout_command, workspace.working_dir)
await workspace.execute_command(checkout_command, working_dir)
async def maybe_run_setup_script(
self,
workspace: AsyncRemoteWorkspace,
working_dir: str,
):
"""Run .openhands/setup.sh if it exists in the workspace or repository."""
setup_script = workspace.working_dir + '/.openhands/setup.sh'
setup_script = working_dir + '/.openhands/setup.sh'
await workspace.execute_command(
f'chmod +x {setup_script} && source {setup_script}', timeout=600
@ -108,10 +111,11 @@ class GitAppConversationService(AppConversationService, ABC):
async def maybe_setup_git_hooks(
self,
workspace: AsyncRemoteWorkspace,
working_dir: str,
):
"""Set up git hooks if .openhands/pre-commit.sh exists in the workspace or repository."""
command = 'mkdir -p .git/hooks && chmod +x .openhands/pre-commit.sh'
result = await workspace.execute_command(command, workspace.working_dir)
result = await workspace.execute_command(command, working_dir)
if result.exit_code:
return
@ -127,9 +131,7 @@ class GitAppConversationService(AppConversationService, ABC):
f'mv {PRE_COMMIT_HOOK} {PRE_COMMIT_LOCAL} &&'
f'chmod +x {PRE_COMMIT_LOCAL}'
)
result = await workspace.execute_command(
command, workspace.working_dir
)
result = await workspace.execute_command(command, working_dir)
if result.exit_code != 0:
_logger.error(
f'Failed to preserve existing pre-commit hook: {result.stderr}',

View File

@ -181,11 +181,11 @@ class LiveStatusAppConversationService(GitAppConversationService):
# Run setup scripts
workspace = AsyncRemoteWorkspace(
working_dir=sandbox_spec.working_dir,
server_url=agent_server_url,
session_api_key=sandbox.session_api_key,
host=agent_server_url, api_key=sandbox.session_api_key
)
async for updated_task in self.run_setup_scripts(task, workspace):
async for updated_task in self.run_setup_scripts(
task, workspace, sandbox_spec.working_dir
):
yield updated_task
# Build the start request

View File

@ -90,7 +90,8 @@ class DockerSandboxService(SandboxService):
status_mapping = {
'running': SandboxStatus.RUNNING,
'paused': SandboxStatus.PAUSED,
'exited': SandboxStatus.MISSING,
# The stop button was pressed in the docker console
'exited': SandboxStatus.PAUSED,
'created': SandboxStatus.STARTING,
'restarting': SandboxStatus.STARTING,
'removing': SandboxStatus.MISSING,

View File

@ -222,7 +222,7 @@ class IssueResolver:
and not is_experimental
):
runtime_container_image = (
f'ghcr.io/all-hands-ai/runtime:{openhands.__version__}-nikolaik'
f'ghcr.io/openhands/runtime:{openhands.__version__}-nikolaik'
)
# Convert container image values to string or None

View File

@ -25,7 +25,7 @@ class BuildFromImageType(Enum):
def get_runtime_image_repo() -> str:
return os.getenv('OH_RUNTIME_RUNTIME_IMAGE_REPO', 'ghcr.io/all-hands-ai/runtime')
return os.getenv('OH_RUNTIME_RUNTIME_IMAGE_REPO', 'ghcr.io/openhands/runtime')
def _generate_dockerfile(

View File

@ -1139,25 +1139,29 @@ def _to_conversation_info(app_conversation: AppConversation) -> ConversationInfo
app_conversation.sandbox_status, ConversationStatus.STOPPED
)
runtime_status_mapping = {
AgentExecutionStatus.ERROR: RuntimeStatus.ERROR,
AgentExecutionStatus.IDLE: RuntimeStatus.READY,
AgentExecutionStatus.RUNNING: RuntimeStatus.READY,
AgentExecutionStatus.PAUSED: RuntimeStatus.READY,
AgentExecutionStatus.WAITING_FOR_CONFIRMATION: RuntimeStatus.READY,
AgentExecutionStatus.FINISHED: RuntimeStatus.READY,
AgentExecutionStatus.STUCK: RuntimeStatus.ERROR,
}
runtime_status = runtime_status_mapping.get(
app_conversation.agent_status, RuntimeStatus.ERROR
)
if conversation_status == ConversationStatus.RUNNING:
runtime_status_mapping = {
AgentExecutionStatus.ERROR: RuntimeStatus.ERROR,
AgentExecutionStatus.IDLE: RuntimeStatus.READY,
AgentExecutionStatus.RUNNING: RuntimeStatus.READY,
AgentExecutionStatus.PAUSED: RuntimeStatus.READY,
AgentExecutionStatus.WAITING_FOR_CONFIRMATION: RuntimeStatus.READY,
AgentExecutionStatus.FINISHED: RuntimeStatus.READY,
AgentExecutionStatus.STUCK: RuntimeStatus.ERROR,
}
runtime_status = runtime_status_mapping.get(
app_conversation.agent_status, RuntimeStatus.ERROR
)
else:
runtime_status = None
title = (
app_conversation.title
or f'Conversation {base62.encodebytes(app_conversation.id.bytes)}'
)
return ConversationInfo(
conversation_id=str(app_conversation.id),
conversation_id=app_conversation.id.hex,
title=title,
last_updated_at=app_conversation.updated_at,
status=conversation_status,

View File

@ -601,7 +601,7 @@ class TestDockerSandboxService:
service._docker_status_to_sandbox_status('paused') == SandboxStatus.PAUSED
)
assert (
service._docker_status_to_sandbox_status('exited') == SandboxStatus.MISSING
service._docker_status_to_sandbox_status('exited') == SandboxStatus.PAUSED
)
assert (
service._docker_status_to_sandbox_status('created')

View File

@ -10,7 +10,7 @@ from openhands.resolver.issue_resolver import IssueResolver
def assert_sandbox_config(
config: SandboxConfig,
base_container_image=SandboxConfig.model_fields['base_container_image'].default,
runtime_container_image='ghcr.io/all-hands-ai/runtime:mock-nikolaik', # Default to mock version
runtime_container_image='ghcr.io/openhands/runtime:mock-nikolaik', # Default to mock version
local_runtime_url=SandboxConfig.model_fields['local_runtime_url'].default,
enable_auto_lint=False,
):
@ -38,7 +38,7 @@ def test_setup_sandbox_config_default():
assert_sandbox_config(
openhands_config.sandbox,
runtime_container_image='ghcr.io/all-hands-ai/runtime:mock-nikolaik',
runtime_container_image='ghcr.io/openhands/runtime:mock-nikolaik',
)