Skip to content

Each client declares which ACP harnesses it offers — adding one to the SDK must not reach Cloud or Replicated #4841

Description

@simonrosenberg

Important

Rewritten 2026-09-04. Filed as an open design question (options A–D); the decision is below. Requirement: adding an ACP harness to the SDK must not change Cloud or Replicated behaviour.

Problem

ACP_PROVIDERS declares what exists. Nothing declares what a deployment offers, so registry membership leaks straight into product surfaces.

Enterprise republishes the whole registry unfiltered:

# openhands/app_server/web_client/default_web_client_config_injector.py:320-335
acp_providers = [... for provider in ACP_PROVIDERS.values()]   # no filter

frontend/src/routes/agent-settings.tsx:97 renders it. Enterprise pins openhands-sdk==1.44.1, which predates Kimi (#4714) and Pi (#4419) — so the next routine bump puts both in Cloud Settings → Agent with no brand mark, no secret fields, no credential preflight, and a KIMI_API_KEY that per #4819 does not authenticate on its own.

Cloud legitimately differs from OSS: headless credential shape (#4629, #4819), image size (#4624 is 518 MiB, #4639 ~123 MB), install shape (#4823), licensing (#4644).

Decision

Each client declares the harnesses it offers and enforces that at conversation start. The SDK stays a registry and carries no deployment policy.

Client Declares Posture
Cloud / Replicated (OpenHands/enterprise) CLOUD_ACP_PROVIDERS, hardcoded — operators cannot widen claude-code, codex, gemini-cli
Canvas / OSS (OpenHands/OpenHands) ACP_PROVIDER_UI everything registered; missing branding degrades to a generic tile
Evaluation (OpenHands/benchmarks) derived from the registry (#4833) everything; one harness per run

Adding a harness is an OSS-and-eval event. Cloud enablement is a separate, deliberate issue.

A UI filter alone is not enough. ACPServerKind widens with the registry, so a persisted setting, an org-settings value (#14675/#14678), an agent profile or a direct API call will validate a harness the client does not offer. Filter and fail closed.

Why not the alternatives. A cloud_supported field on ACPProviderInfo puts deployment policy in a library that also serves OSS and eval, where the answer differs. Deriving from image contents does not work — #4805's npx fallback runs an absent npm provider anyway. A runtime capability endpoint cannot serve the app server's global web-client config, which is emitted before any sandbox exists.

Acceptance Criteria

Open question. Cloud's free-text acp_command field launches any ACP server regardless of the allowlist. Gate it, or accept that the list governs the picker and not the escape hatch — product call.

Out of scope

Support for any particular harness (#4819, #4639, #4635, #4624) and the non-npm install mechanism (#4823).

Related: #4820 · #4833 · #4832 · #4805 · #4643 · #4644 · OpenHands/enterprise#315

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    acpAbout ACPenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions