Skip to navigation

Use the OpenHands Adapter

View as Markdown

Use the NVIDIA NeMo Fabric nvidia.fabric.openhands adapter to run tasks with the OpenHands SDK. The adapter keeps one OpenHands conversation alive for each NeMo Fabric runtime, so ordered invocations retain conversation context.

Install the Adapter

Install the tested OpenHands packages, then install the runtime and adapter:

pip install "openhands-sdk==1.50.0" "openhands-tools==1.50.0"
pip install "nemo-fabric[openhands]"

The 1.50.0 package pair is validated with NVIDIA NIM.

To install only the adapter, use:

pip install nemo-fabric-adapters-openhands

The adapter package supports Python 3.11 or later, while OpenHands requires Python 3.12 or later. The adapter packages do not install OpenHands.

Configure the Adapter

from nemo_fabric import EnvironmentConfig, FabricConfig, HarnessConfig
from nemo_fabric import InstructionConfig, InstructionsConfig, ModelConfig
from nemo_fabric import RuntimeConfig, ToolsConfig
config = FabricConfig(
harness=HarnessConfig(adapter_id="nvidia.fabric.openhands"),
models={
"default": ModelConfig(
provider="nvidia",
model="nvidia/nemotron-3-nano-omni-30b-a3b-reasoning",
api_key_env="NVIDIA_API_KEY",
base_url="https://integrate.api.nvidia.com/v1",
)
},
instructions=InstructionsConfig(
system=InstructionConfig(
content="Review the requested code change.",
mode="append",
)
),
tools=ToolsConfig(enabled=["terminal", "file_editor"]),
runtime=RuntimeConfig(max_turns=20),
environment=EnvironmentConfig(provider="local", workspace="."),
)

The adapter maps normalized model settings, replace and append system instructions, runtime.max_turns, tool policy, MCP servers, skills, and the workspace. Supported tool names are terminal (alias bash) and file_editor (alias edit). OpenHands retains its internal finish and reasoning tools.

For provider="nvidia", the adapter adds LiteLLM’s nvidia_nim/ dispatch prefix while preserving the served model ID, including its nvidia/ namespace. This also supports self-hosted NIM endpoints through base_url. An existing nvidia_nim/ prefix is retained once.

Skill paths resolve from the configuration base directory and must contain a SKILL.md file. The adapter disables ambient OpenHands user, public, project, and memory loading, so only explicitly configured NeMo Fabric skills load.

The adapter configures the OpenHands SDK standard summarizing condenser, default_condenser, with the agent model. When the history sent to the model exceeds 80 events, or exceeds the model input token limit when OpenHands knows it, OpenHands replaces older events with a model-generated summary and keeps the first 4 events. When the model rejects a request for exceeding its context window, OpenHands condenses the history and continues instead of failing the invocation. Summarization calls count toward invocation usage, and each condensation step counts toward runtime.max_turns. NeMo Fabric does not expose condenser tuning parameters.

To keep the full conversation history and make no summarization calls, set the condenser harness setting to none. The default value, default, enables the condenser, and any other value is rejected. The following example turns the condenser off:

from nemo_fabric import HarnessConfig
harness = HarnessConfig(
adapter_id="nvidia.fabric.openhands",
settings={"condenser": "none"},
)

The initial integration does not support Relay telemetry, native streaming, interactive confirmation, MCP authentication, or per-server MCP tool filters.

Understand the Runtime Lifecycle

The adapter runs the OpenHands SDK directly in a persistent Python adapter process. It does not start or connect to an OpenHands server. start creates one local conversation for the NeMo Fabric runtime, and ordered invocations reuse that conversation and its history.

Each invocation returns only the final response and usage for that turn. stop closes the conversation and removes the adapter-owned temporary profile state. Create a new runtime to change the model, workspace, tools, MCP servers, or skills.

The adapter requires invocation-local SDK token records before reporting usage. Missing records leave counters unknown, including requests that fail before the SDK observes usage. Recorded tokens remain available after a later failure. Cost remains unknown unless the SDK records a cost for every returned response; its zero-initialized accumulator does not establish a free request. Input tokens follow LiteLLM’s inclusive prompt_tokens convention. The adapter sets input_tokens_include_cache=true without adding cache tokens again or inventing a missing cache breakdown.

Run the Code Review Example

Set NVIDIA_API_KEY. For a source checkout, also point NeMo Fabric at the Python environment that contains the adapter and OpenHands packages:

export ADAPTER_PYTHON="$PWD/.venv/bin/python"

Then run:

.venv/bin/python -m examples.code_review_agent \
--variant openhands \
--input "Review calculator.py" \
--show-output

Do not combine the OpenHands variant with --relay.

Runtime Health

Fabric.check() supports live and active. Liveness observes the owned native conversation closure flags. Active requires completed native lazy initialization and can return unknown/capabilities_unverified before the first invocation. The adapter does not provide a qualified read-only ready check.

Refer to the SDK health-check overview for shared behavior and a comparison of native evidence across adapters.