Harness backend
OpenHands in HarnessRouter
HarnessRouter drives OpenHands through its maintained agent-server rather than the deprecated CLI, while UHP adoption and upstream OpenHands releases remain separate coordinates.
Current boundary
Section titled “Current boundary”OpenHands became a released HarnessRouter backend in v0.20.0 through PR #215, merged as 9ae33e77a92f240853e6d67a374c545d736c0f2d on 19 September 2026. Current HarnessRouter v0.23.10 retains the backend and still defaults to openhands-agent-server 1.49.2, openhands-tools 1.49.2, openhands-sdk 1.49.2 and LiteLLM 1.94.3.
This is HarnessRouter adapter support, not evidence that OpenHands natively implements UHP. Upstream OpenHands software has advanced separately: the OpenHands repository published v1.22.0 on 22 September 2026 and its release notes say it consumes SDK 1.49.4. HarnessRouter’s adapter pin remains the independently verified 1.49.2 line at the current cutoff.
Why HarnessRouter uses the agent server
Section titled “Why HarnessRouter uses the agent server”PR #215 deliberately uses the maintained openhands-agent-server REST/WebSocket surface rather than the older openhands CLI package. HarnessRouter preserves its normal one-process-per-turn ownership model: one server process is started for the turn, the runner reads normalized events from its driver, and cancellation terminates the process group.
Conversation state is durable across those short-lived server processes. The PR reports that a conversation created by one process can be read intact by another process over the same on-disk store, which is the property that makes recycled per-turn workers compatible with OpenHands continuation.
Identity, policy and secret boundaries
Section titled “Identity, policy and secret boundaries”The adapter treats several coordinates as persistent configuration rather than incidental request state:
- Conversation identity is policy-sensitive. The conversation id is derived from the effective tool policy and declared MCP servers because OpenHands freezes the agent when the conversation is first created. A later create with a different tool set does not mutate the persisted agent.
- Disabled tools are omitted. HarnessRouter does not rely on a prose refusal after a prohibited tool has been exposed; the tool is left out of the OpenHands specification.
- Provider credentials are not persisted in conversation state. PR #215 records the stored LLM specification with
api_key: None; the secret is delivered through the process environment. - Final output is event-shape aware. A successful answer may arrive through
FinishAction, so the driver does not assume that a trailing assistant-message event is the only terminal answer form.
These are OpenHands/HarnessRouter implementation details. They do not add new UHP fields or UHP conformance requirements.
The LiteLLM compatibility pin is intentional
Section titled “The LiteLLM compatibility pin is intentional”The OpenHands SDK telemetry path exposed a version interaction in which LiteLLM could mark cache_creation_tokens as set while the actual attribute was absent. On Google follow-up turns, that could raise an AttributeError after long execution with no useful reason reaching the stored turn record.
PR #215 pins LiteLLM 1.94.3 with OpenHands 1.49.2 and validates the required behavior rather than trusting the version string alone. The same work adds a failure-observability fallback that extracts the useful exception chain from the agent-server log when the WebSocket/event path terminates without publishing a reason.
The measured Google column changed from 29/40 before the corrected environment to 40/40 after under the PR’s stated conditions. This is adapter/provider-runtime evidence, not UHP conformance.
Other runtime constraints
Section titled “Other runtime constraints”The adapter also records two concrete environment constraints:
- OpenHands tools depend on the real
tmuxbinary, so the self-hosted image must include it. TMUX_TMPDIRis kept short because a workspace-derived socket path approached the Unixsun_pathlimit and turned a fast tool startup into repeated failures and very long turns.
OpenHands is opt-in rather than part of the default HR_BACKENDS set because the adapter environment is materially larger than the lightweight backends; PR #215 reports roughly 666 MB for that environment.
Evidence at introduction
Section titled “Evidence at introduction”PR #215 reports:
| Evidence | Result |
|---|---|
| Vercel model scenarios | 239/245 across 49 of the 50 catalog ids |
| Google / Gemini scenarios | 40/40 across eight ids after the compatibility correction |
| Custom harness | Own skill, script, tool policy and declared MCP server pass |
| Registration surface | All 17 expected registration points |
| TypeScript | tsc clean |
| Python suite | 976 passed versus origin/main’s 944, with the same 23 environment failures on both |
Those numbers establish the reviewed adapter/runtime paths only. They are not a UHP Full result and they do not establish universal provider/model compatibility.
Native-adoption boundary
Section titled “Native-adoption boundary”A useful statement is:
HarnessRouter
v0.20.0+can drive OpenHands through the maintained OpenHands agent-server.
A stronger statement such as “OpenHands implements UHP” is not established by the reviewed sources. The UHP server is HarnessRouter; OpenHands is the upstream harness behind that adapter.
Related pages
Section titled “Related pages”Read HarnessRouter, System One, Conformance, Ecosystem, Adoption and Release tracker.