Agentic Environments in Miles: Harbor, HUD, NeMo Gym & OpenEnv Integration Guide
Miles supports four agentic environments—Harbor, HUD, NeMo Gym, and OpenEnv—each integrated through lightweight HTTP adaptors that translate Miles' sampling API into environment-specific protocols while preserving reward computation and metadata flow.
The Miles reinforcement learning framework treats diverse agentic evaluation suites as interchangeable backends. By wrapping Harbor, HUD, NeMo Gym, and OpenEnv with thin adaptor modules, Miles enables seamless agentic environment integration for GRPO training without modifying core rollout logic. Each adaptor follows a consistent request-response pattern: resolve the Miles session URL, build a parameterized request dict, POST via async HTTP, and normalize the JSON response into Miles' Sample schema.
Harbor Integration: Agent Server HTTP Interface
Miles connects to Harbor-based agent servers through direct HTTP POST requests. The swe_agent_function.py adaptor constructs requests containing the Miles session URL, model identifier, and sampling parameters, then transmits them to <AGENT_SERVER_URL>/run.
Key implementation details from the Miles source code:
- Request construction: The
runfunction inexamples/swe-agent-harbor-docker/swe_agent_function.pyassembles a dict withbase_url, model name,request_kwargs, and metadata includingmax_seq_lenandsession_server_id - Response parsing: Returns JSON with
reward,exit_status, and optionalagent_metrics - Abort handling: An
aborthook calls the server's/flushendpoint to terminate in-flight trials
import asyncio
from examples.swe-agent-harbor-docker.swe_agent_function import run
metadata = {"max_seq_len": 2048}
sampling_kwargs = {"temperature": 0.7, "top_p": 0.9}
result = asyncio.run(
run(
base_url="http://localhost:12345", # Miles router URL
prompt="Explain the impact of quantum computing on cryptography.",
request_kwargs=sampling_kwargs,
metadata=metadata,
)
)
print(result) # {'reward': …, 'exit_status': …, …}
HUD Integration: OpenAI-Compatible Token ID Contract
HUD provides an OpenAI-compatible chat endpoint returning token IDs. Miles integrates HUD through sglang_compat.py, an async thin client that forwards requests without altering HUD's server code.
The adaptor preserves HUD's token-ID contract by extracting choice.token_ids alongside generated text. It injects HUD task metadata—environment, template ID, and arguments—into sample metadata for downstream reward model consumption.
from examples.experimental.hud.sglang_compat import AsyncOpenAIChatAgent
agent = AsyncOpenAIChatAgent(model="gpt-4")
response = await agent.chat(
messages=[{"role": "user", "content": "Summarize the paper 'Attention Is All You Need'."}]
)
print(response.choices[0].token_ids) # token-ID contract preserved
NeMo Gym Integration: Responses-API Mapping
NeMo Gym integration routes through the mini_swe_agent_2 sandbox agent. The nemogym_agent_function.py adaptor maps Miles sampling arguments onto NeMo Gym's Responses-API parameters, handles timeouts and retries, and embeds the NeMo Gym URL in metadata.
The implementation in examples/experimental/nemo-gym/nemogym_agent_function.py targets the /run endpoint and translates JSON responses into Miles-standard reward and metrics.
import asyncio
from examples.experimental.nemo_gym.nemogym_agent_function import run
result = asyncio.run(
run(
base_url="http://localhost:8000",
prompt="Implement a binary search tree in Python.",
request_kwargs={"temperature": 0.0},
)
)
print(result["reward"])
OpenEnv Integration: Multi-Backend Sandbox Dispatch
OpenEnv supplies sandbox backends through Daytona, E2B, and Modal. Miles implements a two-layer architecture:
- Registry layer:
openenv_sandbox_common.pymaps backend names to provider-specific modules - Dispatch layer:
openenv_agent_function.pyresolvesOPENENV_SANDBOX_BACKENDfrom environment variables and constructs OpenEnv-compatible requests
Backend-specific modules handle authentication and endpoint URLs:
import asyncio
from examples.experimental.openenv.openenv_agent_function import run
result = asyncio.run(
run(
base_url="http://localhost:9000",
prompt="Write a bash script that backs up /var/log.",
request_kwargs={"max_new_tokens": 256},
metadata={"openenv_sandbox_backend": "daytona"},
)
)
print(result)
Common Integration Pattern Across All Four Environments
Every Miles agentic environment adaptor follows five standardized steps as implemented in the source:
- Resolve session URL —
miles/rollout/agentic/session.pygenerates the trainer's base URL for environment callbacks - Build request dict — Encapsulates model ID, sampling parameters, and metadata
- Async HTTP POST —
httpx.AsyncClientwith keep-alive sockets for long-running trials - Parse and normalize — Extract
reward,exit_status,eval_report, andagent_metricsinto MilesSampleschema - Optional abort/flush — Clean up pending trials for environments like Harbor
This uniformity lets researchers swap environments through configuration changes alone.
Source File Reference
| Component | Path | Purpose |
|---|---|---|
| Harbor adaptor | examples/swe-agent-harbor-docker/swe_agent_function.py |
HTTP interface to Harbor agent server with abort/flush |
| HUD adaptor | examples/experimental/hud/sglang_compat.py |
Token-ID-preserving async client |
| NeMo Gym adaptor | examples/experimental/nemo-gym/nemogym_agent_function.py |
Responses-API mapping with retry logic |
| OpenEnv core | examples/experimental/openenv/openenv_agent_function.py |
Backend-agnostic dispatch |
| OpenEnv registry | examples/experimental/openenv/openenv_sandbox_common.py |
Backend name-to-module mapping |
| Daytona backend | examples/experimental/openenv/openenv_daytona_agent_function.py |
Daytona-specific auth and endpoints |
| E2B backend | examples/experimental/openenv/openenv_e2b_agent_function.py |
E2B sandbox integration |
| Modal backend | examples/experimental/openenv/openenv_modal_agent_function.py |
Modal serverless integration |
| Session resolver | miles/rollout/agentic/session.py |
URL resolution for environment callbacks |
Summary
- Harbor: Direct HTTP POST to agent server with abort/flush lifecycle management
- HUD: OpenAI-compatible wrapper preserving token-ID contracts and task metadata
- NeMo Gym: Responses-API adaptor with timeout handling and URL embedding
- OpenEnv: Pluggable backend system supporting Daytona, E2B, and Modal sandboxes
- Unified interface: All four environments implement the same five-step integration pattern, enabling drop-in replacement during GRPO training
Frequently Asked Questions
How does Miles handle authentication for different OpenEnv backends?
Backend-specific modules in examples/experimental/openenv/ encapsulate provider authentication. openenv_daytona_agent_function.py, openenv_e2b_agent_function.py, and openenv_modal_agent_function.py each manage their respective API keys and endpoint configurations, while the generic openenv_agent_function.py dispatches based on the OPENENV_SANDBOX_BACKEND environment variable or metadata override.
Can Miles abort long-running trials in Harbor environments?
Yes. The Harbor adaptor exposes an abort hook that POSTs to the agent server's /flush endpoint. This terminates in-flight trials without waiting for completion, implemented in swe_agent_function.py alongside the main run function.
What metadata does Miles inject for downstream reward computation?
Each adaptor injects environment-specific context: Harbor includes session and model identifiers; HUD adds task row data (environment, template ID, arguments); NeMo Gym embeds the server URL; OpenEnv records the selected backend. This metadata flows through Miles' Sample schema to reward models.
Is the HUD integration compatible with standard OpenAI SDK usage?
The sglang_compat.py adaptor maintains compatibility while extending functionality. It returns token_ids alongside standard text responses, satisfying HUD's contract without requiring modifications to either HUD's server code or typical OpenAI client patterns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →