Add lock-to-cloud backend setup mode#1389
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
🛑 Mock-LLM E2E Tests6/6 passed · Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
🛑 Mock-LLM E2E Tests8/13 passed · 1 failed · 4 skipped · Commit:
🔍 Failure details (1)❌ chromium › backends/mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configuredPosted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
❌ Mock-LLM E2E Tests55/60 passed · 1 failed · 4 skipped Commit:
🔍 Failure details (1)❌ backends/mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configuredPosted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
❌ Mock-LLM E2E Tests52/60 passed · 3 failed · 5 skipped Commit:
🔍 Failure details (3)❌ backends/mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured⏱️ onboarding/mock-llm-onboarding-happy-path.spec.ts › onboarding happy path › completes the full onboarding flow and launches a conversation❌ onboarding/mock-llm-onboarding-regressions.spec.ts › onboarding recent regressions › defaults the LLM setup step to OpenAI GPT-5.5Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
❌ Mock-LLM E2E Tests53/60 passed · 3 failed · 4 skipped Commit:
🔍 Failure details (3)❌ backends/mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error⏱️ onboarding/mock-llm-onboarding-happy-path.spec.ts › onboarding happy path › completes the full onboarding flow and launches a conversation❌ onboarding/mock-llm-onboarding-regressions.spec.ts › onboarding recent regressions › defaults the LLM setup step to OpenAI GPT-5.5Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
❌ Mock-LLM E2E Tests57/60 passed · 2 failed · 1 skipped Commit:
🔍 Failure details (2)⏱️ onboarding/mock-llm-onboarding-happy-path.spec.ts › onboarding happy path › completes the full onboarding flow and launches a conversation❌ onboarding/mock-llm-onboarding-regressions.spec.ts › onboarding recent regressions › defaults the LLM setup step to OpenAI GPT-5.5Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
✅ Mock-LLM E2E Tests60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
✅ Mock-LLM Docker E2E Test Results60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
e81bcd6 to
012625d
Compare
6f994e3 to
42af044
Compare
✅ Mock-LLM E2E Tests60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
✅ Mock-LLM Docker E2E Test Results60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
…-to-cloud-backend
✅ Mock-LLM E2E Tests60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
✅ Mock-LLM Docker E2E Test Results60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
✅ Mock-LLM E2E Tests60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
hieptl
left a comment
There was a problem hiding this comment.
Hello @neubig,
I followed the steps below and noticed a potential issue:
Step 1: Delete the ~/.openhands directory.
Step 2: Check out the lock-to-cloud-backend branch.
Step 3: Run npm i.
Step 4: Run the following command:
node /Users/hieple/Documents/openhands/agent-server-gui/scripts/static-server.mjs --lock-to-cloud https://app.all-hands.dev
Static-server + proxy listening on http://:::3001/
Static dir: /Users/hieple/Documents/openhands/agent-server-gui/build
Backend setup locked to Cloud: https://app.all-hands.dev
* (default) -> static files + SPA fallbackThen, navigate to http://localhost:3001.
In my case, the Add Backend modal appears first. Is this the expected behavior?
Please see the attached image for additional context.
Thank you very much! 🙏
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
…-to-cloud-backend # Conflicts: # __tests__/components/onboarding/onboarding-modal.test.tsx
🛑 Mock-LLM E2E Tests1/1 passed · Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
…-to-cloud-backend
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
|
| Status | Test | Duration |
|---|
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)
✅ Mock-LLM E2E Tests60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
✅ Mock-LLM Docker E2E Test Results60/60 passed Commit:
Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses) |
|
✅ Review complete. This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here. |
all-hands-bot
left a comment
There was a problem hiding this comment.
🟡 Acceptable — Works well with good test coverage and manual QA evidence. One unused exported function to clean up.
The implementation is clean: the dual config path (VITE_LOCK_TO_CLOUD env var at compile time + window.__AGENT_CANVAS_LOCK_TO_CLOUD__ runtime injection) is the right design for pre-built/frontend-only deployments, and the normalizeCloudHost() helper correctly handles scheme normalization and trailing-slash stripping. The dynamic onboarding step indices are well-tracked and the test coverage across unit, component, and e2e layers is solid.
[IMPROVEMENT OPPORTUNITIES]
[src/api/agent-server-config.ts, Line 103]Dead export:isLockedToCloud()is exported but never imported anywhere in the codebase. Every consumer callsgetLockedCloudHost() !== nulldirectly (e.g.root.tsxline 182). Either use it consistently or remove it — an exported function that's unused is dead code that adds to the module's surface area without benefit.
[STYLE NOTES]
[src/components/features/onboarding/onboarding-modal.tsx, Line 130]Subtle coupling:hideSkip = currentStep === 0 && getLockedCloudHost() !== nullassumes the backend step is always at index 0 when the modal is locked to cloud. This holds in the current code becauseskipBackendStepcan only betruewhen a backend is already healthy, which prevents the locked onboarding from showing in the first place. But the invariant isn't obvious from the variable name alone — a comment like// step 0 is the backend step whenever this modal is shown in locked modewould help future readers avoid accidentally breaking it.
[RISK ASSESSMENT]
- [Overall PR]
⚠️ Risk Assessment: 🟢 LOW
Feature is purely additive and opt-in via a new config flag. No existing behavior is affected whenVITE_LOCK_TO_CLOUDis unset (the default). Changes to the onboarding step-skipping logic are protected by the new unit and component tests. The parent-branch changes (fix-public-onboarding) are already reviewed separately.
VERDICT:
✅ Worth merging — core logic is sound, single minor cleanup (unused isLockedToCloud export) suggested.
KEY INSIGHT:
The dual compile-time/runtime injection pattern is the right approach for pre-built static deployments where you can't bake env vars in — runtime injection via static-server.mjs is the escape hatch that keeps the Docker image generic.
Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:
- Add a
.agents/skills/custom-codereview-guide.mdfile to your branch (or edit it if one already exists) with the/codereviewtrigger and the context the reviewer is missing (e.g., "Security concerns about X do not apply here because Y"). See the customization docs for the required frontmatter format.- Re-request a review - the reviewer reads guidelines from the PR branch, so your changes take effect immediately.
- When your PR is merged, the guideline file goes through normal code review by repository maintainers.
Resolve with AI? Install the iterate skill in your agent and run
/iterateto automatically drive this PR through CI, review, and QA until it's merge-ready.Was this review helpful? React with 👍 or 👎 to give feedback.
This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation
| return null; | ||
| } | ||
|
|
||
| export function isLockedToCloud(): boolean { |
There was a problem hiding this comment.
🟡 Suggestion: isLockedToCloud() is exported but has zero imports in the codebase — every callsite uses getLockedCloudHost() !== null directly. Remove it or replace the direct calls with this helper to keep the API surface intentional.
HUMAN:
I tested this manually and it works as expected, only showing the cloud login when this option is present.
AGENT:
Why
Frontend-only/public deployments sometimes need backend setup locked to one OpenHands Cloud URL so users cannot configure arbitrary local or custom backend targets during onboarding or Add Backend.
Fixes #1392.
Summary
VITE_LOCK_TO_CLOUD=<cloud-url>configuration for locking backend setup to a single OpenHands Cloud URL.scripts/static-server.mjs --lock-to-cloud <cloud-url>support for pre-built/frontend-only deployments.fix-public-onboardingparent branch intolock-to-cloud-backend.Stacked on #1385. Current stack heads: parent
e81bcd6a, child6f994e3b.How to Test
PATH=/usr/bin:$PATH npm run typecheckPATH=/usr/bin:$PATH npm run test -- __tests__/api/agent-server-config.test.ts __tests__/components/backends/backend-form-modal.test.tsx __tests__/components/onboarding/onboarding-modal.test.tsx __tests__/scripts/static-server.test.ts __tests__/root.test.tsxPATH=/usr/bin:$PATH npm run buildManual QA
--lock-to-cloud https://app.all-hands.devonhttps://work-2-tuizajshdoegydst.prod-runtime.all-hands.dev/: first-run onboarding shows only OpenHands Cloud login, with no local backend form and no Advanced custom Cloud URL field.This PR description was updated by an AI agent (OpenHands) on behalf of the user.
🐳 Docker images for this PR
• GHCR package: https://github.com/OpenHands/agent-canvas/pkgs/container/agent-canvas
ghcr.io/openhands/agent-canvasghcr.io/openhands/agent-server:1.28.1-pythonopenhands-automation==1.0.0a106e7bac6faf13e0fa1e6fa98c975cdc56bcfddd7bPull (multi-arch manifest)
# Multi-arch manifest — Docker automatically pulls the correct architecture docker pull ghcr.io/openhands/agent-canvas:sha-6e7bac6Run
All tags pushed for this build
About Multi-Architecture Support
sha-6e7bac6) is a multi-arch manifest supporting both amd64 and arm64sha-6e7bac6-amd64) are also available if needed