Skip to content

Support remote agent server backends#1005

Open
neubig wants to merge 6 commits into
mainfrom
fix/remote-agent-server-backends
Open

Support remote agent server backends#1005
neubig wants to merge 6 commits into
mainfrom
fix/remote-agent-server-backends

Conversation

@neubig
Copy link
Copy Markdown
Member

@neubig neubig commented Jun 1, 2026

Summary

  • Add a distinct remote backend kind for standalone agent servers while preserving local for the canvas-managed agent server and cloud for OpenHands Cloud.
  • Route remote backends through the same direct agent-server code paths as local backends, including health/version checks, settings, model/profile setup, git/workspace queries, MCP/repo flows, and onboarding setup.
  • Keep Cloud behavior separate, requiring API keys only for Cloud hosts and narrowing Cloud host inference so hosted/tunneled agent-server URLs are treated as remote.
  • Return a clear automation-health message for remote backends because standalone agent servers do not include the local automation sidecar.

QA

  • npm run typecheck
  • npx vitest run __tests__/components/backends/add-backend-modal.test.tsx --reporter=verbose
  • npm test (initial full-suite run hit two expected port-conflict failures because the QA mock LLM was occupying port 9999)
  • npx vitest run __tests__/scripts/dev-safe.test.ts __tests__/scripts/ingress.test.ts after freeing port 9999
  • npm run build
  • Browser QA with mock LLM:
    • Local path: npm run dev canvas-managed agent server, mock LLM profile, conversation created, agent response received.
    • Remote path: separate standalone agent server on port 12001 with CORS/session API key, remote backend added from the UI, mock LLM profile, conversation created, agent response received.

Demos

Local canvas-managed agent server

Local backend setup and conversation

Remote standalone agent server

Remote backend setup and conversation

This PR was created 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

Component Value
Image ghcr.io/openhands/agent-canvas
Architectures amd64, arm64
Agent Server ghcr.io/openhands/agent-server:1.24.0-python
Automation openhands-automation==1.0.0a5
Commit c5b59324ad659d186f887af220240339c87ea761

Pull (multi-arch manifest)

# Multi-arch manifest — Docker automatically pulls the correct architecture
docker pull ghcr.io/openhands/agent-canvas:sha-c5b5932

Run

docker run -it --rm \
  -p 8000:8000 \
  ghcr.io/openhands/agent-canvas:sha-c5b5932

All tags pushed for this build

ghcr.io/openhands/agent-canvas:sha-c5b5932-amd64
ghcr.io/openhands/agent-canvas:fix-remote-agent-server-backends-amd64
ghcr.io/openhands/agent-canvas:pr-1005-amd64
ghcr.io/openhands/agent-canvas:sha-c5b5932-arm64
ghcr.io/openhands/agent-canvas:fix-remote-agent-server-backends-arm64
ghcr.io/openhands/agent-canvas:pr-1005-arm64
ghcr.io/openhands/agent-canvas:sha-c5b5932
ghcr.io/openhands/agent-canvas:fix-remote-agent-server-backends
ghcr.io/openhands/agent-canvas:pr-1005

About Multi-Architecture Support

  • Each tag (e.g., sha-c5b5932) is a multi-arch manifest supporting both amd64 and arm64
  • Docker automatically pulls the correct architecture for your platform
  • Individual architecture tags (e.g., sha-c5b5932-amd64) are also available if needed

Co-authored-by: openhands <openhands@all-hands.dev>
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agent-canvas Ready Ready Preview, Comment Jun 2, 2026 12:07am

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

PR Artifacts Cleaned Up

The .pr/ directory has been removed after approval.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

✅ Mock-LLM Docker E2E Test Results

12/12 passed

Commit: 078f161b · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.4s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.8s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.5s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 466ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 29.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.2s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 3.7s

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

Co-authored-by: openhands <openhands@all-hands.dev>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

✅ Mock-LLM Docker E2E Test Results

12/12 passed

Commit: 4fc2dc9d · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.4s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.4s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 199ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 28.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 3.7s

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

Copy link
Copy Markdown
Contributor

