Skip to content

Commit adbde39

Browse files
authored
feat(upgrade): upgrade OpenHands from v1.6.0 to v1.7.0 (#81)
## Summary Upgrade OpenHands from v1.6.0 → v1.7.0 (released 2026-05-01, 296 commits since 1.6.0). **v1.7.0 is a major V0→V1 cleanup release**, not a feature release. Upstream deleted multiple V0 packages the fork was patching: `openhands/llm/`, `openhands/utils/llm.py`, `openhands/storage/`, `openhands/core/config/llm_config.py`, and stripped the store-class fields from `openhands/server/config/server_config.py`. SDK bumped v1.15.0 → v1.19.1 (4 minor versions). ## Status: DRAFT — `do-not-merge` label set The infra-side wiring for v1.7.0 is committed in this PR. Two pieces of dependent work in other repos must complete before this is mergeable: 1. **OpenHands fork branch `custom/v1.7.0-fargate`** must finish cherry-picking the remaining 3 commits and add the new V1 Cognito ports (`openhands/app_server/{settings,secrets,user_auth}/cognito_*.py`). Once that lands and `FORK_REF` is bumped to its final SHA, also re-add those 3 file paths to `docker/download-fork-patches.sh:FILES` (they're documented as TODO comments today). 2. **SDK fork branch** off v1.19.1 with the 5 Bedrock patches (28/29/30/31/32) — currently those patches are applied in-place via `apply-sdk-patches.py` against upstream `OpenHands/software-agent-sdk@v1.19.1`. Optional follow-up: contribute upstream and drop the patches in v1.8.x (see feasibility report §5). Until those land, this PR's image build will succeed but the container will fail-close at startup (Patch 21 multi-tenant verification refuses to run when V1 Cognito injectors aren't wired in `app_server/config.py`). That's the loud, intended failure mode. ## What's done in this PR - [x] Feasibility report (`docs/designs/upgrade-v1.7.0-feasibility.md`) — full plan with verified per-patch verdicts and risk register - [x] `docker/Dockerfile`: `OPENHANDS_VERSION` 1.6.0 → 1.7.0; `openhands-tools` 1.15.0 → 1.19.1; `FORK_REF` repointed to `b707ea5cc1` (partial v1.7.0 fork checkpoint, 17/20 commits ported) - [x] `docker/agent-server-custom/Dockerfile`: SDK clone pin v1.15.0 → v1.19.1; VS Code stage `1.15.0-python` → `1.19.1-python` - [x] `docker/agent-server-custom/apply-sdk-patches.py`: - **Drop Patch 27** (max_output_tokens cap absorbed in SDK v1.19.1: `llm.py:1273-1287` caps to half the context window when output ≥ context) - **Re-anchor Patch 23** (insert before `@field_validator("skills")` since `current_datetime` field was added between `secrets:` and the validator in the v1.19.1 source) - **Add Patch 28**: default credential chain in `_list_bedrock_foundation_models` (allows IRSA / IAM-role / `AWS_PROFILE` Bedrock listing without explicit static creds) - **Add Patch 29**: cross-region inference profile listing (paginate `list_inference_profiles(typeEquals=SYSTEM_DEFINED)`, surface `bedrock/us.` / `bedrock/eu.` / `bedrock/apac.` / `bedrock/global.` IDs) - **Add Patch 30**: cross-region prefix stripping in `get_litellm_model_info` (so `bedrock/us.anthropic.claude-*` finds its `model_cost` entry) - **Add Patch 31**: `os.environ.setdefault("AWS_DEFAULT_REGION", …)` alongside `AWS_REGION_NAME` in `_set_env_side_effects` (boto3 prefers the former for some auth modes) - **Add Patch 32**: env-hint trigger (`AWS_PROFILE` / `AWS_ROLE_ARN` / `AWS_WEB_IDENTITY_TOKEN_FILE`) for Bedrock listing in `get_supported_llm_models` - [x] `docker/apply-startup.sh` Patch 21 rewrite — **security-critical**. Was `grep s3_settings_store.S3SettingsStore` on V0 file path; that file is gone in v1.7.0, so the `[ -f ]` guard would silently skip the check. New check fail-closes on `/app/openhands/app_server/config.py` not referencing `CognitoS3SettingsStore` / `CognitoS3SecretsStore` / `CognitoUserAuth`. Container refuses to start until V1 ports are wired. - [x] `docker/download-fork-patches.sh` — drop V0-deleted entries (server_config.py, secrets.py, llm/bedrock.py, llm/llm.py, llm_config.py, utils/llm.py); add documented TODO for the 3 net-new V1 Cognito port files - [x] `lib/compute-stack.ts`: `DEFAULT_OPENHANDS_VERSION` → 1.7.0; `DEFAULT_RUNTIME_VERSION` → 1.7-nikolaik; image-digest TODO marker (will be updated after first `docker pull` of v1.7.0 base image) - [x] Snapshot regen: `test/__snapshots__/stacks.test.ts.snap` - [x] PR review (`code-reviewer` agent) — both findings addressed: VS Code stage tag mismatch fixed, `FORK_REF` blocking-merge concern → `do-not-merge` label - [x] Local build passes: `npm run build` - [x] Local unit tests: 122 passed, 7 pre-existing failures (`UserConfigStack` `PythonFunction` ARM64 Docker bundling — known QEMU/binfmt issue on this dev box, called out in feasibility §A-3) ## Done in earlier sessions of this PR - Feasibility report committed - Fork branch `custom/v1.7.0-fargate` pushed at SHA `b707ea5cc1` on `zxkane/OpenHands` (17/20 v1.6.0 fork commits cherry-picked; 3 LLM-targeting commits intentionally skipped because they target V0 files now deleted upstream — those move to SDK-side patches instead) ## TODO before this PR is mergeable - [ ] **Finish fork branch** `custom/v1.7.0-fargate` (3 remaining cherry-picks + 3 new V1 Cognito port files); update `FORK_REF` and re-add the 3 paths to `download-fork-patches.sh:FILES` - [ ] **SDK fork branch** off v1.19.1 with the 5 Bedrock patches (alternative: keep applying via `apply-sdk-patches.py` against upstream; the patches are stable as long as the SDK source doesn't shift) - [ ] **Pull v1.7.0 base image** and update `OPENHANDS_IMAGE_DIGEST` in `lib/compute-stack.ts` + `docker/Dockerfile` (placeholder is the v1.6.0 digest — will fail loudly during Docker build until updated) - [ ] **Staging deploy** (`./deploy-staging.local.sh`) — requires QEMU binfmt for ARM64 - [ ] **E2E tests** (`./test/select-e2e-tests.sh --all`) — major upgrade - [ ] **Bedrock-with-IAM-role smoke test** — verifies SDK Bedrock patches (28-32) work end-to-end - [ ] Multi-tenant isolation E2E (two users, settings/secrets confined to `users/{user_id}/...` paths) ## Test Plan - [x] Build passes: `npm run build` - [x] Unit tests pass (122/129; 7 pre-existing ARM64 Docker bundling failures unrelated to v1.7.0) - [ ] Multi-tenant isolation E2E: two users, settings/secrets confined to `users/{user_id}/...` paths - [ ] Conversation lifecycle E2E: start, pause, resume, archive - [ ] Bedrock E2E: IAM-role-only profile (no static keys) lists models and runs a conversation ## Design - [x] Feasibility report (`docs/designs/upgrade-v1.7.0-feasibility.md`) with verified per-patch verdicts and risk register ## Linked - Fork branch (partial): https://github.com/zxkane/OpenHands/tree/custom/v1.7.0-fargate - Upstream v1.7.0 release: https://github.com/OpenHands/OpenHands/releases/tag/1.7.0
1 parent 7f58ab5 commit adbde39

18 files changed

Lines changed: 1322 additions & 722 deletions

docker/Dockerfile

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,52 @@
1919
# This prevents Docker build cache from silently using a stale base image layer.
2020
# To update: docker manifest inspect docker.openhands.dev/openhands/openhands:<version>
2121
# and use the top-level digest (sha256:...) from the manifest list.
22-
ARG OPENHANDS_VERSION=1.6.0
23-
ARG OPENHANDS_IMAGE_DIGEST=sha256:5c0dc26f467bf8e47a6e76308edb7a30af4084b17e23a3460b5467008b12111b
22+
ARG OPENHANDS_VERSION=1.7.0
23+
# Multi-arch manifest list digest (linux/amd64 + linux/arm64) for openhands/openhands:1.7.0.
24+
# Refresh: docker buildx imagetools inspect docker.openhands.dev/openhands/openhands:<version>
25+
ARG OPENHANDS_IMAGE_DIGEST=sha256:916abcb15cc451d96853bd41c55117bb2ff3de0b9914cdcd861d338055798dc6
2426
FROM docker.openhands.dev/openhands/openhands:${OPENHANDS_VERSION}@${OPENHANDS_IMAGE_DIGEST}
2527

2628
# Upgrade system packages to fix CVEs (openssl, gnutls28, etc.)
2729
RUN apt-get update && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*
2830

2931
# Install boto3 for AWS Bedrock support (required by litellm for AWS authentication)
30-
# Upgrade openhands-tools to match agent-server-custom SDK (v1.15.0)
31-
RUN pip install --no-cache-dir boto3 openhands-tools==1.15.0
32+
# Upgrade openhands-tools to match agent-server-custom SDK (v1.19.1)
33+
RUN pip install --no-cache-dir boto3 openhands-tools==1.19.1
3234

3335
# ─── Build-time: Download patched upstream files from fork ───────────────────
3436
# Replaces the old apply-patch.sh (2000+ line regex patching at startup).
3537
# The fork (zxkane/openhands) has clean per-feature commits against the release tag.
3638
# See docker/CLAUDE.md for the full list of patched files and fork branch strategy.
37-
# Pin to commit SHA for reproducible builds (tag: custom-v1.6.0-fargate-r1)
38-
# Fargate branch: RemoteSandboxService compatible, multi-tenant isolation, Bedrock enhancements
39-
ARG FORK_REF=7a481ec3a7ec071851a3a854bd0c76b338c88e7b
39+
# Pin to commit SHA for reproducible builds (branch: custom/v1.7.0-fargate).
40+
# Fargate branch: RemoteSandboxService compatible, multi-tenant isolation, V1 Cognito wiring.
41+
ARG FORK_REF=bb3fe51c920eec0b51bc7e118e340b582db0649f
4042
COPY download-fork-patches.sh /opt/download-fork-patches.sh
4143
RUN FORK_REF=${FORK_REF} sh /opt/download-fork-patches.sh
4244

4345
# ─── Custom modules (NEW files, not upstream modifications) ──────────────────
46+
#
47+
# v1.7.0: COPY destinations migrated to V1 paths (openhands.app_server.*).
48+
# Upstream deleted openhands/server/user_auth/ and openhands/storage/{settings,
49+
# secrets,conversation}/ in v1.7.0. The custom modules now extend the V1 ABCs
50+
# (UserAuth / SettingsStore / SecretsStore) and live alongside the upstream
51+
# defaults under openhands/app_server/{user_auth,settings,secrets}/.
52+
# cognito_file_conversation_store.py is dropped — there is no V1 equivalent;
53+
# multi-tenant conversation isolation runs through CognitoSQLAppConversationInfoService.
4454

4555
# Patched auth_user_context.py for webhook authentication from Docker internal network
4656
COPY patched/ /app/patched/
4757

48-
# Cognito user authentication (Lambda@Edge header-based identity)
49-
COPY cognito_user_auth.py /app/openhands/server/user_auth/
50-
51-
# User-scoped conversation storage (S3 path: users/{user_id}/conversations/{sid}/)
52-
COPY cognito_file_conversation_store.py /app/openhands/storage/conversation/
58+
# Cognito user authentication (Lambda@Edge header-based identity) — V1 path
59+
COPY cognito_user_auth.py /app/openhands/app_server/user_auth/
5360

5461
# User config loader for MCP configurations from S3
5562
COPY user_config_loader.py /app/openhands/server/user_config_loader.py
5663

5764
# User-scoped settings and secrets stores for multi-tenancy (CRITICAL SECURITY)
5865
# Store data at users/{user_id}/settings.json and users/{user_id}/secrets.json
59-
COPY s3_settings_store.py /app/openhands/storage/settings/
60-
COPY s3_secrets_store.py /app/openhands/storage/secrets/
66+
COPY s3_settings_store.py /app/openhands/app_server/settings/
67+
COPY s3_secrets_store.py /app/openhands/app_server/secrets/
6168

6269
# Multi-tenant conversation isolation (user_id-based filtering)
6370
COPY cognito_sql_conversation_info_service.py /app/openhands/app_server/app_conversation/

docker/agent-server-custom/Dockerfile

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
# Custom agent-server build with boto3 included in PyInstaller bundle
22
# This builds the agent-server binary from source with boto3/botocore as hidden imports
33
#
4-
# Build-time patches (Patch 23-26) are applied via apply-sdk-patches.py
5-
# These patches MUST be at build time because PyInstaller creates an immutable binary.
6-
# Runtime patches are in docker/apply-patch.sh for the OpenHands container.
4+
# Build-time patches are applied via apply-sdk-patches.py — see that file for the
5+
# active patch set. These patches MUST be at build time because PyInstaller
6+
# creates an immutable binary. Runtime patches are in docker/apply-startup.sh
7+
# for the OpenHands container.
78

89
# Stage 1: Build the binary
910
# LAST_UPDATED forces CDK to rebuild when bumped (picks up base image security patches)
10-
ARG LAST_UPDATED=2026-04-08
11+
ARG LAST_UPDATED=2026-05-14
1112
FROM python:3.12-slim-bookworm AS builder
1213

1314
# Install build dependencies
@@ -20,13 +21,16 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
2021
# Install uv for fast package management
2122
RUN pip install uv
2223

23-
# Clone the OpenHands SDK repository
24+
# Clone the OpenHands SDK repository.
25+
# Pinned to v1.19.1 alongside the OpenHands v1.7.0 upgrade (PR #81). The fork
26+
# patches in apply-sdk-patches.py are anchored against this exact version.
2427
WORKDIR /build
25-
RUN git clone --depth 1 --branch v1.15.0 https://github.com/OpenHands/software-agent-sdk.git .
28+
ARG SDK_VERSION=v1.19.1
29+
RUN git clone --depth 1 --branch ${SDK_VERSION} https://github.com/OpenHands/software-agent-sdk.git .
2630

2731
# Copy and run SDK patches
28-
# Patches 23, 25-27: Handle invalid/masked secrets + Bedrock max_output_tokens
29-
# See apply-sdk-patches.py for detailed documentation
32+
# Patches 23, 25-26, 28-32: secret-resume validators + Bedrock listing/region/env
33+
# See apply-sdk-patches.py for detailed documentation.
3034
COPY apply-sdk-patches.py /build/
3135
RUN python3 /build/apply-sdk-patches.py /build
3236

@@ -194,8 +198,8 @@ RUN id -u openhands 2>/dev/null || useradd -m -s /bin/bash openhands
194198
# Copy the built binary
195199
COPY --from=builder /build/dist/openhands-agent-server /usr/local/bin/openhands-agent-server
196200

197-
# Copy VSCode server from official agent-server image
198-
COPY --from=ghcr.io/openhands/agent-server:1.15.0-python /openhands/.openvscode-server /openhands/.openvscode-server
201+
# Copy VSCode server from official agent-server image (must track SDK_VERSION above)
202+
COPY --from=ghcr.io/openhands/agent-server:1.19.1-python /openhands/.openvscode-server /openhands/.openvscode-server
199203

200204
# Set permissions
201205
RUN chown -R openhands:openhands /openhands && \

0 commit comments

Comments
 (0)