Skip to content
UHPUHPDeveloper Guide
Independent resource · Not affiliated with HarnessRouter · Site data checked 23 Sep 2026

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.

Verified: HarnessRouter: v0.23.10Static SSG

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.

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.

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.

The adapter also records two concrete environment constraints:

  • OpenHands tools depend on the real tmux binary, so the self-hosted image must include it.
  • TMUX_TMPDIR is kept short because a workspace-derived socket path approached the Unix sun_path limit 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.

PR #215 reports:

EvidenceResult
Vercel model scenarios239/245 across 49 of the 50 catalog ids
Google / Gemini scenarios40/40 across eight ids after the compatibility correction
Custom harnessOwn skill, script, tool policy and declared MCP server pass
Registration surfaceAll 17 expected registration points
TypeScripttsc clean
Python suite976 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.

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.

Read HarnessRouter, System One, Conformance, Ecosystem, Adoption and Release tracker.