all-hands-bot commented Jun 1, 2026

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Acceptable — The three-way backend split (local / remote / cloud) is the right model, and the isAgentServerBackend() guard applied consistently across 15+ files is a clean abstraction. No critical issues. A few improvement opportunities and a stale name worth cleaning up.


Summary

This PR introduces a remote BackendKind for standalone agent-server URLs, keeping local for the canvas-managed bundled server and cloud for OpenHands Cloud. The central isAgentServerBackend() predicate unifies local and remote for code paths that apply to both, while keeping Cloud-only paths narrow. The approach is sound and applied consistently.


Improvement Opportunities

1. Dead code in recommended-automations-launcher.tsx (lines 118–120)

The component hard-guards on line 217 with if (activeBackend.backend.kind !== "local") return null, so handleSelectAutomation is never attached to any DOM element for remote backends. The kind === "remote" ? "local" : kind ternary passed to buildAutomationPrompt is therefore unreachable. It's harmless, but it creates a confusing "what if?" reading of the code.

Two clean options:

  • Remove the guard-mapped ternary and just pass activeBackend.backend.kind as "local" | "cloud" — TypeScript is already happy since the early-return guard narrows kind to "local".
  • If the intent is to eventually support remote backends here, add a // TODO: comment explaining when this branch would be live.

2. Stale function name pickLocalBackend (active-store.ts, line 31)

The function now finds the first agent-server backend (local or remote). The name pickLocalBackend implies it only returns local backends, which will mislead future readers. pickAgentServerBackend or pickFallbackBackend would be accurate.

3. CLOUD_BACKEND_HOSTS is a static allowlist (backend-form-modal.tsx, line 38)

The set-based check is a real improvement over the prior substring match — it avoids false positives on tunneled/hosted agent-server URLs like work-2-xxx.prod-runtime.all-hands.dev. The trade-off is that any new canonical Cloud hostname (e.g. a future eu.app.all-hands.dev) requires a code change here. Worth a short comment to make the maintenance contract explicit.

4. Stale JSDoc in auth.ts

The line "Local agent-server uses X-Session-API-Key" is now incomplete — remote agent-server backends also use X-Session-API-Key (the fallback case on line 28). Suggest updating to:

Local and remote agent-servers use X-Session-API-Key. Cloud expects a bearer token in the Authorization header.

5. i18n/translation.json — all non-English locales stub to "Remote"

Acceptable placeholder, but worth opening a follow-up issue so the untranslated string doesn't get lost.

6. Unrelated fix bundled in this branch (dropdown.tsx)

The useEffect cleanup for closeTimerRef is a good fix (prevents a timer leak on unmount) but is unrelated to the remote backend feature. Not a blocker, but worth a note in the commit message so it doesn't get lost in future bisects.


Testing

The new test "treats hosted non-cloud agent server URLs as remote" directly exercises inferKindFromHost through the UI, which is the most important new logic in this PR. ✅

The existing tests updated kind: "local"kind: "remote" correctly reflect the new semantic. ✅

Not tested (non-blocking given the browser QA in the PR description):

  • isAgentServerBackend() directly — trivial, but a unit test would document the contract
  • The use-automation-health short-circuit for the remote kind
  • getEffectiveLocalBackend when the active backend is remote

Risk Assessment

  • Overall PR ⚠️ Risk: 🟢 LOW
    • Frontend-only change. No existing local or cloud paths are altered — the new remote kind is additive. TypeScript enforces exhaustiveness at call sites. The isAgentServerBackend predicate is simple and correctly replaces all direct kind === "local" checks.

VERDICT:Worth merging. The design is correct and the implementation is consistent. The items above are all non-blocking cleanups; they can go in a follow-up.


Improve this review? If any feedback above seems incorrect or irrelevant to this repository, you can teach the reviewer to do better:

  1. Add a .agents/skills/custom-codereview-guide.md file to your branch (or edit it if one already exists) with the /codereview trigger and the context the reviewer is missing. See the customization docs for the required frontmatter format.
  2. Re-request a review — the reviewer reads guidelines from the PR branch, so your changes take effect immediately.

