Skip to content

✨ backends: add openhands as a T3 headless-only contributor backend - #10634

Merged
clubanderson merged 2 commits into
v5from
feat/openhands-backend
Oct 5, 2026
Merged

clubanderson merged 2 commits into
v5from
feat/openhands-backend

Conversation

@clubanderson

Copy link
Copy Markdown
Member

Summary

Related issues

Refs #6231 (backend acceptance bar). Related: #10625 #10626 #10627

Tier claimed

  • pod path: not claimed — openhands stays out of HEADLESS_BACKENDS / K8S_HEADLESS_BACKENDS; not installed in src/Dockerfile.contributor (image is bookworm/Python 3.11, OpenHands needs 3.12 — follow-up if wanted, with a pinned uv + uv tool install openhands==<ver>).
  • local path: T3 — refusal-gated (postureRefusalGated).

Safety flags

  • backend_perm_flag openhands → --always-approve --override-with-envs (verified: bash -c 'source config/backends.conf; backend_perm_flag openhands').
  • Both are argparse store_true flags (no value to be misparsed). --always-approve is mutually exclusive with --llm-approve (argparse group → exit 2 if both). --headless without -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-CLI openhands_cli/entrypoint.py, argparsers/util.py.
  • Refusal gate verified: unconfined_local_perm_flag_shell openhands exits 1 without the env var, emits the flags with HIVE_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 Backend ok.
  • go test ./pkg/dashboard/ — all backend/local-mode/matrix/teams tests pass. Two unrelated failures (TestAgentsCollapsedSummaryRendersPerAgentTiles, TestOpenAPISpecCoversEveryRegisteredRoute) reproduce identically on untouched v5 HEAD. Heads-up: pkg/dashboard currently panics at init on v5 HEAD (feedback.go:80 uses a (?= lookahead Go's regexp rejects — 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 -n on backends.conf / contributor-agent.sh; just --summary parses.
Adding or changing a CLI backend?
  • PR body states the claimed tier per launch path (pod / local).
  • List parity: KNOWN_BACKENDS, backend_binary, backend_perm_flag, config.CLIBackends (TestShellAndGoCLIBackendListsAgree passes).
  • Local posture declared and tested (localBackendPostures["openhands"] = postureRefusalGated; unconfined_local_backend_env_var; comment guard string updated).
  • Safety flags honored: see above.
  • Credential detection is honest (detect_cli probes LLM_API_KEY or settings.json, not --version alone).
  • Docs rows: docs/backend-setup.md, src/docs/sandbox-isolation.md, src/docs/contributor-relay.md (AGENT_BACKEND, env var, instruction-file, backend table rows).
  • Installs pinned: n/a — not added to any image.
  • Metering posture stated.

Contributor checklist

  • Changelog fragment changelog.d/added-openhands-backend.md
  • Targets v5
  • Emoji title
  • DCO sign-off
  • Docs updated
  • No secrets committed

@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign nicholasjackson for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added dco-signoff: yes Indicates the PR's author has signed the DCO. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Oct 5, 2026
@github-actions

github-actions Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Open PR overlap check

Base branch: v5

Conflicts are checked with every PR merged onto the current tip of v5, so a PR that only needs a rebase is not reported as conflicting with its siblings.

PR Title Relation Files
#10636 📖 docs: align Goose integration with AAIF upstream same files config/backends.conf
docs/backend-setup.md

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>
@hivecommons-hive

Copy link
Copy Markdown
Contributor

Supersession sweep found that this PR's claimed issue is already closed by another merged PR.

  • Claimed issue: hive#6231
  • Closing PR: #6299

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.

@clubanderson

Copy link
Copy Markdown
Member Author

CI note: the remaining red jobs are the pre-existing v5 baseline failures, each reproduced on untouched origin/v5 HEAD (0904d04) with no change from this PR:

  • TestAgentsCollapsedSummaryRendersPerAgentTiles and TestOpenAPISpecCoversEveryRegisteredRoute (pkg/dashboard)
  • TestStyleRatchet (pkg/dashboard/webstatic — static/index.html raw-padding 230 > baseline 229; this PR does not touch index.html)

Everything this PR touches is green: backend parity/posture tests, pkg/config, pkg/hub, relay JS tests, docs link/citation checks, lint, build. Rebased onto #10617 so the earlier hub/dashboard init panic is gone.

@clubanderson
clubanderson merged commit 18e4a36 into v5 Oct 5, 2026
55 of 61 checks passed
@kubestellar-prow
kubestellar-prow Bot deleted the feat/openhands-backend branch October 5, 2026 16:57
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

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

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant