Repository navigation
✨ backends: add openhands as a T3 headless-only contributor backend - #10634
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Open PR overlap checkBase branch: Conflicts are checked with every PR merged onto the current tip of
|
Wire the OpenHands CLI (PyPI openhands, MIT) through the contributor relay's headless path: openhands --headless -t "<prompt>" --always-approve --override-with-envs. --override-with-envs is deliberate — without it the CLI ignores LLM_API_KEY/LLM_BASE_URL/LLM_MODEL in favour of its persisted settings, so an env-only credential never reaches the agent. OpenHands has no --model flag, so AGENT_MODEL is forwarded as LLM_MODEL instead. The bare CLI has no sandbox, allowlist, or deny-list hive can wire (its Docker sandbox exists only behind openhands serve / Agent Canvas, which have no one-shot task shape), so it takes the #4918 refusal gate (HIVE_OPENHANDS_DANGEROUSLY_RUN_UNCONFINED), detect_cli probes the credential rather than trusting --version, and it stays out of the headless K8s allowlist and the contributor image (needs Python 3.12; the image is bookworm/3.11). Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Stage ~/.openhands/settings.json and forward LLM_API_KEY/LLM_BASE_URL/LLM_MODEL so detect_cli can succeed inside a derived image, matching the local-path contract (--override-with-envs). Signed-off-by: Andrew Anderson <andy@clubanderson.com>
6953d16 to
3cf0099
Compare
|
Supersession sweep found that this PR's claimed issue is already closed by another merged PR.
A different merged PR closed the claimed issue. Leaving this contributor PR open for a human to review. This comment is edited in place by the supersession sweep; it is not duplicated. |
|
CI note: the remaining red jobs are the pre-existing
Everything this PR touches is green: backend parity/posture tests, |
|
Thank you for your contribution! Your PR has been merged. We'd love to hear how your experience was: share feedback |
Summary
openhands(OpenHands CLI, PyPIopenhands, MIT) as a T3 experimental, headless-only contributor backend, followingsrc/docs/backend-support-tiers.md.openhands --headless -t "<prompt>" --always-approve --override-with-envs.--override-with-envsis required because the CLI otherwise ignoresLLM_API_KEY/LLM_BASE_URL/LLM_MODELin favour of~/.openhands/settings.json; OpenHands has no--modelflag, soAGENT_MODELis forwarded asLLM_MODEL(newheadlessChildEnv()in the relay,openhandsadded toNO_MODEL_FLAG_BACKENDS).HIVE_OPENHANDS_DANGEROUSLY_RUN_UNCONFINED(Default agent launch path is unconfined on the operator's host — an agent running an assigned repo's test suite reached my bootloader #4918 contract), honestdetect_cli(probesLLM_API_KEY/settings.json;--versionis an argparse version action that exits 0 with no credential), Justfile preflight, GoCLIBackends+ teams label, posture table +backends.confcomment guard, docs rows, changelog fragment.Related issues
Refs #6231 (backend acceptance bar). Related: #10625 #10626 #10627
Tier claimed
openhandsstays out ofHEADLESS_BACKENDS/K8S_HEADLESS_BACKENDS; not installed insrc/Dockerfile.contributor(image is bookworm/Python 3.11, OpenHands needs 3.12 — follow-up if wanted, with a pinneduv+uv tool install openhands==<ver>).postureRefusalGated).Safety flags
backend_perm_flag openhands→--always-approve --override-with-envs(verified:bash -c 'source config/backends.conf; backend_perm_flag openhands').store_trueflags (no value to be misparsed).--always-approveis mutually exclusive with--llm-approve(argparse group → exit 2 if both).--headlesswithout-t/-f→parser.error→ exit 2, so a mis-built argv fails loudly rather than opening the TUI. Headless mode forces always-approve regardless (docs.openhands.dev/openhands/usage/cli/headless). Source:OpenHands/OpenHands-CLIopenhands_cli/entrypoint.py,argparsers/util.py.unconfined_local_perm_flag_shell openhandsexits 1 without the env var, emits the flags withHIVE_OPENHANDS_DANGEROUSLY_RUN_UNCONFINED=1.Metering posture
Unmetered on this path (OpenHands reports usage to its own conversation store, not to hive's sinks). Budget-gated hives should treat it as unmetered — same as the other T3 relay-only CLIs.
Testing
node bin/contributor-relay.test.js: 600/680 (baseline on this macOS host: 598/678 — the 80 failures are pre-existing tmux/env-dependent; the 2 new openhands tests pass).go test ./pkg/config/ok;go test ./pkg/agent/ -run Backendok.go test ./pkg/dashboard/— all backend/local-mode/matrix/teams tests pass. Two unrelated failures (TestAgentsCollapsedSummaryRendersPerAgentTiles,TestOpenAPISpecCoversEveryRegisteredRoute) reproduce identically on untouchedv5HEAD. Heads-up:pkg/dashboardcurrently panics at init on v5 HEAD (feedback.go:80uses a(?=lookahead Go'sregexprejects — from 🐛 feedback: attribute dashboard feedback issues to the submitter #10593); I patched it locally only to run the suite and did not include that change.bash -nonbackends.conf/contributor-agent.sh;just --summaryparses.Adding or changing a CLI backend?
pod/local).KNOWN_BACKENDS,backend_binary,backend_perm_flag,config.CLIBackends(TestShellAndGoCLIBackendListsAgreepasses).localBackendPostures["openhands"] = postureRefusalGated;unconfined_local_backend_env_var; comment guard string updated).detect_cliprobesLLM_API_KEYorsettings.json, not--versionalone).docs/backend-setup.md,src/docs/sandbox-isolation.md,src/docs/contributor-relay.md(AGENT_BACKEND, env var, instruction-file, backend table rows).Contributor checklist
changelog.d/added-openhands-backend.mdv5