Was this review helpful? React with 👍 or 👎.

This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

Comment thread src/components/features/automations/recommended-automations-launcher.tsx Outdated
Comment thread src/api/backend-registry/active-store.ts Outdated
Comment thread src/components/features/backends/backend-form-modal.tsx
Co-authored-by: openhands <openhands@all-hands.dev>
Copy link
Copy Markdown
Member Author

neubig commented Jun 1, 2026

Addressed review cleanup in b0c30c4: removed the unreachable remote automation prompt mapping, renamed the fallback picker, documented the Cloud host allowlist, and updated agent-server auth docs. CI is re-running on the new SHA.\n\n_This comment was created by an AI agent (OpenHands) on behalf of the user._

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

✅ Mock-LLM Docker E2E Test Results

12/12 passed

Commit: b0c30c4f · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.8s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.4s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.8s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.5s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 467ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 29.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.2s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.2s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 3.7s

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

@neubig neubig requested a review from all-hands-bot June 1, 2026 23:39
Copy link
Copy Markdown
Contributor

all-hands-bot commented Jun 1, 2026

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — Support remote agent server backends

The overall design is clean and well-reasoned. The isAgentServerBackend() helper avoids scattering kind === "local" || kind === "remote" checks across the codebase, and the CLOUD_BACKEND_HOSTS allowlist is a more robust approach than the previous substring match. The local/remote/cloud taxonomy is clearly motivated by the PR description and the QA demos back it up.

Three items worth addressing before merge:

  1. Missing test for the core new path in use-automation-health. The remote-backend short-circuit (returning a synthetic error without calling checkHealth) is the most novel behaviour in this PR and has no unit test.
  2. Stale variable name locals in backend-selector.tsx now silently includes remote backends.
  3. Implicit mapping of remote → local in the marketplace utility could use a one-line comment so future readers don't have to reverse-engineer the intent.

This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

Comment thread src/hooks/query/use-automation-health.ts
Comment thread src/components/features/backends/backend-selector.tsx Outdated
Comment thread src/components/features/backends/backend-selector.tsx Outdated
Comment thread src/utils/mcp-marketplace-utils.ts Outdated
Co-authored-by: openhands <openhands@all-hands.dev>
Copy link
Copy Markdown
Member Author

neubig commented Jun 1, 2026

Addressed the changes requested in 966a319: added remote automation-health coverage, renamed the backend selector collection to agentServers, and documented the remote marketplace availability mapping. Re-requesting review now.\n\n_This comment was created by an AI agent (OpenHands) on behalf of the user._

Copy link
Copy Markdown
Contributor

all-hands-bot commented Jun 1, 2026

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — Support remote agent server backends

All three items from the previous CHANGES_REQUESTED review have been resolved:

  • use-automation-health.test.tsx now covers the remote backend short-circuit (returns a synthetic error without calling checkHealth)
  • locals renamed to agentServers in backend-selector.tsx
  • ✅ The remote → local availability mapping in mcp-marketplace-utils.ts is now commented inline

All six first-pass suggestions from the initial review were also addressed in b0c30c4 (dead code removed, stale pickLocalBackend renamed, CLOUD_BACKEND_HOSTS comment added, JSDoc updated). The overall design is clean — the isAgentServerBackend() predicate applied consistently across 15+ files is far better than scattering kind === "local" || kind === "remote" checks, and the tighter CLOUD_BACKEND_HOSTS allowlist correctly treats tunnelled runtime URLs as remote agent servers rather than Cloud.


Remaining minor items

1. isAgentServerBackend should be a TypeScript type predicate

The function is declared to return boolean but callers cannot benefit from type narrowing. Typing it as a predicate would let TypeScript narrow backend.kind automatically at every call site:

export function isAgentServerBackend(
  backend: Pick<Backend, "kind">,
): backend is Pick<Backend, "kind"> & { kind: "local" | "remote" } {
  return backend.kind === "local" || backend.kind === "remote";
}

2. isLocalBackend / isLocal variable names are now misleading at 7 call sites

After this change, const isLocalBackend = isAgentServerBackend(backend) is true for both local and remote backends. The name implies a local-only check and will mislead future maintainers. Consider renaming the local variables to isAgentServer at each call site, or adding a brief comment.

Affected files: git-control-bar.tsx, home-chat-launcher.tsx, use-model-interceptor.ts, setup-llm-step.tsx, use-has-git-commits.ts, use-local-git-info.ts, use-workspace-session.ts.

3. BACKEND$KIND_REMOTE i18n is stubbed as "Remote" across all 14 non-English locales

Worth a follow-up issue before shipping so translators can address it.

4. dropdown.tsx timer-cleanup fix is still bundled in this branch

Good fix, but unrelated to remote agent-server support. Harmless here; just worth noting for the record.


None of the above are blockers. The implementation is correct, tests cover the new code paths, and browser QA was performed on both the local and remote flows.

This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

Comment thread src/api/backend-registry/types.ts
Comment thread src/components/features/chat/git-control-bar.tsx
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

❌ Mock-LLM Docker E2E Test Results

11/12 passed · 1 failed

Commit: 966a319d · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.5s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.5s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.5s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 231ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 28.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.4s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.4s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 204ms
🔍 Failure details (1)

❌ mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away

Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:18300/
Call log:
  - navigating to "http://localhost:18300/", waiting until "domcontentloaded"

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

✅ Mock-LLM Docker E2E Test Results

12/12 passed

Commit: 80f358b2 · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.8s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.4s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.8s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.5s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 508ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 29.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.2s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.4s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.5s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 3.7s

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

Co-authored-by: openhands <openhands@all-hands.dev>
Copy link
Copy Markdown
Member Author

neubig commented Jun 2, 2026

Addressed the latest suggestions in c5b5932: isAgentServerBackend is now a type predicate, and the local-named booleans that apply to both local and remote agent-server backends were renamed to usesAgentServerBackend.

This comment was created by an AI agent (OpenHands) on behalf of the user.

Copy link
Copy Markdown
Contributor

all-hands-bot commented Jun 2, 2026

Review complete.

This review was performed through OpenHands Cloud Automation. You can log in and view the conversation here.

Copy link
Copy Markdown
Contributor

@all-hands-bot all-hands-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — Support remote agent server backends

This is a clean, well-executed feature. The three-way split (local / remote / cloud) is the right model, and the isAgentServerBackend() type predicate now provides proper TypeScript narrowing at every call site. All three rounds of prior feedback have been addressed.

What's good:

  • isAgentServerBackend() as a type predicate cleanly centralises the local || remote check across 15+ files without scattering kind === "local" || kind === "remote" conditionals.
  • CLOUD_BACKEND_HOSTS allowlist with its maintenance comment correctly prevents false positives for work-* tunnel URLs that share the all-hands.dev domain.
  • useAutomationHealth returns a clear synthetic error for remote backends without hitting the sidecar, and the new test case covers that path.
  • The inferKindFromHost fallback to "remote" on parse errors is the right defensive default.
  • The Dropdown timer cleanup on unmount is a good hygiene fix.

One minor gap (non-blocking):

The new BACKEND$KIND_REMOTE i18n key ships with all non-English locales set to the English literal "Remote". Compare with BACKEND$KIND_LOCAL which has proper translations ("ローカル", "本地", "원격", etc.). "Remote" is recognisable across most locales, so this won't break anything, but it creates inconsistency with the other backend-kind labels. Worth filing a follow-up to add translations.

This review was generated by an AI agent (OpenHands) on behalf of the user through OpenHands Automation. View conversation

Comment thread src/i18n/translation.json
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

❌ Mock-LLM Docker E2E Test Results

11/12 passed · 1 failed

Commit: c5b59324 · Workflow run · Test artifacts

Status Test Duration
mock-llm-auth-modes.spec.ts › auth mode: non-public key rotation › recovers when localStorage has a stale session API key 3.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › shows the auth screen when no key is configured 1.2s
mock-llm-auth-modes.spec.ts › auth mode: public gate › rejects an incorrect key with an inline error 1.4s
mock-llm-auth-modes.spec.ts › auth mode: public gate › allows access after pasting the correct key 1.7s
mock-llm-auth-modes.spec.ts › auth mode: public gate › re-prompts when the server rotates its key (stale localStorage) 1.4s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 1: setup LLM profile and register automation trajectory 213ms
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 2: create automation and dispatch run via the UI 29.7s
mock-llm-automation.spec.ts › mock-LLM automation lifecycle › step 3: verify automation and run on the automations page 4.1s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 1: create an LLM profile pointing at the mock LLM server 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 2: activate the mock-llm profile and verify settings API 4.4s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 3: run a conversation with the mock LLM 4.3s
mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away 211ms
🔍 Failure details (1)

❌ mock-llm-conversation.spec.ts › mock-LLM agent-server conversation › step 4: resume conversation from sidebar after navigating away

Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:18300/
Call log:
  - navigating to "http://localhost:18300/", waiting until "domcontentloaded"

Posted by the Mock-LLM E2E workflow · results are deterministic (scripted LLM responses)

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

📸 Snapshot Test Report

✅ All snapshots match the main branch baselines.

Category Count
🔴 Changed 0
🆕 New 0
✅ Unchanged 73
Total 73
✅ Unchanged snapshots (73)

archived-conversation

  • conversation-panel-with-archived-badges
  • conversation-view-archived
  • conversation-view-sandbox-error

automations

  • automations-delete-modal
  • automations-list-active-inactive
  • automations-no-automations
  • automations-search-no-results

backends-extended

  • backend-add-blank-disabled
  • backend-add-cloud-advanced-open
  • backend-add-cloud-no-key-disabled
  • backend-add-cloud-with-key-enabled
  • backend-add-form-partially-filled
  • backend-add-invalid-url-disabled
  • backend-add-local-ready
  • backend-add-name-only-disabled
  • backend-add-two-column-layout
  • backend-add-whitespace-host-disabled
  • backend-after-switch
  • backend-cancel-nothing-saved
  • backend-dropdown-two-backends
  • backend-edit-prefilled
  • backend-manage-after-removal
  • backend-manage-two-listed
  • backend-remove-cancelled
  • backend-remove-confirmation
  • backend-switch-overlay

backends

  • backend-add-modal
  • backend-manage-modal
  • backend-selector-open

changes-tab

  • changes-deleted-file
  • changes-diff-viewer
  • changes-empty

collapsible-thinking

  • reasoning-content-collapsed
  • reasoning-content-expanded
  • think-action-collapsed
  • think-action-expanded

mcp-page

  • mcp-custom-server-1-editor-open
  • mcp-custom-server-2-url-filled
  • mcp-custom-server-3-all-filled
  • mcp-custom-server-4-installed
  • mcp-custom-server-editor
  • mcp-empty-installed
  • mcp-search-filtered
  • mcp-slack-install-1-marketplace
  • mcp-slack-install-2-modal
  • mcp-slack-install-3-filled
  • mcp-slack-install-4-installed

onboarding

  • onboarding-step-0-choose-agent
  • onboarding-step-1-check-backend
  • onboarding-step-2-setup-llm
  • onboarding-step-3-say-hello

projects-workspace-browser

  • projects-workspace-browser

settings-page

  • add-backend-modal
  • analytics-consent-modal
  • home-screen
  • settings-app-page
  • settings-page

settings-secrets

  • secrets-add-form-filled
  • secrets-add-form
  • secrets-after-save
  • secrets-delete-confirm
  • secrets-list

settings-verification

  • condenser-settings
  • verification-settings-off
  • verification-settings-on

sidebar

  • sidebar-collapsed
  • sidebar-conversation-panel
  • sidebar-filter-menu

skills-page

  • skills-empty
  • skills-loaded
  • skills-no-match
  • skills-search-filtered
  • skills-type-filter

Generated by the Snapshot Tests workflow. This comment was created by an AI agent (OpenHands) on behalf of the repo maintainers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants